Skip to content

Commit

Permalink
FEATURE folders always go first when ordering (revert to the original…
Browse files Browse the repository at this point in the history
… 4.0 behaviour)

See silverstripe#893
  • Loading branch information
dnsl48 committed Apr 17, 2019
1 parent 9f07249 commit 4971b81
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
49 changes: 47 additions & 2 deletions code/GraphQL/FolderTypeCreator.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,58 @@ public function resolveChildrenConnection(
$result = $childrenConnection->resolveList($list, $args);
$list = $result['edges'];

// Filter by permission
$ids = $list->column('ID');
if (!isset($args['sortBy'])) {
// only show folders first if no manual ordering is set

$list = $list->alterDataQuery(static function (DataQuery $dataQuery) {
$query = $dataQuery->query();
$existingOrderBys = [];
foreach ($query->getOrderBy() as $field => $direction) {
if (strpos($field, '.') === false) {
// some fields may be surrogates added by extending augmentSQL (e.g. fluent)
// we have to preserve those expressions rather than auto-generated names
// that SQLSelect::addOrderBy leaves for them (usually that's alike _SortColumn0)
//
// see related issues for more details:
// - https://github.com/silverstripe/silverstripe-asset-admin/issues/820
// - https://github.com/silverstripe/silverstripe-asset-admin/issues/893
$field = $query->expressionForField(trim($field, '"')) ?: $field;
}

$existingOrderBys[$field] = $direction;
}

// Folders should always go first due to backwards compatibility
// See https://github.com/silverstripe/silverstripe-asset-admin/issues/893
$dataQuery->sort(
sprintf(
'(CASE WHEN "ClassName"=%s THEN 1 ELSE 0 END)',
DB::get_conn()->quoteString('SilverStripe\Assets\Folder')
),
'DESC',
true
);

foreach ($existingOrderBys as $field => $dir) {
$dataQuery->sort($field, $dir, false);
}

return $dataQuery;
});
}


// DataQuery::column ignores surrogate sorting fields
// see https://github.com/silverstripe/silverstripe-framework/issues/8926
// the following line is a workaround for `$ids = $list->column('ID');`
$ids = $list->dataQuery()->execute()->column('ID');

$permissionChecker = File::singleton()->getPermissionChecker();
$canViewIDs = array_keys(array_filter($permissionChecker->canViewMultiple(
$ids,
$context['currentUser']
)));

// Filter by visible IDs (or force empty set if none are visible)
// Remove the limit as it no longer applies. We've already filtered down to the exact
// IDs we need.
Expand Down
20 changes: 20 additions & 0 deletions tests/php/GraphQL/FolderTypeCreatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ class FolderTypeCreatorTest extends SapphireTest

protected $usesDatabase = true;

public function testItSortsChildrenOnTypeByDefault()
{
$rootFolder = Folder::singleton();
$file = File::create(['Name' => 'aaa file']);
$file->write();
$folder = Folder::create(['Name' => 'bbb folder']);
$folder->write();
$list = $this->resolveChildrenConnection(
$rootFolder,
[]
);
$this->assertEquals(
[
$folder->Name,
$file->Name,
],
$list['edges']->column('Name')
);
}

public function testItDoesNotFilterByParentIdWithRecursiveFlag()
{
$rootFolder = Folder::singleton();
Expand Down

0 comments on commit 4971b81

Please sign in to comment.