diff --git a/apps/files_sharing/lib/Command/DeleteOrphanShares.php b/apps/files_sharing/lib/Command/DeleteOrphanShares.php index e15581b4113cf..71c0c137754d8 100644 --- a/apps/files_sharing/lib/Command/DeleteOrphanShares.php +++ b/apps/files_sharing/lib/Command/DeleteOrphanShares.php @@ -52,7 +52,11 @@ public function execute(InputInterface $input, OutputInterface $output): int { $exists = $this->orphanHelper->fileExists($share['fileid']); $output->writeln("{$share['target']} owned by {$share['owner']}"); if ($exists) { - $output->writeln(" file still exists but the share owner lost access to it, run occ info:file {$share['fileid']} for more information about the file"); + if ($this->orphanHelper->isInTrashbin($share['fileid'])) { + $output->writeln(" file is in the trashbin of the share owner, run occ info:file {$share['fileid']} for more information about the file"); + } else { + $output->writeln(" file still exists but the share owner lost access to it, run occ info:file {$share['fileid']} for more information about the file"); + } } else { $output->writeln(' file no longer exists'); } diff --git a/apps/files_sharing/lib/OrphanHelper.php b/apps/files_sharing/lib/OrphanHelper.php index ed3a355263544..4b81434aa2866 100644 --- a/apps/files_sharing/lib/OrphanHelper.php +++ b/apps/files_sharing/lib/OrphanHelper.php @@ -56,6 +56,15 @@ public function fileExists(int $fileId): bool { return $query->executeQuery()->fetchOne() !== false; } + public function isInTrashbin(int $fileId): bool { + $query = $this->connection->getQueryBuilder(); + $query->select('path') + ->from('filecache') + ->where($query->expr()->eq('fileid', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))); + $path = $query->executeQuery()->fetchOne(); + return $path !== false && str_starts_with($path, 'files_trashbin/'); + } + /** * @return \Traversable */ diff --git a/core/Command/Info/FileUtils.php b/core/Command/Info/FileUtils.php index e106fc7a77aa2..811813483095a 100644 --- a/core/Command/Info/FileUtils.php +++ b/core/Command/Info/FileUtils.php @@ -73,13 +73,23 @@ public function getFilesByUser(FileInfo $file): array { */ public function getNode(string $fileInput): ?Node { if (is_numeric($fileInput)) { - $mounts = $this->userMountCache->getMountsForFileId((int)$fileInput); - if (!$mounts) { - return null; + $id = (int)$fileInput; + $mounts = $this->userMountCache->getMountsForFileId($id); + if ($mounts) { + $mount = reset($mounts); + $userFolder = $this->rootFolder->getUserFolder($mount->getUser()->getUID()); + $node = $userFolder->getFirstNodeById($id); + if ($node) { + return $node; + } + // the file might live outside of the user files folder, e.g. in the trashbin or versions + $node = $userFolder->getParent()->getFirstNodeById($id); + if ($node) { + return $node; + } } - $mount = reset($mounts); - $userFolder = $this->rootFolder->getUserFolder($mount->getUser()->getUID()); - return $userFolder->getFirstNodeById((int)$fileInput); + // the file might not belong to a user at all, e.g. appdata on the root storage + return $this->getNodeFromRootMount($id); } else { try { return $this->rootFolder->get($fileInput); @@ -89,6 +99,23 @@ public function getNode(string $fileInput): ?Node { } } + /** + * Resolve a file id directly on the root storage, covering files that are + * not part of any user mount such as appdata. + */ + private function getNodeFromRootMount(int $id): ?Node { + $mount = $this->rootFolder->getMount(''); + $storage = $mount->getStorage(); + if ($storage === null) { + return null; + } + $cacheEntry = $storage->getCache()->get($id); + if ($cacheEntry === false) { + return null; + } + return $this->rootFolder->getNodeFromCacheEntryAndMount($cacheEntry, $mount); + } + public function formatPermissions(string $type, int $permissions): string { if ($permissions == Constants::PERMISSION_ALL || ($type === 'file' && $permissions == (Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE))) { return 'full permissions';