aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files
diff options
context:
space:
mode:
authorChristopher Ng <chrng8@gmail.com>2024-07-30 18:19:55 -0700
committerChristopher Ng <chrng8@gmail.com>2024-08-01 09:14:44 -0700
commitaa4d82d428c7125cd1286047e7531a62ce72af6d (patch)
tree3d861b74d39983e58e021a1b068153a7a89c2031 /apps/files
parent8bbd3261434e4d0cc6eb6a4350e101a0428a4804 (diff)
downloadnextcloud-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')
-rw-r--r--apps/files/lib/AppInfo/Application.php6
-rw-r--r--apps/files/lib/Controller/ApiController.php114
2 files changed, 95 insertions, 25 deletions
diff --git a/apps/files/lib/AppInfo/Application.php b/apps/files/lib/AppInfo/Application.php
index de0542c8ad3..3d2d0527072 100644
--- a/apps/files/lib/AppInfo/Application.php
+++ b/apps/files/lib/AppInfo/Application.php
@@ -41,7 +41,9 @@ use OCP\Files\Events\Node\BeforeNodeCopiedEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
+use OCP\Files\IRootFolder;
use OCP\IConfig;
+use OCP\IL10N;
use OCP\IPreview;
use OCP\IRequest;
use OCP\IServerContainer;
@@ -53,6 +55,7 @@ use OCP\Settings\Events\DeclarativeSettingsSetValueEvent;
use OCP\Share\IManager as IShareManager;
use OCP\Util;
use Psr\Container\ContainerInterface;
+use Psr\Log\LoggerInterface;
class Application extends App implements IBootstrap {
public const APP_ID = 'files';
@@ -80,6 +83,9 @@ class Application extends App implements IBootstrap {
$server->getUserFolder(),
$c->get(UserConfig::class),
$c->get(ViewConfig::class),
+ $c->get(IL10N::class),
+ $c->get(IRootFolder::class),
+ $c->get(LoggerInterface::class),
);
});
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.