From a91a4bbdc245bdf4435a56b62ac83d45a4799fd4 Mon Sep 17 00:00:00 2001 From: Loz Calver Date: Wed, 12 Feb 2014 15:37:59 +0000 Subject: [PATCH] FIX: Searchable fields with dot notation can be inherited from summary_fields (fixes #1429) --- model/DataObject.php | 17 ++++++++--- tests/model/DataObjectTest.php | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/model/DataObject.php b/model/DataObject.php index 9cbabbf02..0fd1281c0 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -3179,16 +3179,25 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $fields = $this->stat('searchable_fields'); $labels = $this->fieldLabels(); - // fallback to summary fields - if(!$fields) { + // fallback to summary fields (unless empty array is explicitly specified) + if( ! $fields && ! is_array($fields)) { $summaryFields = array_keys($this->summaryFields()); $fields = array(); - // remove the custom getters as the search should not include. + // remove the custom getters as the search should not include them if($summaryFields) { foreach($summaryFields as $key => $name) { - if($this->hasDatabaseField($name) || $this->relObject($name)) { + $spec = $name; + + // Extract field name in case this is a method called on a field (e.g. "Date.Nice") + if(($fieldPos = strpos($name, '.')) !== false) { + $name = substr($name, 0, $fieldPos); + } + + if($this->hasDatabaseField($name)) { $fields[] = $name; + } elseif($this->relObject($spec)) { + $fields[] = $spec; } } } diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index 7f5688a40..bbd76436b 100644 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -645,6 +645,43 @@ class DataObjectTest extends SapphireTest { 'databaseFields() on subclass contains only fields defined on instance' ); } + + public function testSearchableFields() { + $player = $this->objFromFixture('DataObjectTest_Player', 'captain1'); + $fields = $player->searchableFields(); + $this->assertArrayHasKey( + 'IsRetired', + $fields, + 'Fields defined by $searchable_fields static are correctly detected' + ); + $this->assertArrayHasKey( + 'ShirtNumber', + $fields, + 'Fields defined by $searchable_fields static are correctly detected' + ); + + $team = $this->objFromFixture('DataObjectTest_Team', 'team1'); + $fields = $team->searchableFields(); + $this->assertArrayHasKey( + 'Title', + $fields, + 'Fields can be inherited from the $summary_fields static, including methods called on fields' + ); + $this->assertArrayHasKey( + 'Captain.ShirtNumber', + $fields, + 'Fields on related objects can be inherited from the $summary_fields static' + ); + $this->assertArrayHasKey( + 'Captain.FavouriteTeam.Title', + $fields, + 'Fields on related objects can be inherited from the $summary_fields static' + ); + + $testObj = new DataObjectTest_Fixture(); + $fields = $testObj->searchableFields(); + $this->assertEmpty($fields); + } public function testDataObjectUpdate() { /* update() calls can use the dot syntax to reference has_one relations and other methods that return @@ -1191,6 +1228,11 @@ class DataObjectTest_Player extends Member implements TestOnly { private static $belongs_many_many = array( 'Teams' => 'DataObjectTest_Team' ); + + private static $searchable_fields = array( + 'IsRetired', + 'ShirtNumber' + ); } class DataObjectTest_Team extends DataObject implements TestOnly { @@ -1220,6 +1262,12 @@ class DataObjectTest_Team extends DataObject implements TestOnly { ) ); + private static $summary_fields = array( + 'Title.UpperCase' => 'Title', + 'Captain.ShirtNumber' => 'Captain\'s shirt number', + 'Captain.FavouriteTeam.Title' => 'Captain\'s favourite team' + ); + private static $default_sort = '"Title"'; public function MyTitle() { @@ -1251,6 +1299,13 @@ class DataObjectTest_Fixture extends DataObject implements TestOnly { 'MyFieldWithDefault' => 'Default Value', ); + private static $summary_fields = array( + 'Data' => 'Data', + 'DateField.Nice' => 'Date' + ); + + private static $searchable_fields = array(); + public function populateDefaults() { parent::populateDefaults();