diff options
author | Christopher Ng <chrng8@gmail.com> | 2024-07-29 11:42:09 -0700 |
---|---|---|
committer | Christopher Ng <chrng8@gmail.com> | 2024-07-29 11:42:09 -0700 |
commit | 87f0676b3259e682eaa0fca83d1854525291d514 (patch) | |
tree | ee85fa2e68ac7489de4d739df59b77674492103f | |
parent | 75e194113bc1c1b416d1adc1318824d2c55e0d25 (diff) | |
download | nextcloud-server-test/folder-tree.tar.gz nextcloud-server-test/folder-tree.zip |
feat: Implement folder tree endpointstest/folder-tree
Signed-off-by: Christopher Ng <chrng8@gmail.com>
-rw-r--r-- | apps/files/lib/Controller/ApiController.php | 148 |
1 files changed, 123 insertions, 25 deletions
diff --git a/apps/files/lib/Controller/ApiController.php b/apps/files/lib/Controller/ApiController.php index 9cf634f9404..b91eb82c604 100644 --- a/apps/files/lib/Controller/ApiController.php +++ b/apps/files/lib/Controller/ApiController.php @@ -8,11 +8,16 @@ namespace OCA\Files\Controller; 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; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\DataResponse; @@ -20,10 +25,14 @@ 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\IUserSession; @@ -34,34 +43,20 @@ use OCP\Share\IShare; * @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, + ) { 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; } /** @@ -231,6 +226,109 @@ class ApiController extends Controller { return new DataResponse(['files' => $files]); } + /** + * @param Folder[] $folders + */ + private function getChildrenFromAllFolders(array $folders): array { + $user = $this->userSession->getUser(); + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + $tree = []; + + foreach ($folders as $folder) { + $path = $userFolder->getRelativePath($folder->getPath()); + $pathSegments = explode('/', trim($path, '/')); + $current = &$tree; + foreach ($pathSegments as $name) { + if (empty($current['children'][$name])) { + $current['children'][$name] = [ + 'children' => [], + ]; + if ($name !== $folder->getName()) { + $current['children'][$name]['displayName'] = $folder->getName(); + } + } + $current = &$current['children'][$name]; + } + } + + return $tree['children'] ?? $tree; + } + + /** + * Returns a folder tree of the user's files. + */ + #[NoAdminRequired] + #[NoCSRFRequired] // TODO Remove + #[ApiRoute(verb: 'GET', url: '/api/v1/folder-tree-search')] + public function getFolderTreeSearch(): JSONResponse { + $user = $this->userSession->getUser(); + + $start = microtime(true); + try { + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + $searchQuery = new SearchQuery( + new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE), + 0, + 0, + [], + $user, + false, + ); + /** @var Folder[] $folders */ + $folders = $userFolder->search($searchQuery); + $children = $this->getChildrenFromAllFolders($folders); + } catch (\RuntimeException $e) { + $children = []; + } + $executionTime = microtime(true) - $start; + + return new JSONResponse([ + 'executionTime' => $executionTime, + 'children' => $children, + ]); + } + + /** + * @param \OCP\Files\Node[] $nodes + */ + private function getChildren(array $nodes): array { + $children = []; + foreach ($nodes as $node) { + if (!($node instanceof Folder)) { + continue; + } + $basename = basename($node->getPath()); + $entry = [ + 'basename' => $basename, + 'children' => $this->getChildren($node->getDirectoryListing()), + ]; + if ($basename !== $node->getName()) { + $entry['displayName'] = $node->getName(); + } + $children[] = $entry; + } + return $children; + } + + /** + * Returns a folder tree of the user's files. + */ + #[NoAdminRequired] + #[NoCSRFRequired] // TODO Remove + #[ApiRoute(verb: 'GET', url: '/api/v1/folder-tree')] + public function getFolderTree(): JSONResponse { + $user = $this->userSession->getUser(); + + $start = microtime(true); + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + $children = $this->getChildren($userFolder->getDirectoryListing()); + $executionTime = microtime(true) - $start; + + return new JSONResponse([ + 'executionTime' => $executionTime, + 'children' => $children, + ]); + } /** * Returns the current logged-in user's storage stats. |