From bfa67339f71991bbabb9ecd1d635e251bad5edcf Mon Sep 17 00:00:00 2001 From: Serge Latyntcev Date: Wed, 17 Apr 2019 17:14:12 +1200 Subject: [PATCH] FIX folders always go first when ordering (revert to the original 4.0 behaviour) --- code/GraphQL/FolderTypeCreator.php | 46 ++++++++++++++++++++- tests/php/GraphQL/FolderTypeCreatorTest.php | 20 +++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/code/GraphQL/FolderTypeCreator.php b/code/GraphQL/FolderTypeCreator.php index a82f5d26f..fac5f80df 100644 --- a/code/GraphQL/FolderTypeCreator.php +++ b/code/GraphQL/FolderTypeCreator.php @@ -158,8 +158,52 @@ public function resolveChildrenConnection( $filter['parentId'] = $object->ID; $list = $filterInputType->filterList($list, $filter); + 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(Folder::class) + ), + 'DESC', + true + ); + + foreach ($existingOrderBys as $field => $dir) { + $dataQuery->sort($field, $dir, false); + } + + return $dataQuery; + }); + } + // Filter by permission - $ids = $list->column('ID'); + // 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, diff --git a/tests/php/GraphQL/FolderTypeCreatorTest.php b/tests/php/GraphQL/FolderTypeCreatorTest.php index 6b65f4b88..cc9657b31 100644 --- a/tests/php/GraphQL/FolderTypeCreatorTest.php +++ b/tests/php/GraphQL/FolderTypeCreatorTest.php @@ -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();