FIX include related fields on canFilter() check

closes #5576
This commit is contained in:
Jonathon Menz 2016-08-11 10:19:32 -07:00
parent f0b32f1483
commit d4114b3dce
2 changed files with 46 additions and 2 deletions

View File

@ -233,12 +233,24 @@ class DataList extends ViewableData implements SS_List, SS_Filterable, SS_Sortab
}
/**
* Returns true if this DataList can be filtered by the given field.
*
* @param string $fieldName
* @param string $fieldName (May be a related field in dot notation like Member.FirstName)
* @return boolean
*/
public function canFilterBy($fieldName) {
if($t = singleton($this->dataClass)->hasDatabaseField($fieldName)){
$model = singleton($this->dataClass);
$relations = explode(".", $fieldName);
// First validate the relationships
$fieldName = array_pop($relations);
foreach ($relations as $r) {
$relationClass = $model->getRelationClass($r);
if (!$relationClass) return false;
$model = singleton($relationClass);
if (!$model) return false;
}
// Then check field
if ($model->hasDatabaseField($fieldName)){
return true;
}
return false;

View File

@ -533,6 +533,38 @@ class DataListTest extends SapphireTest {
$this->assertEquals('Phil', $list->last()->Name, 'Last comment should be from Phil');
}
/**
* Test DataList->canFilterBy()
*/
public function testCanFilterBy() {
// Basic check
$team = DataObjectTest_Team::get();
$this->assertTrue($team->canFilterBy("Title"));
$this->assertFalse($team->canFilterBy("SomethingElse"));
// Has one
$this->assertTrue($team->canFilterBy("CaptainID"));
$this->assertTrue($team->canFilterBy("Captain.ShirtNumber"));
$this->assertFalse($team->canFilterBy("SomethingElse.ShirtNumber"));
$this->assertFalse($team->canFilterBy("Captain.SomethingElse"));
$this->assertTrue($team->canFilterBy("Captain.FavouriteTeam.Captain.ShirtNumber"));
// Has many
$this->assertTrue($team->canFilterBy("Fans.Name"));
$this->assertFalse($team->canFilterBy("SomethingElse.Name"));
$this->assertFalse($team->canFilterBy("Fans.SomethingElse"));
// Many many
$this->assertTrue($team->canFilterBy("Players.FirstName"));
$this->assertFalse($team->canFilterBy("SomethingElse.FirstName"));
$this->assertFalse($team->canFilterBy("Players.SomethingElse"));
// Subclasses
$subteam = DataObjectTest_SubTeam::get();
$this->assertTrue($subteam->canFilterBy("Title"));
$this->assertTrue($subteam->canFilterBy("SubclassDatabaseField"));
}
/**
* $list->filter('Name', 'bob'); // only bob in the list
*/