Skip to content

Commit

Permalink
FIX Orderable rows now respects actual MMTL sort orders instead of in…
Browse files Browse the repository at this point in the history
…crementing from SiteTree
  • Loading branch information
robbieaverill committed Sep 28, 2018
1 parent a034bd5 commit b221134
Showing 1 changed file with 51 additions and 16 deletions.
67 changes: 51 additions & 16 deletions src/GridFieldOrderableRows.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

use Exception;
use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Control\RequestHandler;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Forms\GridField\GridField;
Expand All @@ -20,11 +22,11 @@
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\DataObjectSchema;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\ORM\ManyManyList;
use SilverStripe\ORM\ManyManyThroughList;
use SilverStripe\ORM\ManyManyThroughQueryManipulator;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\FieldType\DBDatetime;
use SilverStripe\Versioned\Versioned;
use SilverStripe\View\ViewableData;

Expand Down Expand Up @@ -295,7 +297,22 @@ public function getColumnContent($grid, $record, $col)
$record->ID,
$this->getSortField()
);
$sortField = new HiddenField($sortFieldName, false, $record->getField($this->getSortField()));

// Default: Get the sort field directly from the current record
$currentSortValue = $record->getField($this->getSortField());

$list = $grid->getList();
if ($list instanceof ManyManyThroughList) {
// In a many many through list we should get the current sort order from the relationship
// if it exists, not directly from the record
$throughListSorts = $this->getSortValuesFromManyManyThroughList($list, $this->getSortField());

if (array_key_exists($record->ID, $throughListSorts)) {
$currentSortValue = $throughListSorts[$record->ID];
}
}

$sortField = HiddenField::create($sortFieldName, false, $currentSortValue);
$sortField->addExtraClass('ss-orderable-hidden-sort');
$sortField->setForm($grid->getForm());

Expand Down Expand Up @@ -345,17 +362,18 @@ public function getManipulatedData(GridField $grid, SS_List $list)
$sortterm .= '"'.$this->getSortTable($list).'"."'.$this->getSortField().'"';
}
return $list->sort($sortterm);
} else {
return $list;
}

return $list;
}

/**
* Handles requests to reorder a set of IDs in a specific order.
*
* @param GridField $grid
* @param SS_HTTPRequest $request
* @return SS_HTTPResponse
* @param HTTPRequest $request
* @return string
* @throws HTTPResponse_Exception
*/
public function handleReorder($grid, $request)
{
Expand Down Expand Up @@ -536,16 +554,7 @@ protected function executeReorder(GridField $grid, $sortedIDs)
}
}
} elseif ($items instanceof ManyManyThroughList) {
$manipulator = $this->getManyManyInspector($list);
$joinClass = $manipulator->getJoinClass();
$fromRelationName = $manipulator->getForeignKey();
$toRelationName = $manipulator->getLocalKey();
$sortlist = DataList::create($joinClass)->filter([
$toRelationName => $items->column('ID'),
// first() is safe as there are earlier checks to ensure our list to sort is valid
$fromRelationName => $items->first()->getJoin()->$fromRelationName,
]);
$current = $sortlist->map($toRelationName, $sortField)->toArray();
$current = $this->getSortValuesFromManyManyThroughList($list, $sortField);
} else {
$current = $items->map('ID', $sortField)->toArray();
}
Expand Down Expand Up @@ -759,4 +768,30 @@ protected function getManyManyInspector($list)
}
return $inspector;
}

/**
* Used to get sort orders from a many many through list relationship record, rather than the current
* record itself.
*
* @param ManyManyList|ManyManyThroughList $list
* @return int[] Sort orders for the
*/
protected function getSortValuesFromManyManyThroughList($list, $sortField)
{
$manipulator = $this->getManyManyInspector($list);

// Find the foreign key name, ID and class to look up
$joinClass = $manipulator->getJoinClass();
$fromRelationName = $manipulator->getForeignKey();
$toRelationName = $manipulator->getLocalKey();

// Create a list of the MMTL relations
$sortlist = DataList::create($joinClass)->filter([
$toRelationName => $list->column('ID'),
// first() is safe as there are earlier checks to ensure our list to sort is valid
$fromRelationName => $list->first()->getJoin()->$fromRelationName,
]);

return $sortlist->map($toRelationName, $sortField)->toArray();
}
}

0 comments on commit b221134

Please sign in to comment.