Skip to content

Commit

Permalink
ENHANCEMENT: GridFieldComponents will now use SS_Filterable, SS_Sorta…
Browse files Browse the repository at this point in the history
…ble, and SS_Limitable to determine which features are applicable to the List provided, and either throw an error, or silently disable the feature.

API CHANGE: Added throwExceptionOnBadDataType() to GridFilterFilter, GridFieldPaginator, and GridFieldSortableHeader.
  • Loading branch information
Sam Minnee authored and Stig Lindqvist committed Mar 9, 2012
1 parent e9e7655 commit 426f167
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 11 deletions.
2 changes: 1 addition & 1 deletion forms/gridfield/GridField.php
Expand Up @@ -323,7 +323,7 @@ public function FieldHolder() {
foreach($this->components as $item) {
if($item instanceof GridField_HTMLProvider) {
$fragments = $item->getHTMLFragments($this);
foreach($fragments as $k => $v) {
if($fragments) foreach($fragments as $k => $v) {
$k = strtolower($k);
if(!isset($content[$k])) $content[$k] = "";
$content[$k] .= $v . "\n";
Expand Down
32 changes: 22 additions & 10 deletions forms/gridfield/GridFieldConfig.php
Expand Up @@ -132,10 +132,14 @@ public static function create($itemsPerPage=null){
*/
public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldToolbarHeader());
$this->addComponent(new GridFieldSortableHeader());
$this->addComponent(new GridFieldFilterHeader());
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldPaginator($itemsPerPage));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));

$sort->throwExceptionOnBadDataType(false);
$filter->throwExceptionOnBadDataType(false);
$pagination->throwExceptionOnBadDataType(false);
}
}

Expand All @@ -159,13 +163,17 @@ public static function create($itemsPerPage=null){
*/
public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldToolbarHeader());
$this->addComponent(new GridFieldSortableHeader());
$this->addComponent(new GridFieldFilterHeader());
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction());
$this->addComponent(new GridFieldPaginator($itemsPerPage));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDetailForm());

$sort->throwExceptionOnBadDataType(false);
$filter->throwExceptionOnBadDataType(false);
$pagination->throwExceptionOnBadDataType(false);
}
}

Expand Down Expand Up @@ -202,12 +210,16 @@ public static function create($itemsPerPage=null){
public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldToolbarHeader());
$this->addComponent(new GridFieldAddExistingAutocompleter());
$this->addComponent(new GridFieldSortableHeader());
$this->addComponent(new GridFieldFilterHeader());
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction(true));
$this->addComponent(new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDeleteAction());
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDetailForm());

