ENHANCEMENT: GridFieldComponents will now use SS_Filterable, SS_Sortable, 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.
This commit is contained in:
Sam Minnee 2012-03-09 14:32:16 +13:00 committed by Stig Lindqvist
parent e9e7655867
commit 426f16764c
5 changed files with 146 additions and 11 deletions

View File

@ -323,7 +323,7 @@ class GridField extends FormField {
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";

View File

@ -132,10 +132,14 @@ class GridFieldConfig_Base extends GridFieldConfig {
*/
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);
}
}
@ -159,13 +163,17 @@ class GridFieldConfig_RecordEditor extends GridFieldConfig {
*/
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);
}
}
@ -202,12 +210,16 @@ class GridFieldConfig_RelationEditor extends GridFieldConfig {
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);
}
}

View File

@ -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'])){
@ -39,6 +76,8 @@ class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataMan
* @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;
@ -54,6 +93,8 @@ class GridFieldFilterHeader implements GridField_HTMLProvider, GridField_DataMan
}
public function getHTMLFragments($gridField) {
if(!$this->checkDataType($gridField->getList())) return;
$forTemplate = new ArrayData(array());
$forTemplate->Fields = new ArrayList;

View File

@ -20,6 +20,11 @@ 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
@ -27,6 +32,34 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
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;
}
}
/**
*
@ -34,6 +67,8 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
* @return array
*/
public function getActions($gridField) {
if(!$this->checkDataType($gridField->getList())) return;
return array('paginate');
}
@ -46,6 +81,8 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
* @return void
*/
public function handleAction(GridField $gridField, $actionName, $arguments, $data) {
if(!$this->checkDataType($gridField->getList())) return;
if($actionName !== 'paginate') {
return;
}
@ -60,6 +97,8 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
* @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;
@ -80,6 +119,8 @@ class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipu
* @return array
*/
public function getHTMLFragments($gridField) {
if(!$this->checkDataType($gridField->getList())) return;
$state = $gridField->State->GridFieldPaginator;
if(!is_int($state->currentPage))
$state->currentPage = 1;

View File

@ -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;
@ -58,10 +93,14 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
* @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':
@ -77,6 +116,8 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
}
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
if(!$this->checkDataType($dataList)) return $dataList;
$state = $gridField->State->GridFieldSortableHeader;
if ($state->SortColumn == "") {
return $dataList;