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)); $allowSort = ($title && $list->canSortBy($columnField));
if(strpos($columnField, '.') !== false) { if(!$allowSort && strpos($columnField, '.') !== false) {
// we have a relation column with dot notation // we have a relation column with dot notation
// @see DataObject::relField for approximation
$parts = explode('.', $columnField); $parts = explode('.', $columnField);
$tmpItem = singleton($list->dataClass()); $tmpItem = singleton($list->dataClass());
for($idx = 0; $idx < sizeof($parts); $idx++) { for($idx = 0; $idx < sizeof($parts); $idx++) {
$methodName = $parts[$idx]; $methodName = $parts[$idx];
if($tmpItem instanceof DataObject && $tmpItem->hasField($methodName)) { if($tmpItem instanceof SS_List) {
// If we've found a field, we can sort on it
$allowSort = true;
} else if ($tmpItem instanceof SS_List) {
// It's impossible to sort on a HasManyList/ManyManyList // It's impossible to sort on a HasManyList/ManyManyList
throw new Exception(__CLASS__ . ' is unable to sort on has_many/many_many relations,' break;
. ' please only specify has_one relations'); } elseif($tmpItem->hasMethod($methodName)) {
} else { // The part is a relation name, so get the object/list from it
// Else, the part is a relation name, so get the object/list from it
$tmpItem = $tmpItem->$methodName(); $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_Cheerleader',
'GridFieldSortableHeaderTest_CheerleaderHat' '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() { public function testGetManipulatedData() {
$list = new DataList('GridFieldSortableHeaderTest_Team'); $list = new DataList('GridFieldSortableHeaderTest_Team');
@ -77,6 +102,12 @@ class GridFieldSortableHeaderTest extends SapphireTest {
} }
class GridFieldSortableHeaderTest_Team extends DataObject implements TestOnly { 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( private static $db = array(
'Name' => 'Varchar', 'Name' => 'Varchar',