$sort->throwExceptionOnBadDataType(false);
$filter->throwExceptionOnBadDataType(false);
$pagination->throwExceptionOnBadDataType(false);
}
}
41 changes: 41 additions & 0 deletions forms/gridfield/GridFieldFilterHeader.php
Expand Up @@ -8,17 +8,54 @@
* @subpackage fields-relational
*/
class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {

/**
* See {@link throwExceptionOnBadDataType()}
*/
protected $throwExceptionOnBadDataType = true;

/**
* Determine what happens when this component is used with a list that isn't {@link SS_Filterable}.
*
* - true: An exception is thrown
* - false: This component will be ignored - it won't make any changes to the GridField.
*
* By default, this is set to true so that it's clearer what's happening, but the predefined
* {@link GridFieldConfig} subclasses set this to false for flexibility.
*/
public function throwExceptionOnBadDataType($throwExceptionOnBadDataType) {
$this->throwExceptionOnBadDataType = $throwExceptionOnBadDataType;
}

/**
* Check that this dataList is of the right data type.
* Returns false if it's a bad data type, and if appropriate, throws an exception.
*/
protected function checkDataType($dataList) {
if($dataList instanceof SS_Filterable) {
return true;
} else {
if($this->throwExceptionOnBadDataType) {
throw new LogicException(get_class($this) . " expects an SS_Filterable list to be passed to the GridField.");
}
return false;
}
}

/**
*
* @param GridField $gridField
* @return array
*/
public function getActions($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

return array('filter', 'reset');
}

function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if(!$this->checkDataType($gridField->getList())) return;

$state = $gridField->State->GridFieldFilterHeader;
if($actionName === 'filter') {
if(isset($data['filter'])){
Expand All @@ -39,6 +76,8 @@ function handleAction(GridField $gridField, $actionName, $arguments, $data) {
* @return SS_List
*/
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
if(!$this->checkDataType($dataList)) return $dataList;

$state = $gridField->State->GridFieldFilterHeader;
if(!isset($state->Columns)) {
return $dataList;
Expand All @@ -54,6 +93,8 @@ public function getManipulatedData(GridField $gridField, SS_List $dataList) {
}

public function getHTMLFragments($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList;

Expand Down
41 changes: 41 additions & 0 deletions forms/gridfield/GridFieldPaginator.php
Expand Up @@ -20,20 +20,55 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
*/
protected $itemClass = 'GridFieldPaginator_Row';

/**
* See {@link throwExceptionOnBadDataType()}
*/
protected $throwExceptionOnBadDataType = true;

/**
*
* @param int $itemsPerPage - How many items should be displayed per page
*/
public function __construct($itemsPerPage=null) {
if($itemsPerPage) $this->itemsPerPage = $itemsPerPage;
}

/**
* Determine what happens when this component is used with a list that isn't {@link SS_Filterable}.
*
* - true: An exception is thrown
* - false: This component will be ignored - it won't make any changes to the GridField.
*
* By default, this is set to true so that it's clearer what's happening, but the predefined
* {@link GridFieldConfig} subclasses set this to false for flexibility.
*/
public function throwExceptionOnBadDataType($throwExceptionOnBadDataType) {
$this->throwExceptionOnBadDataType = $throwExceptionOnBadDataType;
}

/**
* Check that this dataList is of the right data type.
* Returns false if it's a bad data type, and if appropriate, throws an exception.
*/
protected function checkDataType($dataList) {
if($dataList instanceof SS_Limitable) {
return true;
} else {
if($this->throwExceptionOnBadDataType) {
throw new LogicException(get_class($this) . " expects an SS_Limitable list to be passed to the GridField.");
}
return false;
}
}

/**
*
* @param GridField $gridField
* @return array
*/
public function getActions($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

return array('paginate');
}

Expand All @@ -46,6 +81,8 @@ public function getActions($gridField) {
* @return void
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if(!$this->checkDataType($gridField->getList())) return;

if($actionName !== 'paginate') {
return;
}
Expand All @@ -60,6 +97,8 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
* @return SS_List
*/
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
if(!$this->checkDataType($dataList)) return $dataList;

$state = $gridField->State->GridFieldPaginator;
if(!is_int($state->currentPage))
$state->currentPage = 1;
Expand All @@ -80,6 +119,8 @@ public function getManipulatedData(GridField $gridField, SS_List $dataList) {
* @return array
*/
public function getHTMLFragments($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

$state = $gridField->State->GridFieldPaginator;
if(!is_int($state->currentPage))
$state->currentPage = 1;
Expand Down
41 changes: 41 additions & 0 deletions forms/gridfield/GridFieldSortableHeader.php
Expand Up @@ -8,11 +8,46 @@
* @subpackage fields-relational
*/
class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {

/**
* See {@link throwExceptionOnBadDataType()}
*/
protected $throwExceptionOnBadDataType = true;

/**
* Determine what happens when this component is used with a list that isn't {@link SS_Filterable}.
*
* - true: An exception is thrown
* - false: This component will be ignored - it won't make any changes to the GridField.
*
* By default, this is set to true so that it's clearer what's happening, but the predefined
* {@link GridFieldConfig} subclasses set this to false for flexibility.
*/
public function throwExceptionOnBadDataType($throwExceptionOnBadDataType) {
$this->throwExceptionOnBadDataType = $throwExceptionOnBadDataType;
}

/**
* Check that this dataList is of the right data type.
* Returns false if it's a bad data type, and if appropriate, throws an exception.
*/
protected function checkDataType($dataList) {
if($dataList instanceof SS_Sortable) {
return true;
} else {
if($this->throwExceptionOnBadDataType) {
throw new LogicException(get_class($this) . " expects an SS_Sortable list to be passed to the GridField.");
}
return false;
}
}

/**
* Returns the header row providing titles with sort buttons
*/
public function getHTMLFragments($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList;

Expand Down Expand Up @@ -58,10 +93,14 @@ public function getHTMLFragments($gridField) {
* @return array
*/
public function getActions($gridField) {
if(!$this->checkDataType($gridField->getList())) return;

return array('sortasc', 'sortdesc');
}

function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if(!$this->checkDataType($gridField->getList())) return;

$state = $gridField->State->GridFieldSortableHeader;
switch($actionName) {
case 'sortasc':
Expand All @@ -77,6 +116,8 @@ function handleAction(GridField $gridField, $actionName, $arguments, $data) {
}

public function getManipulatedData(GridField $gridField, SS_List $dataList) {
if(!$this->checkDataType($dataList)) return $dataList;

$state = $gridField->State->GridFieldSortableHeader;
if ($state->SortColumn == "") {
return $dataList;
Expand Down

0 comments on commit 426f167

Please sign in to comment.