/**
  * 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));
 }
 /**
  * @skipUpgrade
  * @covers SilverStripe\Forms\GridField\GridField::getColumns
  */
 public function testGetColumns()
 {
     $obj = new GridField('testfield', 'testfield', Member::get());
     $expected = array(0 => 'FirstName', 1 => 'Surname', 2 => 'Email');
     $this->assertEquals($expected, $obj->getColumns());
 }