Merge pull request #2683 from tractorcow/pulls/2682-fix-gridfieldsortableheader

BUG Fixes #2682 - Regression in #2595
This commit is contained in:
Ingo Schommer 2013-11-29 09:17:39 -08:00
commit 73eae2990f
2 changed files with 45 additions and 10 deletions

View File

@ -100,23 +100,27 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
$allowSort = ($title && $list->canSortBy($columnField));
if(strpos($columnField, '.') !== false) {
if(!$allowSort && strpos($columnField, '.') !== false) {
// we have a relation column with dot notation
// @see DataObject::relField for approximation
$parts = explode('.', $columnField);
$tmpItem = singleton($list->dataClass());
for($idx = 0; $idx < sizeof($parts); $idx++) {
$methodName = $parts[$idx];
if($tmpItem instanceof DataObject && $tmpItem->hasField($methodName)) {
// If we've found a field, we can sort on it
$allowSort = true;
} else if ($tmpItem instanceof SS_List) {
if($tmpItem instanceof SS_List) {
// It's impossible to sort on a HasManyList/ManyManyList
throw new Exception(__CLASS__ . ' is unable to sort on has_many/many_many relations,'
. ' please only specify has_one relations');
} else {
// Else, the part is a relation name, so get the object/list from it
break;
} elseif($tmpItem->hasMethod($methodName)) {
// The part is a relation name, so get the object/list from it
$tmpItem = $tmpItem->$methodName();
} elseif($tmpItem instanceof DataObject && $tmpItem->hasField($methodName)) {
// Else, if we've found a field at the end of the chain, we can sort on it.
// If a method is applied further to this field (E.g. 'Cost.Currency') then don't try to sort.
$allowSort = $idx === sizeof($parts) - 1;
break;
} else {
// If neither method nor field, then unable to sort
break;
}
}
}

View File

@ -13,6 +13,31 @@ class GridFieldSortableHeaderTest extends SapphireTest {
'GridFieldSortableHeaderTest_Cheerleader',
'GridFieldSortableHeaderTest_CheerleaderHat'
);
/**
* Tests that the appropriate sortable headers are generated
*/
public function testRenderHeaders() {
// Generate sortable header and extract HTML
$list = new DataList('GridFieldSortableHeaderTest_Team');
$config = new GridFieldConfig_RecordEditor();
$form = new Form(Controller::curr(), 'Form', new FieldList(), new FieldList());
$gridField = new GridField('testfield', 'testfield', $list, $config);
$gridField->setForm($form);
$compontent = $gridField->getConfig()->getComponentByType('GridFieldSortableHeader');
$htmlFragment = $compontent->getHTMLFragments($gridField);
// Check that the output shows name and hat as sortable fields, but not city
$this->assertContains('<span class="non-sortable">City</span>', $htmlFragment['header']);
$this->assertContains('value="Name" class="action ss-gridfield-sort" id="action_SetOrderName"', $htmlFragment['header']);
$this->assertContains('value="Cheerleader Hat" class="action ss-gridfield-sort" id="action_SetOrderCheerleader-Hat-Colour"', $htmlFragment['header']);
// Check inverse of above
$this->assertNotContains('value="City" class="action ss-gridfield-sort" id="action_SetOrderCity"', $htmlFragment['header']);
$this->assertNotContains('<span class="non-sortable">Name</span>', $htmlFragment['header']);
$this->assertNotContains('<span class="non-sortable">Cheerleader Hat</span>', $htmlFragment['header']);
}
public function testGetManipulatedData() {
$list = new DataList('GridFieldSortableHeaderTest_Team');
@ -77,6 +102,12 @@ class GridFieldSortableHeaderTest extends SapphireTest {
}
class GridFieldSortableHeaderTest_Team extends DataObject implements TestOnly {
private static $summary_fields = array(
'Name' => 'Name',
'City.Initial' => 'City',
'Cheerleader.Hat.Colour' => 'Cheerleader Hat'
);
private static $db = array(
'Name' => 'Varchar',