From 01808a8316b182a438dfc5365cec8fffdb096c8e Mon Sep 17 00:00:00 2001 From: Guy Sartorelli Date: Mon, 8 May 2023 12:55:17 +1200 Subject: [PATCH] FIX Don't assume searchableFields() exists in gridfield filter --- src/Forms/GridField/GridFieldFilterHeader.php | 41 +++++++++++++------ .../GridField/GridFieldFilterHeaderTest.php | 34 ++++++++++++++- .../NonDataObject.php | 14 +++++++ 3 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 tests/php/Forms/GridField/GridFieldFilterHeaderTest/NonDataObject.php diff --git a/src/Forms/GridField/GridFieldFilterHeader.php b/src/Forms/GridField/GridFieldFilterHeader.php index 6292985be..a0fff8038 100755 --- a/src/Forms/GridField/GridFieldFilterHeader.php +++ b/src/Forms/GridField/GridFieldFilterHeader.php @@ -6,6 +6,7 @@ use LogicException; use SilverStripe\Admin\LeftAndMain; use SilverStripe\Control\Controller; use SilverStripe\Control\HTTPResponse; +use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Convert; use SilverStripe\Dev\Deprecation; @@ -258,20 +259,36 @@ class GridFieldFilterHeader extends AbstractGridFieldComponent implements GridFi return false; } $modelClass = $gridField->getModelClass(); - // note: searchableFields() will return summary_fields if there are no searchable_fields on the model - $searchableFields = array_keys($modelClass::singleton()->searchableFields()); - $summaryFields = array_keys($modelClass::singleton()->summaryFields()); - sort($searchableFields); - sort($summaryFields); - // searchable_fields has been explictily defined i.e. searchableFields() is not falling back to summary_fields - if ($searchableFields !== $summaryFields) { - return true; - } - // we have fallen back to summary_fields, check they are filterable - foreach ($searchableFields as $searchableField) { - if ($list->canFilterBy($searchableField)) { + $singleton = singleton($modelClass); + if (ClassInfo::hasMethod($singleton, 'summaryFields') + && ClassInfo::hasMethod($singleton, 'searchableFields') + ) { + // note: searchableFields() will return summary_fields if there are no searchable_fields on the model + $searchableFields = array_keys($singleton->searchableFields()); + $summaryFields = array_keys($singleton->summaryFields()); + sort($searchableFields); + sort($summaryFields); + // searchable_fields has been explictily defined i.e. searchableFields() is not falling back to summary_fields + if ($searchableFields !== $summaryFields) { return true; } + // we have fallen back to summary_fields, check they are filterable + foreach ($searchableFields as $searchableField) { + if ($list->canFilterBy($searchableField)) { + return true; + } + } + } else { + // Allows non-DataObject classes to be used with this component + $columns = $gridField->getColumns(); + foreach ($columns as $columnField) { + $metadata = $gridField->getColumnMetadata($columnField); + $title = $metadata['title']; + + if ($title && $list->canFilterBy($columnField)) { + return true; + } + } } return false; } diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php index bf6c95b8c..28b964acb 100644 --- a/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest.php @@ -8,13 +8,16 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; use SilverStripe\Forms\GridField\GridField; +use SilverStripe\Forms\GridField\GridFieldConfig; use SilverStripe\Forms\GridField\GridFieldConfig_RecordEditor; use SilverStripe\Forms\GridField\GridFieldFilterHeader; use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Cheerleader; use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\CheerleaderHat; use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Mom; +use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\NonDataObject; use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\Team; use SilverStripe\Forms\Tests\GridField\GridFieldFilterHeaderTest\TeamGroup; +use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; @@ -187,7 +190,7 @@ class GridFieldFilterHeaderTest extends SapphireTest { $gridField = $this->gridField; $filterHeader = $gridField->getConfig()->getComponentByType(GridFieldFilterHeader::class); - + // test that you can filter by something if searchable_fields is not defined // silverstripe will scaffold db columns that are in the gridfield to be // searchable by default @@ -208,4 +211,33 @@ class GridFieldFilterHeaderTest extends SapphireTest Config::modify()->set(Team::class, 'summary_fields', ['MySummaryField']); $this->assertFalse($filterHeader->canFilterAnyColumns($gridField)); } + + public function testCanFilterAnyColumnsNonDataObject() + { + $list = new ArrayList([ + new NonDataObject([]), + ]); + $config = GridFieldConfig::create()->addComponent(new GridFieldFilterHeader()); + $gridField = new GridField('testfield', 'testfield', $list, $config); + $form = new Form(null, 'Form', new FieldList([$gridField]), new FieldList()); + /** @var GridFieldFilterHeader $component */ + $component = $gridField->getConfig()->getComponentByType(GridFieldFilterHeader::class); + + $this->assertFalse($component->canFilterAnyColumns($gridField)); + } + + public function testRenderHeadersNonDataObject() + { + $list = new ArrayList([ + new NonDataObject([]), + ]); + $config = GridFieldConfig::create()->addComponent(new GridFieldFilterHeader()); + $gridField = new GridField('testfield', 'testfield', $list, $config); + $form = new Form(null, 'Form', new FieldList([$gridField]), new FieldList()); + /** @var GridFieldFilterHeader $component */ + $component = $gridField->getConfig()->getComponentByType(GridFieldFilterHeader::class); + $htmlFragment = $component->getHTMLFragments($gridField); + + $this->assertNull($htmlFragment); + } } diff --git a/tests/php/Forms/GridField/GridFieldFilterHeaderTest/NonDataObject.php b/tests/php/Forms/GridField/GridFieldFilterHeaderTest/NonDataObject.php new file mode 100644 index 000000000..c446dddfc --- /dev/null +++ b/tests/php/Forms/GridField/GridFieldFilterHeaderTest/NonDataObject.php @@ -0,0 +1,14 @@ + 'Title']; + } +}