3939class FolderController extends OCSController {
4040 private ?IUser $ user ;
4141
42- protected const ALLOWED_ORDER_BY = [
43- 'mount_point ' ,
44- 'quota ' ,
45- 'groups ' ,
46- 'acl ' ,
47- ];
48-
4942 public function __construct (
5043 string $ AppName ,
5144 IRequest $ request ,
@@ -102,7 +95,8 @@ private function formatFolder(array $folder): array {
10295 * @param bool $applicable Filter by applicable groups
10396 * @param non-negative-int $offset Number of items to skip.
10497 * @param ?positive-int $limit Number of items to return.
105- * @param null|'mount_point'|'quota'|'groups'|'acl' $orderBy The key to order by
98+ * @param 'mount_point'|'quota'|'groups'|'acl' $orderBy The key to order by
99+ * @param 'asc'|'desc' $order Sort ascending or descending
106100 * @return DataResponse<Http::STATUS_OK, array<string, GroupFoldersFolder>, array{}>
107101 * @throws OCSNotFoundException Storage not found
108102 * @throws OCSBadRequestException Wrong limit used
@@ -111,58 +105,39 @@ private function formatFolder(array $folder): array {
111105 */
112106 #[NoAdminRequired]
113107 #[FrontpageRoute(verb: 'GET ' , url: '/folders ' )]
114- public function getFolders (bool $ applicable = false , int $ offset = 0 , ?int $ limit = null , ?string $ orderBy = 'mount_point ' ): DataResponse {
108+ public function getFolders (bool $ applicable = false , int $ offset = 0 , ?int $ limit = null , string $ orderBy = 'mount_point ' , string $ order = 'asc ' ): DataResponse {
109+ /** @psalm-suppress DocblockTypeContradiction */
115110 if ($ limit !== null && $ limit <= 0 ) {
116111 throw new OCSBadRequestException ('The limit must be greater than 0. ' );
117112 }
118113
114+ /** @psalm-suppress DocblockTypeContradiction */
115+ if (!in_array ($ orderBy , ['mount_point ' , 'quota ' , 'groups ' , 'acl ' ], true )) {
116+ throw new OCSBadRequestException ('The orderBy is not allowed. ' );
117+ }
118+
119+ /** @psalm-suppress DocblockTypeContradiction */
120+ if (!in_array ($ order , ['asc ' , 'desc ' ], true )) {
121+ throw new OCSBadRequestException ('The order is not allowed. ' );
122+ }
123+
119124 $ storageId = $ this ->getRootFolderStorageId ();
120125 if ($ storageId === null ) {
121126 throw new OCSNotFoundException ();
122127 }
123128
124129 $ folders = [];
125- foreach ($ this ->manager ->getAllFoldersWithSize ($ storageId ) as $ id => $ folder ) {
130+ $ i = 0 ;
131+ foreach ($ this ->manager ->getAllFoldersWithSize ($ storageId , $ offset , $ limit , $ orderBy , $ order ) as $ id => $ folder ) {
126132 // Make them string-indexed for OpenAPI JSON output
127- $ folders [(string )$ id ] = $ this ->formatFolder ($ folder );
128- }
129-
130- $ orderBy = in_array ($ orderBy , self ::ALLOWED_ORDER_BY , true )
131- ? $ orderBy
132- : 'mount_point ' ;
133-
134- // in case of equal orderBy value always fall back to the mount_point - same as on the frontend
135- /**
136- * @var GroupFoldersFolder $a
137- * @var GroupFoldersFolder $b
138- */
139- uasort ($ folders , function (array $ a , array $ b ) use ($ orderBy ) {
140- if ($ orderBy === 'groups ' ) {
141- if (($ value = count ($ a ['groups ' ]) - count ($ b ['groups ' ])) !== 0 ) {
142- return $ value ;
143- }
144- } else {
145- if (($ value = $ this ->compareFolderNames ((string )($ a [$ orderBy ] ?? '' ), (string )($ b [$ orderBy ] ?? '' ))) !== 0 ) {
146- return $ value ;
147- }
148- }
149-
150- // fallback to mount_point
151- if (($ value = $ this ->compareFolderNames ($ a ['mount_point ' ] ?? '' , $ b ['mount_point ' ])) !== 0 ) {
152- return $ value ;
153- }
154-
155- // fallback to id
156- return $ a ['id ' ] - $ b ['id ' ];
157- });
133+ // JavaScript doesn't preserve JSON object key orders, so we need to manually add this information.
134+ $ folders [(string )$ id ] = array_merge ($ this ->formatFolder ($ folder ), [
135+ 'sortIndex ' => $ offset + $ i ++,
136+ ]);
137+ }
158138
159139 $ isAdmin = $ this ->delegationService ->isAdminNextcloud () || $ this ->delegationService ->isDelegatedAdmin ();
160140 if ($ isAdmin && !$ applicable ) {
161- // If only the default values are provided the pagination can be skipped.
162- if ($ offset !== 0 || $ limit !== null ) {
163- $ folders = array_slice ($ folders , $ offset , $ limit , true );
164- }
165-
166141 return new DataResponse ($ folders );
167142 }
168143
@@ -174,11 +149,6 @@ public function getFolders(bool $applicable = false, int $offset = 0, ?int $limi
174149 $ folders = array_filter (array_map ($ this ->filterNonAdminFolder (...), $ folders ));
175150 }
176151
177- // If only the default values are provided the pagination can be skipped.
178- if ($ offset !== 0 || $ limit !== null ) {
179- $ folders = array_slice ($ folders , $ offset , $ limit , true );
180- }
181-
182152 return new DataResponse ($ folders );
183153 }
184154
0 commit comments