/** * Returns the header row providing titles with sort buttons * * @param GridField $gridField * @return array */ public function getHTMLFragments($gridField) { $list = $gridField->getList(); if (!$this->checkDataType($list)) { return null; } /** @var Sortable $list */ $forTemplate = new ArrayData(array()); $forTemplate->Fields = new ArrayList(); $state = $gridField->State->GridFieldSortableHeader; $columns = $gridField->getColumns(); $currentColumn = 0; $schema = DataObject::getSchema(); foreach ($columns as $columnField) { $currentColumn++; $metadata = $gridField->getColumnMetadata($columnField); $fieldName = str_replace('.', '-', $columnField); $title = $metadata['title']; if (isset($this->fieldSorting[$columnField]) && $this->fieldSorting[$columnField]) { $columnField = $this->fieldSorting[$columnField]; } $allowSort = $title && $list->canSortBy($columnField); 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 SS_List) { // It's impossible to sort on a HasManyList/ManyManyList break; } elseif (method_exists($tmpItem, 'hasMethod') && $tmpItem->hasMethod($methodName)) { // The part is a relation name, so get the object/list from it $tmpItem = $tmpItem->{$methodName}(); } elseif ($tmpItem instanceof DataObject && $schema->fieldSpec($tmpItem, $methodName, DataObjectSchema::DB_ONLY)) { // Else, if we've found a database 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; } } } if ($allowSort) { $dir = 'asc'; if ($state->SortColumn(null) == $columnField && $state->SortDirection('asc') == 'asc') { $dir = 'desc'; } $field = GridField_FormAction::create($gridField, 'SetOrder' . $fieldName, $title, "sort{$dir}", array('SortColumn' => $columnField))->addExtraClass('grid-field__sort'); if ($state->SortColumn(null) == $columnField) { $field->addExtraClass('ss-gridfield-sorted'); if ($state->SortDirection('asc') == 'asc') { $field->addExtraClass('ss-gridfield-sorted-asc'); } else { $field->addExtraClass('ss-gridfield-sorted-desc'); } } } else { if ($currentColumn == count($columns) && $gridField->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldFilterHeader')) { $field = new LiteralField($fieldName, '<button type="button" name="showFilter" class="btn font-icon-search btn--no-text btn--icon-large grid-field__filter-open"></button>'); } else { $field = new LiteralField($fieldName, '<span class="non-sortable">' . $title . '</span>'); } } $forTemplate->Fields->push($field); } $template = SSViewer::get_templates_by_class($this, '_Row', __CLASS__); return array('header' => $forTemplate->renderWith($template)); }
/** * @covers SilverStripe\Forms\GridField\GridField::getColumnMetadata */ public function testGetColumnMetadataBadArguments() { $this->setExpectedException('InvalidArgumentException'); $list = ArrayList::create(); $config = GridFieldConfig::create()->addComponent(new GridFieldTest_Component()); $obj = new GridField('testfield', 'testfield', $list, $config); $obj->getColumnMetadata('non-exist-qweqweqwe'); }