2011-12-06 01:56:24 +01:00
< ? php
2016-06-15 06:03:16 +02:00
2016-08-19 00:51:35 +02:00
namespace SilverStripe\Forms\GridField ;
use SilverStripe\Forms\FieldGroup ;
use SilverStripe\Forms\TextField ;
2016-09-09 08:43:05 +02:00
use SilverStripe\ORM\Filterable ;
2016-06-15 06:03:16 +02:00
use SilverStripe\ORM\SS_List ;
use SilverStripe\ORM\ArrayList ;
2016-08-19 00:51:35 +02:00
use SilverStripe\View\ArrayData ;
use SilverStripe\View\SSViewer ;
use LogicException ;
2011-12-06 01:56:24 +01:00
/**
2014-08-15 08:53:05 +02:00
* GridFieldFilterHeader alters the { @ link GridField } with some filtering
2013-05-20 12:18:07 +02:00
* fields in the header of each column .
2014-08-15 08:53:05 +02:00
*
2011-12-06 01:56:24 +01:00
* @ see GridField
*/
2016-11-29 00:31:16 +01:00
class GridFieldFilterHeader implements GridField_HTMLProvider , GridField_DataManipulator , GridField_ActionProvider
{
/**
* See { @ link setThrowExceptionOnBadDataType ()}
*
* @ var bool
*/
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 .
*
* @ param bool $throwExceptionOnBadDataType
*/
public function setThrowExceptionOnBadDataType ( $throwExceptionOnBadDataType )
{
$this -> throwExceptionOnBadDataType = $throwExceptionOnBadDataType ;
}
/**
* See { @ link setThrowExceptionOnBadDataType ()}
*/
public function getThrowExceptionOnBadDataType ()
{
return $this -> 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 .
*
* @ param SS_List $dataList
* @ return bool
*/
protected function checkDataType ( $dataList )
{
if ( $dataList instanceof Filterable ) {
return true ;
} else {
if ( $this -> throwExceptionOnBadDataType ) {
throw new LogicException (
2017-05-17 07:40:13 +02:00
static :: class . " expects an SS_Filterable list to be passed to the GridField. "
2016-11-29 00:31:16 +01:00
);
}
return false ;
}
}
/**
*
* @ param GridField $gridField
* @ return array
*/
public function getActions ( $gridField )
{
if ( ! $this -> checkDataType ( $gridField -> getList ())) {
return [];
}
return array ( 'filter' , 'reset' );
}
public function handleAction ( GridField $gridField , $actionName , $arguments , $data )
{
if ( ! $this -> checkDataType ( $gridField -> getList ())) {
return ;
}
$state = $gridField -> State -> GridFieldFilterHeader ;
if ( $actionName === 'filter' ) {
if ( isset ( $data [ 'filter' ][ $gridField -> getName ()])) {
foreach ( $data [ 'filter' ][ $gridField -> getName ()] as $key => $filter ) {
$state -> Columns -> $key = $filter ;
}
}
} elseif ( $actionName === 'reset' ) {
$state -> Columns = null ;
}
}
/**
*
* @ param GridField $gridField
* @ param SS_List $dataList
* @ return SS_List
*/
public function getManipulatedData ( GridField $gridField , SS_List $dataList )
{
if ( ! $this -> checkDataType ( $dataList )) {
return $dataList ;
}
/** @var Filterable $dataList */
/** @var GridState_Data $columns */
$columns = $gridField -> State -> GridFieldFilterHeader -> Columns ( null );
if ( empty ( $columns )) {
return $dataList ;
}
$filterArguments = $columns -> toArray ();
$dataListClone = clone ( $dataList );
foreach ( $filterArguments as $columnName => $value ) {
if ( $dataList -> canFilterBy ( $columnName ) && $value ) {
2018-01-16 19:39:30 +01:00
$dataListClone = $dataListClone -> filter ( $columnName . ':PartialMatch' , $value );
2016-11-29 00:31:16 +01:00
}
}
return $dataListClone ;
}
2016-12-13 02:18:10 +01:00
/**
* Returns whether this { @ link GridField } has any columns to sort on at all .
*
2017-01-11 00:00:01 +01:00
* @ param GridField $gridField
2016-12-13 02:18:10 +01:00
* @ return boolean
*/
public function canFilterAnyColumns ( $gridField )
{
$list = $gridField -> getList ();
if ( ! $this -> checkDataType ( $list )) {
return false ;
}
$columns = $gridField -> getColumns ();
foreach ( $columns as $columnField ) {
$metadata = $gridField -> getColumnMetadata ( $columnField );
$title = $metadata [ 'title' ];
if ( $title && $list -> canFilterBy ( $columnField )) {
return true ;
}
}
return false ;
}
2016-11-29 00:31:16 +01:00
public function getHTMLFragments ( $gridField )
{
$list = $gridField -> getList ();
if ( ! $this -> checkDataType ( $list )) {
return null ;
}
/** @var Filterable $list */
$forTemplate = new ArrayData ( array ());
2016-12-13 02:18:10 +01:00
$forTemplate -> Fields = new ArrayList ();
2016-11-29 00:31:16 +01:00
$columns = $gridField -> getColumns ();
$filterArguments = $gridField -> State -> GridFieldFilterHeader -> Columns -> toArray ();
$currentColumn = 0 ;
2016-12-13 02:18:10 +01:00
$canFilter = false ;
2016-11-29 00:31:16 +01:00
foreach ( $columns as $columnField ) {
$currentColumn ++ ;
$metadata = $gridField -> getColumnMetadata ( $columnField );
$title = $metadata [ 'title' ];
$fields = new FieldGroup ();
if ( $title && $list -> canFilterBy ( $columnField )) {
2016-12-13 02:18:10 +01:00
$canFilter = true ;
2016-11-29 00:31:16 +01:00
$value = '' ;
if ( isset ( $filterArguments [ $columnField ])) {
$value = $filterArguments [ $columnField ];
}
$field = new TextField ( 'filter[' . $gridField -> getName () . '][' . $columnField . ']' , '' , $value );
$field -> addExtraClass ( 'grid-field__sort-field' );
$field -> addExtraClass ( 'no-change-track' );
$field -> setAttribute (
'placeholder' ,
2018-01-16 19:39:30 +01:00
_t ( 'SilverStripe\\Forms\\GridField\\GridField.FilterBy' , " Filter by " ) . _t ( 'SilverStripe\\Forms\\GridField\\GridField.' . $metadata [ 'title' ], $metadata [ 'title' ])
2016-11-29 00:31:16 +01:00
);
$fields -> push ( $field );
$fields -> push (
GridField_FormAction :: create ( $gridField , 'reset' , false , 'reset' , null )
2016-12-13 02:18:10 +01:00
-> addExtraClass ( 'btn font-icon-cancel btn-secondary btn--no-text ss-gridfield-button-reset' )
2017-04-20 03:15:24 +02:00
-> setAttribute ( 'title' , _t ( 'SilverStripe\\Forms\\GridField\\GridField.ResetFilter' , " Reset " ))
2016-11-29 00:31:16 +01:00
-> setAttribute ( 'id' , 'action_reset_' . $gridField -> getModelClass () . '_' . $columnField )
);
}
if ( $currentColumn == count ( $columns )) {
$fields -> push (
GridField_FormAction :: create ( $gridField , 'filter' , false , 'filter' , null )
-> addExtraClass ( 'btn font-icon-search btn--no-text btn--icon-large grid-field__filter-submit ss-gridfield-button-filter' )
2017-04-20 03:15:24 +02:00
-> setAttribute ( 'title' , _t ( 'SilverStripe\\Forms\\GridField\\GridField.Filter' , 'Filter' ))
2016-11-29 00:31:16 +01:00
-> setAttribute ( 'id' , 'action_filter_' . $gridField -> getModelClass () . '_' . $columnField )
);
$fields -> push (
GridField_FormAction :: create ( $gridField , 'reset' , false , 'reset' , null )
2016-12-20 22:43:33 +01:00
-> addExtraClass ( 'btn font-icon-cancel btn--no-text grid-field__filter-clear btn--icon-md ss-gridfield-button-close' )
2017-04-20 03:15:24 +02:00
-> setAttribute ( 'title' , _t ( 'SilverStripe\\Forms\\GridField\\GridField.ResetFilter' , " Reset " ))
2016-11-29 00:31:16 +01:00
-> setAttribute ( 'id' , 'action_reset_' . $gridField -> getModelClass () . '_' . $columnField )
);
2017-04-21 05:30:09 +02:00
$fields -> addExtraClass ( 'grid-field__filter-buttons' );
2016-11-29 00:31:16 +01:00
$fields -> addExtraClass ( 'no-change-track' );
}
$forTemplate -> Fields -> push ( $fields );
}
2016-12-23 02:09:00 +01:00
if ( ! $canFilter ) {
2016-12-13 02:18:10 +01:00
return null ;
}
2016-11-29 00:31:16 +01:00
$templates = SSViewer :: get_templates_by_class ( $this , '_Row' , __CLASS__ );
return array (
'header' => $forTemplate -> renderWith ( $templates ),
);
}
2012-02-11 03:26:26 +01:00
}