11<?php
22
33declare (strict_types=1 );
4- /**
5- * @copyright Copyright (c) 2018 Roeland Jago Douma <roeland@famdouma.nl>
6- *
7- * @author Florent Poinsaut <florent@solution-libre.fr>
8- * @author Roeland Jago Douma <roeland@famdouma.nl>
9- * @author John Molakvoæ <skjnldsv@protonmail.com>
10- *
11- * @license GNU AGPL version 3 or any later version
12- *
13- * This program is free software: you can redistribute it and/or modify
14- * it under the terms of the GNU Affero General Public License as
15- * published by the Free Software Foundation, either version 3 of the
16- * License, or (at your option) any later version.
17- *
18- * This program is distributed in the hope that it will be useful,
19- * but WITHOUT ANY WARRANTY; without even the implied warranty of
20- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21- * GNU Affero General Public License for more details.
22- *
23- * You should have received a copy of the GNU Affero General Public License
24- * along with this program. If not, see <http://www.gnu.org/licenses/>.
25- *
26- */
4+
5+ // SPDX-FileCopyrightText: 2018 Nextcloud GmbH
6+ // SPDX-FileCopyrightText: 2022 Solution Libre SAS
7+ // SPDX-FileContributor: Roeland Jago Douma <roeland@famdouma.nl>
8+ // SPDX-FileContributor: Florent Poinsaut <florent@solution-libre.fr>
9+ // SPDX-FileContributor: John Molakvoæ <skjnldsv@protonmail.com>
2710
2811namespace OCA \ShareListing \Service ;
2912
3316use OCP \Files \Folder ;
3417use OCP \Files \IRootFolder ;
3518use OCP \Files \NotFoundException ;
36- use OCP \IUserManager ;
3719use OCP \Share ;
3820use OCP \Share \IManager as ShareManager ;
3921use OCP \Share \IShare ;
4426use function iter \filter ;
4527use function iter \map ;
4628
47- class SharesList {
29+ final class SharesList {
4830
4931 public const FILTER_NONE = 0 ;
5032 public const FILTER_OWNER = 1 ;
@@ -56,11 +38,13 @@ class SharesList {
5638
5739 public function __construct (
5840 private ShareManager $ shareManager ,
59- private IUserManager $ userManager ,
6041 private IRootFolder $ rootFolder ,
6142 ) {
6243 }
6344
45+ /**
46+ * @return non-empty-array<IShare::TYPE_*>
47+ */
6448 private function getShareTypes (): array {
6549 return [
6650 IShare::TYPE_USER ,
@@ -71,11 +55,18 @@ private function getShareTypes(): array {
7155 ];
7256 }
7357
58+ /**
59+ * @return Iterator<IShare>
60+ */
7461 public function get (?string $ userId , int $ filter , ?string $ path = null , ?string $ token = null ): Iterator {
62+ /** @var iterable<IShare> $shares */
7563 $ shares = $ this ->getShares ($ userId );
7664
7765 // If path is set. Filter for the current user
7866 if ($ path !== null ) {
67+ if ($ userId === null ) {
68+ throw new \RuntimeException ('Unable to query a path if no user is set. ' );
69+ }
7970 $ userFolder = $ this ->rootFolder ->getUserFolder ($ userId );
8071 try {
8172 $ node = $ userFolder ->get ($ path );
@@ -137,8 +128,10 @@ public function get(?string $userId, int $filter, ?string $path = null, ?string
137128 * Get all shares. And filter them by being a subpath of the current path.
138129 * This allows us to build a list of subfiles/folder that are shared
139130 * as well
131+ * @return Iterator<IShare>
140132 */
141133 public function getSub (string $ userId , int $ filter , string $ path ): Iterator {
134+ /** @var iterable<IShare> $shares */
142135 $ shares = $ this ->shareManager ->getAllShares ();
143136
144137 // If path is set. Filter for the current user
@@ -150,7 +143,7 @@ public function getSub(string $userId, int $filter, string $path): Iterator {
150143 return new EmptyIterator ();
151144 }
152145
153- $ shares = filter (function (IShare $ share ) use ($ node ) {
146+ $ shares = filter (function (IShare $ share ) use ($ node ): bool {
154147 if ($ node ->getId () === $ share ->getNodeId ()) {
155148 return false ;
156149 }
@@ -161,30 +154,26 @@ public function getSub(string $userId, int $filter, string $path): Iterator {
161154 }, $ shares );
162155
163156 if ($ filter === self ::FILTER_OWNER ) {
164- $ shares = filter (fn (IShare $ share ) => $ share ->getShareOwner () === $ userId , $ shares );
157+ $ shares = filter (fn (IShare $ share ): bool => $ share ->getShareOwner () === $ userId , $ shares );
165158 }
166159 if ($ filter === self ::FILTER_INITIATOR ) {
167- $ shares = filter (fn (IShare $ share ) => $ share ->getSharedBy () === $ userId , $ shares );
160+ $ shares = filter (fn (IShare $ share ): bool => $ share ->getSharedBy () === $ userId , $ shares );
168161 }
169162 if ($ filter === self ::FILTER_RECIPIENT ) {
170163 // We can't check the recipient since this might be a group share etc. However you can't share to yourself
171- $ shares = filter (fn (IShare $ share ) => $ share ->getShareOwner () !== $ userId && $ share ->getSharedBy () !== $ userId , $ shares );
164+ $ shares = filter (fn (IShare $ share ): bool => $ share ->getShareOwner () !== $ userId && $ share ->getSharedBy () !== $ userId , $ shares );
172165 }
173166
174- $ shares = filter (function (IShare $ share ) {
167+ return filter (function (IShare $ share ): bool {
175168 try {
176169 $ userFolder = $ this ->rootFolder ->getUserFolder ($ share ->getShareOwner ());
177- } catch (NoUserException ) {
178- return false ;
179170 } catch (Throwable ) {
180171 return false ;
181172 }
182173 $ nodes = $ userFolder ->getById ($ share ->getNodeId ());
183174
184175 return $ nodes !== [];
185176 }, $ shares );
186-
187- return $ shares ;
188177 }
189178
190179 public function getFormattedShares (?string $ userId = null , int $ filter = self ::FILTER_NONE , ?string $ path = null , ?string $ token = null ): Iterator {
@@ -196,7 +185,8 @@ public function getFormattedShares(?string $userId = null, int $filter = self::F
196185 }
197186
198187 private function getShares (?string $ userId ): Iterator {
199- if (empty ($ userId )) {
188+ if ($ userId === null ) {
189+ /** @var iterable<IShare> $shares */
200190 $ shares = $ this ->shareManager ->getAllShares ();
201191 } else {
202192 $ shareTypes = $ this ->getShareTypes ();
@@ -232,12 +222,12 @@ public function formatShare(IShare $share): array {
232222 ];
233223
234224 $ nodes = $ userFolder ->getById ($ share ->getNodeId ());
235- $ node = array_shift ( $ nodes );
236- $ data [ ' path ' ] = $ userFolder -> getRelativePath ( $ node -> getPath () );
237- $ data ['name ' ] = $ node ->getName ( );
238- $ data ['is_directory ' ] = $ node ->getType () === ' dir ' ;
239-
240-
225+ if (! empty ( $ nodes )) {
226+ $ node = array_shift ( $ nodes );
227+ $ data ['path ' ] = $ userFolder -> getRelativePath ( $ node ->getPath () );
228+ $ data ['name ' ] = $ node ->getName () ;
229+ $ data [ ' is_directory ' ] = $ node -> getType () === ' dir ' ;
230+ }
241231
242232 if ($ share ->getShareType () === IShare::TYPE_USER ) {
243233 $ data ['type ' ] = 'user ' ;
@@ -261,24 +251,23 @@ public function formatShare(IShare $share): array {
261251 $ data ['recipient ' ] = $ share ->getSharedWith ();
262252 }
263253
264- if ($ share ->getExpirationDate () !== null ) {
265- $ data ['expiration ' ] = $ share ->getExpirationDate ()->format ('Y-m-d H:i:s ' );
254+ $ expirationDate = $ share ->getExpirationDate ();
255+ if ($ expirationDate !== null ) {
256+ $ data ['expiration ' ] = $ expirationDate ->format ('Y-m-d H:i:s ' );
266257 }
267258
268259 return $ data ;
269260 }
270261
271262 public function filterStringToInt (?string $ filterString ): int {
272- $ filter = match ($ filterString ) {
263+ return match ($ filterString ) {
273264 'owner ' => SharesList::FILTER_OWNER ,
274265 'initiator ' => SharesList::FILTER_INITIATOR ,
275266 'recipient ' => SharesList::FILTER_RECIPIENT ,
276267 'has-expiration ' => SharesList::FILTER_HAS_EXPIRATION ,
277268 'no-expiration ' => SharesList::FILTER_NO_EXPIRATION ,
278269 default => SharesList::FILTER_NONE ,
279270 };
280-
281- return $ filter ;
282271 }
283272
284273 public function getSerializedShares (array $ shares , ?string $ format = 'json ' ): string {
0 commit comments