From 87bee943767cca6ef1f6103413b89ba7d92db8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Thu, 21 Aug 2025 22:28:58 +0200 Subject: [PATCH 1/4] feat: Query storageId and rootId from database MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- lib/Controller/FolderController.php | 4 ++ lib/Folder/FolderManager.php | 74 +++++++++++++++++------------ 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/lib/Controller/FolderController.php b/lib/Controller/FolderController.php index b067e3f99..47c21a617 100644 --- a/lib/Controller/FolderController.php +++ b/lib/Controller/FolderController.php @@ -92,6 +92,10 @@ private function formatFolder(array $folder): array { $folder['group_details'] = $folder['groups']; $folder['groups'] = array_map(fn (array $group): int => $group['permissions'], $folder['groups']); + // Remove fields that are not available on GroupFoldersFolder + unset($folder['root_id']); + unset($folder['storage_id']); + return $folder; } diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index bbb2ad478..c6a218d75 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -51,6 +51,8 @@ * permissions: int, * quota: int, * acl: bool, + * storage_id: int, + * root_id: int, * rootCacheEntry: ?CacheEntry, * } * @psalm-type InternalFolderOut = array{ @@ -60,6 +62,8 @@ * quota: int, * size: int, * acl: bool, + * storage_id: int, + * root_id: int, * manage: list, * } * @psalm-type InternalFolderMapping = array{ @@ -92,7 +96,7 @@ public function getAllFolders(): array { $query = $this->connection->getQueryBuilder(); - $query->select('folder_id', 'mount_point', 'quota', 'acl') + $query->select('folder_id', 'mount_point', 'quota', 'acl', 'storage_id', 'root_id') ->from('group_folders', 'f'); $rows = $query->executeQuery()->fetchAll(); @@ -106,7 +110,9 @@ public function getAllFolders(): array { 'groups' => $applicableMap[$id] ?? [], 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => 0, - 'acl' => (bool)$row['acl'] + 'acl' => (bool)$row['acl'], + 'storage_id' => (int)$row['storage_id'], + 'root_id' => (int)$row['root_id'], ]; } @@ -147,7 +153,7 @@ public function getAllFoldersWithSize(int $rootStorageId): array { $query = $this->connection->getQueryBuilder(); - $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl') + $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl', 'storage_id', 'root_id') ->from('group_folders', 'f'); $this->joinQueryWithFileCache($query, $rootStorageId); @@ -166,6 +172,8 @@ public function getAllFoldersWithSize(int $rootStorageId): array { 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ? (int)$row['size'] : 0, 'acl' => (bool)$row['acl'], + 'storage_id' => (int)$row['storage_id'], + 'root_id' => (int)$row['root_id'], 'manage' => $this->getManageAcl($mappings) ]; } @@ -183,7 +191,7 @@ public function getAllFoldersForUserWithSize(int $rootStorageId, IUser $user): a $query = $this->connection->getQueryBuilder(); - $query->select('f.folder_id', 'mount_point', 'quota', 'c.size', 'acl') + $query->select('f.folder_id', 'mount_point', 'quota', 'c.size', 'acl', 'storage_id', 'root_id') ->from('group_folders', 'f') ->innerJoin( 'f', @@ -209,6 +217,8 @@ public function getAllFoldersForUserWithSize(int $rootStorageId, IUser $user): a 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ? (int)$row['size'] : 0, 'acl' => (bool)$row['acl'], + 'storage_id' => (int)$row['storage_id'], + 'root_id' => (int)$row['root_id'], 'manage' => $this->getManageAcl($mappings) ]; } @@ -313,7 +323,7 @@ public function getFolder(int $id, int $rootStorageId = 0): ?array { $query = $this->connection->getQueryBuilder(); - $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl') + $query->select('folder_id', 'mount_point', 'quota', 'c.size', 'acl', 'storage_id', 'root_id') ->from('group_folders', 'f') ->where($query->expr()->eq('folder_id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT))); $this->joinQueryWithFileCache($query, $rootStorageId); @@ -329,11 +339,14 @@ public function getFolder(int $id, int $rootStorageId = 0): ?array { return [ 'id' => $id, + 'folder_id' => $id, 'mount_point' => (string)$row['mount_point'], 'groups' => $applicableMap[$id] ?? [], 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ?: 0, 'acl' => (bool)$row['acl'], + 'storage_id' => (int)$row['storage_id'], + 'root_id' => (int)$row['root_id'], 'manage' => $this->getManageAcl($folderMappings) ]; } @@ -573,6 +586,22 @@ public function searchUsers(int $id, string $search = '', int $limit = 10, int $ return array_values($users); } + /** + * @return list + */ + private function rowsToFolders(array $rows): array { + return array_values(array_map(fn (array $folder): array => [ + 'folder_id' => (int)$folder['folder_id'], + 'mount_point' => (string)$folder['mount_point'], + 'permissions' => (int)$folder['group_permissions'], + 'quota' => $this->getRealQuota((int)$folder['quota']), + 'acl' => (bool)$folder['acl'], + 'storage_id' => (int)$folder['storage_id'], + 'root_id' => (int)$folder['root_id'], + 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null + ], $rows)); + } + /** * @return list * @throws Exception @@ -585,6 +614,8 @@ public function getFoldersForGroup(string $groupId, int $rootStorageId = 0): arr 'mount_point', 'quota', 'acl', + 'storage_id', + 'root_id', 'c.fileid', 'c.storage', 'c.path', @@ -610,16 +641,7 @@ public function getFoldersForGroup(string $groupId, int $rootStorageId = 0): arr ->where($query->expr()->eq('a.group_id', $query->createNamedParameter($groupId))); $this->joinQueryWithFileCache($query, $rootStorageId); - $result = $query->executeQuery()->fetchAll(); - - return array_values(array_map(fn (array $folder): array => [ - 'folder_id' => (int)$folder['folder_id'], - 'mount_point' => (string)$folder['mount_point'], - 'permissions' => (int)$folder['group_permissions'], - 'quota' => $this->getRealQuota((int)$folder['quota']), - 'acl' => (bool)$folder['acl'], - 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null - ], $result)); + return $this->rowsToFolders($query->executeQuery()->fetchAll()); } /** @@ -635,6 +657,8 @@ public function getFoldersForGroups(array $groupIds, int $rootStorageId = 0): ar 'mount_point', 'quota', 'acl', + 'storage_id', + 'root_id', 'c.fileid', 'c.storage', 'c.path', @@ -667,14 +691,7 @@ public function getFoldersForGroups(array $groupIds, int $rootStorageId = 0): ar $result = array_merge($result, $query->executeQuery()->fetchAll()); } - return array_map(fn (array $folder): array => [ - 'folder_id' => (int)$folder['folder_id'], - 'mount_point' => (string)$folder['mount_point'], - 'permissions' => (int)$folder['group_permissions'], - 'quota' => $this->getRealQuota((int)$folder['quota']), - 'acl' => (bool)$folder['acl'], - 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null - ], array_values($result)); + return $this->rowsToFolders($result); } /** @@ -701,6 +718,8 @@ public function getFoldersFromCircleMemberships(IUser $user, int $rootStorageId 'f.mount_point', 'f.quota', 'f.acl', + 'f.storage_id', + 'f.root_id', 'c.fileid', 'c.storage', 'c.path', @@ -733,14 +752,7 @@ public function getFoldersFromCircleMemberships(IUser $user, int $rootStorageId } $this->joinQueryWithFileCache($query, $rootStorageId); - return array_map(fn (array $folder): array => [ - 'folder_id' => (int)$folder['folder_id'], - 'mount_point' => (string)$folder['mount_point'], - 'permissions' => (int)$folder['group_permissions'], - 'quota' => $this->getRealQuota((int)$folder['quota']), - 'acl' => (bool)$folder['acl'], - 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null - ], array_values($query->executeQuery()->fetchAll())); + return $this->rowsToFolders($query->executeQuery()->fetchAll()); } From 32763c4fdc1301fccc7a3fdfd99fb01852482850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Thu, 21 Aug 2025 21:59:15 +0200 Subject: [PATCH 2/4] chore: Remove unused getGroupFolderRootId MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- lib/Folder/FolderManager.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index c6a218d75..8f9addaed 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -119,20 +119,6 @@ public function getAllFolders(): array { return $folderMap; } - /** - * @throws Exception - */ - private function getGroupFolderRootId(int $rootStorageId): int { - $query = $this->connection->getQueryBuilder(); - - $query->select('fileid') - ->from('filecache') - ->where($query->expr()->eq('storage', $query->createNamedParameter($rootStorageId))) - ->andWhere($query->expr()->eq('path_hash', $query->createNamedParameter(md5('__groupfolders')))); - - return (int)$query->executeQuery()->fetchOne(); - } - private function joinQueryWithFileCache(IQueryBuilder $query, int $rootStorageId): void { $conditions = [ $query->expr()->eq('c.fileid', 'f.root_id'), From 831c037ea385d592416c1d863f71e6abb294caec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Wed, 20 Aug 2025 21:09:07 +0200 Subject: [PATCH 3/4] fix: Reuse already known rootId MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- lib/Mount/GroupMountPoint.php | 2 ++ lib/Mount/MountProvider.php | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Mount/GroupMountPoint.php b/lib/Mount/GroupMountPoint.php index 4facb1f11..0c75a3d29 100644 --- a/lib/Mount/GroupMountPoint.php +++ b/lib/Mount/GroupMountPoint.php @@ -22,9 +22,11 @@ public function __construct( ?IStorageFactory $loader = null, ?array $mountOptions = null, ?int $mountId = null, + ?int $rootId = null, ) { /** @var Storage $storage */ parent::__construct($storage, $mountpoint, $arguments, $loader, $mountOptions, $mountId, MountProvider::class); + $this->rootId = $rootId; } public function getMountType(): string { diff --git a/lib/Mount/MountProvider.php b/lib/Mount/MountProvider.php index daa3ee1c4..2c52080c0 100644 --- a/lib/Mount/MountProvider.php +++ b/lib/Mount/MountProvider.php @@ -112,7 +112,8 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader): array { $folder['acl'], $user, $aclManager, - $rootRules + $rootRules, + $folder['root_id'], ); }, $folders)); } @@ -147,6 +148,7 @@ public function getMount( ?IUser $user = null, ?ACLManager $aclManager = null, array $rootRules = [], + ?int $rootId = null, ): ?IMountPoint { if (!$cacheEntry) { // trigger folder creation @@ -199,7 +201,8 @@ public function getMount( $maskedStore, $mountPoint, null, - $loader + $loader, + rootId: $rootId, ); } From 4b46c2a35590987b168b139d7556a3691fd54813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=BCller?= Date: Thu, 21 Aug 2025 22:36:27 +0200 Subject: [PATCH 4/4] chore: Unset rootId and storageId in tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcel Müller --- tests/Folder/FolderManagerTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Folder/FolderManagerTest.php b/tests/Folder/FolderManagerTest.php index a348b03a1..c9482e4b0 100644 --- a/tests/Folder/FolderManagerTest.php +++ b/tests/Folder/FolderManagerTest.php @@ -88,6 +88,8 @@ private function assertHasFolders(array $folders): void { foreach ($existingFolders as &$existingFolder) { unset($existingFolder['id']); + unset($existingFolder['root_id']); + unset($existingFolder['storage_id']); } $this->assertEquals($folders, $existingFolders);