diff options
author | Christopher Ng <chrng8@gmail.com> | 2024-07-30 18:19:55 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2024-08-01 09:14:44 -0700 |
commit | aa4d82d428c7125cd1286047e7531a62ce72af6d (patch) | |
tree | 3d861b74d39983e58e021a1b068153a7a89c2031 /apps/files/lib/Controller/ApiController.php | |
parent | 8bbd3261434e4d0cc6eb6a4350e101a0428a4804 (diff) | |
download | nextcloud-server-aa4d82d428c7125cd1286047e7531a62ce72af6d.tar.gz nextcloud-server-aa4d82d428c7125cd1286047e7531a62ce72af6d.zip |
feat(files): Implement endpoint to retrieve a user's folder tree
Signed-off-by: Christopher Ng <chrng8@gmail.com>
Diffstat (limited to 'apps/files/lib/Controller/ApiController.php')
-rw-r--r-- | apps/files/lib/Controller/ApiController.php | 114 |
1 files changed, 89 insertions, 25 deletions
diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php index 2581faa4d8d..e5b9086995e 100644 --- a/apps/files/lib/Controller/ApiController.php +++ b/apps/files/lib/Controller/ApiController.php @@ -7,12 +7,16 @@ */ namespace OCA\Files\Controller; +use OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException; use OC\Files\Node\Node; +use OC\Files\Search\SearchComparison; +use OC\Files\Search\SearchQuery; use OCA\Files\Service\TagService; use OCA\Files\Service\UserConfig; use OCA\Files\Service\ViewConfig; use OCP\AppFramework\Controller; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\ApiRoute; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\Attribute\OpenAPI; @@ -24,48 +28,42 @@ use OCP\AppFramework\Http\FileDisplayResponse; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\StreamResponse; +use OCP\Files\Cache\ICacheEntry; use OCP\Files\File; use OCP\Files\Folder; +use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; +use OCP\Files\Search\ISearchComparison; use OCP\IConfig; +use OCP\IL10N; use OCP\IPreview; use OCP\IRequest; +use OCP\IUser; use OCP\IUserSession; use OCP\Share\IManager; use OCP\Share\IShare; +use Psr\Log\LoggerInterface; +use Throwable; /** * @package OCA\Files\Controller */ class ApiController extends Controller { - private TagService $tagService; - private IManager $shareManager; - private IPreview $previewManager; - private IUserSession $userSession; - private IConfig $config; - private ?Folder $userFolder; - private UserConfig $userConfig; - private ViewConfig $viewConfig; - public function __construct(string $appName, IRequest $request, - IUserSession $userSession, - TagService $tagService, - IPreview $previewManager, - IManager $shareManager, - IConfig $config, - ?Folder $userFolder, - UserConfig $userConfig, - ViewConfig $viewConfig) { + private IUserSession $userSession, + private TagService $tagService, + private IPreview $previewManager, + private IManager $shareManager, + private IConfig $config, + private ?Folder $userFolder, + private UserConfig $userConfig, + private ViewConfig $viewConfig, + private IL10N $l10n, + private IRootFolder $rootFolder, + private LoggerInterface $logger, + ) { parent::__construct($appName, $request); - $this->userSession = $userSession; - $this->tagService = $tagService; - $this->previewManager = $previewManager; - $this->shareManager = $shareManager; - $this->config = $config; - $this->userFolder = $userFolder; - $this->userConfig = $userConfig; - $this->viewConfig = $viewConfig; } /** @@ -232,6 +230,72 @@ class ApiController extends Controller { return new DataResponse(['files' => $files]); } + /** + * @param Folder[] $folders + */ + private function getTree(array $folders): array { + $user = $this->userSession->getUser(); + if (!($user instanceof IUser)) { + throw new NotLoggedInException(); + } + + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + $tree = []; + foreach ($folders as $folder) { + $path = $userFolder->getRelativePath($folder->getPath()); + if ($path === null) { + continue; + } + $pathBasenames = explode('/', trim($path, '/')); + $current = &$tree; + foreach ($pathBasenames as $basename) { + if (!isset($current['children'][$basename])) { + $current['children'][$basename] = [ + 'id' => $folder->getId(), + ]; + $displayName = $folder->getName(); + if ($displayName !== $basename) { + $current['children'][$basename]['displayName'] = $displayName; + } + } + $current = &$current['children'][$basename]; + } + } + return $tree['children'] ?? $tree; + } + + /** + * Returns a folder tree for the user. + */ + #[NoAdminRequired] + #[ApiRoute(verb: 'GET', url: '/api/v1/folder-tree')] + public function getFolderTree(): JSONResponse { + $user = $this->userSession->getUser(); + if (!($user instanceof IUser)) { + return new JSONResponse([ + 'message' => $this->l10n->t('Failed to authorize'), + ], Http::STATUS_UNAUTHORIZED); + } + + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + try { + $searchQuery = new SearchQuery( + new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE), + 0, + 0, + [], + $user, + false, + ); + /** @var Folder[] $folders */ + $folders = $userFolder->search($searchQuery); + $tree = $this->getTree($folders); + } catch (Throwable $th) { + $this->logger->error($th->getMessage(), ['exception' => $th]); + $tree = []; + } + return new JSONResponse($tree, Http::STATUS_OK, [], JSON_FORCE_OBJECT); + } /** * Returns the current logged-in user's storage stats. |