From ff28ac7ea257ad3dd2b2b57dc3a543dd516c123b Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:28:27 +0100 Subject: [PATCH 1/6] refactor(files_sharing): apply DRY for user and node ID in MountProvider Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/MountProvider.php | 37 +++++++++++++----------- build/psalm-baseline.xml | 4 +-- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 349aa1cae88..962836f40a9 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -46,32 +46,34 @@ class MountProvider implements IMountProvider { * @return IMountPoint[] */ public function getMountsForUser(IUser $user, IStorageFactory $loader) { + $userId = $user->getUID(); $shares = array_merge( - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_USER, null, -1), - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_GROUP, null, -1), - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_CIRCLE, null, -1), - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_ROOM, null, -1), - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_DECK, null, -1), - $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_SCIENCEMESH, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_USER, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_GROUP, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_CIRCLE, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_ROOM, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_DECK, null, -1), + $this->shareManager->getSharedWith($userId, IShare::TYPE_SCIENCEMESH, null, -1), ); - // filter out excluded shares and group shares that includes self - $shares = array_filter($shares, function (IShare $share) use ($user) { - return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID() && $share->getSharedBy() !== $user->getUID(); + // filter out shares owned or shared by the user and ones for which + // the user has no permissions + $shares = array_filter($shares, function (IShare $share) use ($userId) { + return $share->getPermissions() > 0 && $share->getShareOwner() !== $userId && $share->getSharedBy() !== $userId; }); $superShares = $this->buildSuperShares($shares, $user); $allMounts = $this->mountManager->getAll(); $mounts = []; - $view = new View('/' . $user->getUID() . '/files'); + $view = new View('/' . $userId . '/files'); $ownerViews = []; - $sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($user->getUID()); + $sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($userId); /** @var CappedMemoryCache $folderExistCache */ $foldersExistCache = new CappedMemoryCache(); $validShareCache = $this->cacheFactory->createLocal('share-valid-mountpoint-max'); - $maxValidatedShare = $validShareCache->get($user->getUID()) ?? 0; + $maxValidatedShare = $validShareCache->get($userId) ?? 0; $newMaxValidatedShare = $maxValidatedShare; foreach ($superShares as $share) { @@ -95,7 +97,7 @@ class MountProvider implements IMountProvider { '\OCA\Files_Sharing\SharedStorage', $allMounts, [ - 'user' => $user->getUID(), + 'user' => $userId, // parent share 'superShare' => $parentShare, // children/component of the superShare @@ -131,7 +133,7 @@ class MountProvider implements IMountProvider { } } - $validShareCache->set($user->getUID(), $newMaxValidatedShare, 24 * 60 * 60); + $validShareCache->set($userId, $newMaxValidatedShare, 24 * 60 * 60); // array_filter removes the null values from the array return array_values(array_filter($mounts)); @@ -148,10 +150,11 @@ class MountProvider implements IMountProvider { $tmp = []; foreach ($shares as $share) { - if (!isset($tmp[$share->getNodeId()])) { - $tmp[$share->getNodeId()] = []; + $nodeId = $share->getNodeId(); + if (!isset($tmp[$nodeId])) { + $tmp[$nodeId] = []; } - $tmp[$share->getNodeId()][] = $share; + $tmp[$nodeId][] = $share; } $result = []; diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index a70e6bce393..916f142181e 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -1686,11 +1686,11 @@ getShareOwner() . '/files')]]> - getUID() . '/files')]]> + getShareOwner() . '/files')]]> - getUID() . '/files')]]> + From 2ae7c3ecae70c9b8d6427aa78ab822497d5b5738 Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:31:36 +0100 Subject: [PATCH 2/6] fix(files_sharing): remove unnecessary array_values in MountProvider Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/MountProvider.php | 2 +- build/psalm-baseline.xml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 962836f40a9..7c101314931 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -171,7 +171,7 @@ class MountProvider implements IMountProvider { $result[] = $tmp2; } - return array_values($result); + return $result; } /** diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index 916f142181e..e7c7f278c0a 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -1692,9 +1692,6 @@ getShareOwner() . '/files')]]> - - - From 111d9397ae5be63401f04e17fdd0f040c1e58d05 Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Thu, 30 Oct 2025 10:55:40 +0100 Subject: [PATCH 3/6] refactor(files_sharing): reduce complexity in MountProvider::buildSuperShares Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/MountProvider.php | 138 +++++++++++++++-------- 1 file changed, 92 insertions(+), 46 deletions(-) diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 7c101314931..0a6c80769b2 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -7,6 +7,7 @@ */ namespace OCA\Files_Sharing; +use InvalidArgumentException; use OC\Files\View; use OCA\Files_Sharing\Event\ShareMountedEvent; use OCP\Cache\CappedMemoryCache; @@ -18,6 +19,7 @@ use OCP\Files\Storage\IStorageFactory; use OCP\ICacheFactory; use OCP\IConfig; use OCP\IUser; +use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; use Psr\Log\LoggerInterface; @@ -175,23 +177,24 @@ class MountProvider implements IMountProvider { } /** - * Build super shares (virtual share) by grouping them by node id and target, - * then for each group compute the super share and return it along with the matching - * grouped shares. The most permissive permissions are used based on the permissions - * of all shares within the group. + * Groups shares by node ID and builds a new share object (super share) + * which represents a summarized version of all the shares in the group. + * + * The permissions and attributes of the super share are accumulated from + * the shares in the group, forming the most permissive combination + * possible. * * @param IShare[] $allShares * @param IUser $user user - * @return array Tuple of [superShare, groupedShares] + * @return list}> Tuple of [superShare, groupedShares] */ private function buildSuperShares(array $allShares, IUser $user) { $result = []; $groupedShares = $this->groupShares($allShares); - /** @var IShare[] $shares */ foreach ($groupedShares as $shares) { - if (count($shares) === 0) { + if (\count($shares) === 0) { continue; } @@ -204,14 +207,7 @@ class MountProvider implements IMountProvider { ->setShareType($shares[0]->getShareType()) ->setTarget($shares[0]->getTarget()); - // Gather notes from all the shares. - // Since these are readly available here, storing them - // enables the DAV FilesPlugin to avoid executing many - // DB queries to retrieve the same information. - $allNotes = implode("\n", array_map(function ($sh) { - return $sh->getNote(); - }, $shares)); - $superShare->setNote($allNotes); + $this->combineNotes($shares, $superShare); // use most permissive permissions // this covers the case where there are multiple shares for the same @@ -220,7 +216,6 @@ class MountProvider implements IMountProvider { $superAttributes = $this->shareManager->newShare()->newAttributes(); $status = IShare::STATUS_PENDING; foreach ($shares as $share) { - $superPermissions |= $share->getPermissions(); $status = max($status, $share->getStatus()); // update permissions $superPermissions |= $share->getPermissions(); @@ -228,38 +223,11 @@ class MountProvider implements IMountProvider { // update share permission attributes $attributes = $share->getAttributes(); if ($attributes !== null) { - foreach ($attributes->toArray() as $attribute) { - if ($superAttributes->getAttribute($attribute['scope'], $attribute['key']) === true) { - // if super share attribute is already enabled, it is most permissive - continue; - } - // update supershare attributes with subshare attribute - $superAttributes->setAttribute($attribute['scope'], $attribute['key'], $attribute['value']); - } + $this->mergeAttributes($attributes, $superAttributes); } - // adjust target, for database consistency if needed - if ($share->getTarget() !== $superShare->getTarget()) { - $share->setTarget($superShare->getTarget()); - try { - $this->shareManager->moveShare($share, $user->getUID()); - } catch (\InvalidArgumentException $e) { - // ignore as it is not important and we don't want to - // block FS setup - - // the subsequent code anyway only uses the target of the - // super share - - // such issue can usually happen when dealing with - // null groups which usually appear with group backend - // caching inconsistencies - $this->logger->debug( - 'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(), - ['app' => 'files_sharing'] - ); - } - } - if (!is_null($share->getNodeCacheEntry())) { + $this->adjustTarget($share, $superShare, $user); + if ($share->getNodeCacheEntry() !== null) { $superShare->setNodeCacheEntry($share->getNodeCacheEntry()); } } @@ -273,4 +241,82 @@ class MountProvider implements IMountProvider { return $result; } + + /** + * Combines $attributes into the most permissive set of attributes and + * sets them in $superAttributes. + */ + private function mergeAttributes( + IAttributes $attributes, + IAttributes $superAttributes, + ): void { + foreach ($attributes->toArray() as $attribute) { + if ($superAttributes->getAttribute( + $attribute['scope'], + $attribute['key'] + ) === true) { + // if super share attribute is already enabled, it is most permissive + continue; + } + // update super share attributes with subshare attribute + $superAttributes->setAttribute( + $attribute['scope'], + $attribute['key'], + $attribute['value'] + ); + } + } + + /** + * Gather notes from all the shares. Since these are readily available + * here, storing them enables the DAV FilesPlugin to avoid executing many + * DB queries to retrieve the same information. + * + * @param array $shares + * @param IShare $superShare + * @return void + */ + private function combineNotes( + array &$shares, + IShare $superShare, + ): void { + $allNotes = implode( + "\n", + array_map(static fn ($sh) => $sh->getNote(), $shares) + ); + $superShare->setNote($allNotes); + } + + /** + * Adjusts the target in $share for DB consistency, if needed. + */ + private function adjustTarget( + IShare $share, + IShare $superShare, + IUser $user, + ): void { + if ($share->getTarget() === $superShare->getTarget()) { + return; + } + + $share->setTarget($superShare->getTarget()); + try { + $this->shareManager->moveShare($share, $user->getUID()); + } catch (InvalidArgumentException $e) { + // ignore as it is not important and we don't want to + // block FS setup + + // the subsequent code anyway only uses the target of the + // super share + + // such issue can usually happen when dealing with + // null groups which usually appear with group backend + // caching inconsistencies + $this->logger->debug( + 'Could not adjust share target for share ' . $share->getId( + ) . ' to make it consistent: ' . $e->getMessage(), + ['app' => 'files_sharing'] + ); + } + } } From 2d74a755a8e02ae316377e4a4425136ddf925ebd Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:10:11 +0100 Subject: [PATCH 4/6] refactor(files_sharing): apply DRY in MountProvider Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/MountProvider.php | 8 +++----- build/psalm-baseline.xml | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 0a6c80769b2..53a15c527c1 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -79,10 +79,8 @@ class MountProvider implements IMountProvider { $newMaxValidatedShare = $maxValidatedShare; foreach ($superShares as $share) { + [$parentShare, $groupedShares] = $share; try { - /** @var IShare $parentShare */ - $parentShare = $share[0]; - if ($parentShare->getStatus() !== IShare::STATUS_ACCEPTED && ($parentShare->getShareType() === IShare::TYPE_GROUP || $parentShare->getShareType() === IShare::TYPE_USERGROUP @@ -92,7 +90,7 @@ class MountProvider implements IMountProvider { $owner = $parentShare->getShareOwner(); if (!isset($ownerViews[$owner])) { - $ownerViews[$owner] = new View('/' . $parentShare->getShareOwner() . '/files'); + $ownerViews[$owner] = new View('/' . $owner . '/files'); } $shareId = (int)$parentShare->getId(); $mount = new SharedMount( @@ -103,7 +101,7 @@ class MountProvider implements IMountProvider { // parent share 'superShare' => $parentShare, // children/component of the superShare - 'groupedShares' => $share[1], + 'groupedShares' => $groupedShares, 'ownerView' => $ownerViews[$owner], 'sharingDisabledForUser' => $sharingDisabledForUser ], diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index e7c7f278c0a..da97acda4e4 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -1685,11 +1685,11 @@ - getShareOwner() . '/files')]]> + - getShareOwner() . '/files')]]> + From 881453dbde42f8184676781af1b8e32723d9d5e1 Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Mon, 3 Nov 2025 15:06:28 +0100 Subject: [PATCH 5/6] refactor(files_sharing): extract getMountsForUser logic Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/MountProvider.php | 193 ++++++++++++++--------- 1 file changed, 115 insertions(+), 78 deletions(-) diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php index 53a15c527c1..a2ca0076124 100644 --- a/apps/files_sharing/lib/MountProvider.php +++ b/apps/files_sharing/lib/MountProvider.php @@ -7,6 +7,7 @@ */ namespace OCA\Files_Sharing; +use Exception; use InvalidArgumentException; use OC\Files\View; use OCA\Files_Sharing\Event\ShareMountedEvent; @@ -23,6 +24,7 @@ use OCP\Share\IAttributes; use OCP\Share\IManager; use OCP\Share\IShare; use Psr\Log\LoggerInterface; +use function count; class MountProvider implements IMountProvider { /** @@ -58,85 +60,10 @@ class MountProvider implements IMountProvider { $this->shareManager->getSharedWith($userId, IShare::TYPE_SCIENCEMESH, null, -1), ); - // filter out shares owned or shared by the user and ones for which - // the user has no permissions - $shares = array_filter($shares, function (IShare $share) use ($userId) { - return $share->getPermissions() > 0 && $share->getShareOwner() !== $userId && $share->getSharedBy() !== $userId; - }); - + $shares = $this->filterShares($shares, $userId); $superShares = $this->buildSuperShares($shares, $user); - $allMounts = $this->mountManager->getAll(); - $mounts = []; - $view = new View('/' . $userId . '/files'); - $ownerViews = []; - $sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($userId); - /** @var CappedMemoryCache $folderExistCache */ - $foldersExistCache = new CappedMemoryCache(); - - $validShareCache = $this->cacheFactory->createLocal('share-valid-mountpoint-max'); - $maxValidatedShare = $validShareCache->get($userId) ?? 0; - $newMaxValidatedShare = $maxValidatedShare; - - foreach ($superShares as $share) { - [$parentShare, $groupedShares] = $share; - try { - if ($parentShare->getStatus() !== IShare::STATUS_ACCEPTED - && ($parentShare->getShareType() === IShare::TYPE_GROUP - || $parentShare->getShareType() === IShare::TYPE_USERGROUP - || $parentShare->getShareType() === IShare::TYPE_USER)) { - continue; - } - - $owner = $parentShare->getShareOwner(); - if (!isset($ownerViews[$owner])) { - $ownerViews[$owner] = new View('/' . $owner . '/files'); - } - $shareId = (int)$parentShare->getId(); - $mount = new SharedMount( - '\OCA\Files_Sharing\SharedStorage', - $allMounts, - [ - 'user' => $userId, - // parent share - 'superShare' => $parentShare, - // children/component of the superShare - 'groupedShares' => $groupedShares, - 'ownerView' => $ownerViews[$owner], - 'sharingDisabledForUser' => $sharingDisabledForUser - ], - $loader, - $view, - $foldersExistCache, - $this->eventDispatcher, - $user, - ($shareId <= $maxValidatedShare), - ); - - $newMaxValidatedShare = max($shareId, $newMaxValidatedShare); - - $event = new ShareMountedEvent($mount); - $this->eventDispatcher->dispatchTyped($event); - - $mounts[$mount->getMountPoint()] = $allMounts[$mount->getMountPoint()] = $mount; - foreach ($event->getAdditionalMounts() as $additionalMount) { - $allMounts[$additionalMount->getMountPoint()] = $mounts[$additionalMount->getMountPoint()] = $additionalMount; - } - } catch (\Exception $e) { - $this->logger->error( - 'Error while trying to create shared mount', - [ - 'app' => 'files_sharing', - 'exception' => $e, - ], - ); - } - } - - $validShareCache->set($userId, $newMaxValidatedShare, 24 * 60 * 60); - - // array_filter removes the null values from the array - return array_values(array_filter($mounts)); + return $this->getMountsFromSuperShares($userId, $superShares, $loader, $user); } /** @@ -192,7 +119,7 @@ class MountProvider implements IMountProvider { $groupedShares = $this->groupShares($allShares); foreach ($groupedShares as $shares) { - if (\count($shares) === 0) { + if (count($shares) === 0) { continue; } @@ -317,4 +244,114 @@ class MountProvider implements IMountProvider { ); } } + /** + * @param string $userId + * @param array $superShares + * @param IStorageFactory $loader + * @param IUser $user + * @return array + * @throws Exception + */ + private function getMountsFromSuperShares( + string $userId, + array $superShares, + IStorageFactory $loader, + IUser $user, + ): array { + $allMounts = $this->mountManager->getAll(); + $mounts = []; + $view = new View('/' . $userId . '/files'); + $ownerViews = []; + $sharingDisabledForUser + = $this->shareManager->sharingDisabledForUser($userId); + /** @var CappedMemoryCache $folderExistCache */ + $foldersExistCache = new CappedMemoryCache(); + + $validShareCache + = $this->cacheFactory->createLocal('share-valid-mountpoint-max'); + $maxValidatedShare = $validShareCache->get($userId) ?? 0; + $newMaxValidatedShare = $maxValidatedShare; + + foreach ($superShares as $share) { + [$parentShare, $groupedShares] = $share; + try { + if ($parentShare->getStatus() !== IShare::STATUS_ACCEPTED + && ($parentShare->getShareType() === IShare::TYPE_GROUP + || $parentShare->getShareType() === IShare::TYPE_USERGROUP + || $parentShare->getShareType() === IShare::TYPE_USER) + ) { + continue; + } + + $owner = $parentShare->getShareOwner(); + if (!isset($ownerViews[$owner])) { + $ownerViews[$owner] = new View('/' . $owner . '/files'); + } + $shareId = (int)$parentShare->getId(); + $mount = new SharedMount( + '\OCA\Files_Sharing\SharedStorage', + $allMounts, + [ + 'user' => $userId, + // parent share + 'superShare' => $parentShare, + // children/component of the superShare + 'groupedShares' => $groupedShares, + 'ownerView' => $ownerViews[$owner], + 'sharingDisabledForUser' => $sharingDisabledForUser + ], + $loader, + $view, + $foldersExistCache, + $this->eventDispatcher, + $user, + $shareId <= $maxValidatedShare, + ); + + $newMaxValidatedShare = max($shareId, $newMaxValidatedShare); + + $event = new ShareMountedEvent($mount); + $this->eventDispatcher->dispatchTyped($event); + + $mounts[$mount->getMountPoint()] + = $allMounts[$mount->getMountPoint()] = $mount; + foreach ($event->getAdditionalMounts() as $additionalMount) { + $allMounts[$additionalMount->getMountPoint()] + = $mounts[$additionalMount->getMountPoint()] + = $additionalMount; + } + } catch (Exception $e) { + $this->logger->error( + 'Error while trying to create shared mount', + [ + 'app' => 'files_sharing', + 'exception' => $e, + ], + ); + } + } + + $validShareCache->set($userId, $newMaxValidatedShare, 24 * 60 * 60); + + // array_filter removes the null values from the array + return array_values(array_filter($mounts)); + } + + /** + * Filters out shares owned or shared by the user and ones for which the + * user has no permissions. + * + * @param IShare[] $shares + * @return IShare[] + */ + private function filterShares(array $shares, string $userId): array { + return array_filter( + $shares, + static function (IShare $share) use ($userId) { + return $share->getPermissions() > 0 + && $share->getShareOwner() !== $userId + && $share->getSharedBy() !== $userId; + } + ); + } } From cfba3f83703b8d0910a7ea44f7bd5869581756e8 Mon Sep 17 00:00:00 2001 From: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> Date: Mon, 3 Nov 2025 17:42:17 +0100 Subject: [PATCH 6/6] refactor(files_sharing): avoid magic numbers in external/MountProvider Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com> --- apps/files_sharing/lib/External/MountProvider.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/files_sharing/lib/External/MountProvider.php b/apps/files_sharing/lib/External/MountProvider.php index a1b8092d032..5a0021db6b7 100644 --- a/apps/files_sharing/lib/External/MountProvider.php +++ b/apps/files_sharing/lib/External/MountProvider.php @@ -15,6 +15,7 @@ use OCP\Http\Client\IClientService; use OCP\IDBConnection; use OCP\IUser; use OCP\Server; +use OCP\Share\IShare; class MountProvider implements IMountProvider { public const STORAGE = '\OCA\Files_Sharing\External\Storage'; @@ -54,7 +55,7 @@ class MountProvider implements IMountProvider { $qb->select('remote', 'share_token', 'password', 'mountpoint', 'owner') ->from('share_external') ->where($qb->expr()->eq('user', $qb->createNamedParameter($user->getUID()))) - ->andWhere($qb->expr()->eq('accepted', $qb->createNamedParameter(1, IQueryBuilder::PARAM_INT))); + ->andWhere($qb->expr()->eq('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED, IQueryBuilder::PARAM_INT))); $result = $qb->executeQuery(); $mounts = []; while ($row = $result->fetchAssociative()) {