diff options
-rw-r--r-- | apps/files_trashbin/lib/Helper.php | 24 | ||||
-rw-r--r-- | apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php | 7 | ||||
-rw-r--r-- | apps/files_trashbin/lib/Sabre/TrashFolder.php | 6 | ||||
-rw-r--r-- | apps/files_trashbin/lib/Trash/LegacyTrashBackend.php | 4 | ||||
-rw-r--r-- | apps/files_trashbin/lib/Trash/TrashItem.php | 2 | ||||
-rw-r--r-- | apps/files_trashbin/lib/Trashbin.php | 16 |
6 files changed, 48 insertions, 11 deletions
diff --git a/apps/files_trashbin/lib/Helper.php b/apps/files_trashbin/lib/Helper.php index 746832e9280..a01786bf304 100644 --- a/apps/files_trashbin/lib/Helper.php +++ b/apps/files_trashbin/lib/Helper.php @@ -45,17 +45,30 @@ class Helper { foreach ($dirContent as $entry) { $entryName = $entry->getName(); $name = $entryName; + if ($dir === '' || $dir === '/') { - $pathparts = pathinfo($entryName); - $timestamp = substr($pathparts['extension'], 1); - $name = $pathparts['filename']; + $pathParts = pathinfo($entryName); + $timestamp = substr($pathParts['extension'], 1); + $name = $pathParts['filename']; } elseif ($timestamp === null) { // for subfolders we need to calculate the timestamp only once $parts = explode('/', ltrim($dir, '/')); - $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); + $timestamp = ''; + for ($i = 0, $count = count($parts); $i < $count && $timestamp === ''; $i++) { + $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); + } + + if ($timestamp === '') { + $pathParts = pathinfo($entryName); + $timestamp = substr($pathParts['extension'], 1); + $name = $pathParts['filename']; + } } + + $originalPath = ''; - $originalName = substr($entryName, 0, -strlen($timestamp) - 2); + $originalName = $timestamp === '' ? $entryName : substr($entryName, 0, -strlen($timestamp) - 2); + $hasFileTrashEntry = array_key_exists($originalName, $extraData); if (isset($extraData[$originalName][$timestamp]['location'])) { $originalPath = $extraData[$originalName][$timestamp]['location']; if (substr($originalPath, -1) === '/') { @@ -73,6 +86,7 @@ class Helper { 'etag' => '', 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE, 'fileid' => $entry->getId(), + 'is_trash_root' => !$hasFileTrashEntry, ]; if ($originalPath) { if ($originalPath !== '.') { diff --git a/apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php b/apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php index 9e8f67f4db6..36054ce952d 100644 --- a/apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php +++ b/apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php @@ -19,6 +19,13 @@ abstract class AbstractTrashFolder extends AbstractTrash implements ICollection, $entries = $this->trashManager->listTrashFolder($this->data); $children = array_map(function (ITrashItem $entry) { + if (str_starts_with($entry->getTrashPath(), '/' . $entry->getOriginalLocation())) { + // parent folder is a fake trash folder + if ($entry->getType() === FileInfo::TYPE_FOLDER) { + return new TrashFolder($this->trashManager, $entry); + } + return new TrashFile($this->trashManager, $entry); + } if ($entry->getType() === FileInfo::TYPE_FOLDER) { return new TrashFolderFolder($this->trashManager, $entry); } diff --git a/apps/files_trashbin/lib/Sabre/TrashFolder.php b/apps/files_trashbin/lib/Sabre/TrashFolder.php index e1c495bf08e..000ee3fca87 100644 --- a/apps/files_trashbin/lib/Sabre/TrashFolder.php +++ b/apps/files_trashbin/lib/Sabre/TrashFolder.php @@ -12,6 +12,10 @@ use OCA\Files_Trashbin\Trashbin; class TrashFolder extends AbstractTrashFolder { public function getName(): string { - return Trashbin::getTrashFilename($this->data->getName(), $this->getDeletionTime()); + if ($this->getDeletionTime() === 0) { + return $this->data->getName(); + } else { + return Trashbin::getTrashFilename($this->data->getName(), $this->getDeletionTime()); + } } } diff --git a/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php b/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php index 204defde35c..cb77e7e5c50 100644 --- a/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php +++ b/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php @@ -45,12 +45,12 @@ class LegacyTrashBackend implements ITrashBackend { } /** @psalm-suppress UndefinedInterfaceMethod */ $deletedBy = $this->userManager->get($file['deletedBy']) ?? $parent?->getDeletedBy(); - $trashFilename = Trashbin::getTrashFilename($file->getName(), $file->getMtime()); + $trashFilename = $file->getMtime() === 0 ? $file->getName() : Trashbin::getTrashFilename($file->getName(), $file->getMtime()); return new TrashItem( $this, $originalLocation, $file->getMTime(), - $parentTrashPath . '/' . ($isRoot ? $trashFilename : $file->getName()), + $parentTrashPath . '/' . $trashFilename, $file, $user, $deletedBy, diff --git a/apps/files_trashbin/lib/Trash/TrashItem.php b/apps/files_trashbin/lib/Trash/TrashItem.php index 2ae999a2069..98d205e9330 100644 --- a/apps/files_trashbin/lib/Trash/TrashItem.php +++ b/apps/files_trashbin/lib/Trash/TrashItem.php @@ -39,7 +39,7 @@ class TrashItem implements ITrashItem { } public function isRootItem(): bool { - return substr_count($this->getTrashPath(), '/') === 1; + return substr_count($this->getTrashPath(), '/') === 1 || str_ends_with($this->trashPath, strval($this->deletedTime)); } public function getUser(): IUser { diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index 667066c2fca..b7d91d6227d 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -264,9 +264,21 @@ class Trashbin implements IEventListener { $lockingProvider = Server::get(ILockingProvider::class); // disable proxy to prevent recursive calls - $trashPath = '/files_trashbin/files/' . static::getTrashFilename($filename, $timestamp); + $trashPath = '/files_trashbin/files/' . $location . '/' . static::getTrashFilename($filename, $timestamp); $gotLock = false; + // Reproduce folder hierarchy of deleted file in trash + $parentDirs = explode('/', $location); + $pathPrefix = '/files_trashbin/files/'; + foreach ($parentDirs as $parentDir) { + $pathPrefix .= $parentDir . '/'; + if ($ownerView->is_dir($pathPrefix)) { + continue; + } + + $ownerView->mkdir($pathPrefix); + } + do { /** @var ILockingStorage & IStorage $trashStorage */ [$trashStorage, $trashInternalPath] = $ownerView->resolvePath($trashPath); @@ -279,7 +291,7 @@ class Trashbin implements IEventListener { $timestamp = $timestamp + 1; - $trashPath = '/files_trashbin/files/' . static::getTrashFilename($filename, $timestamp); + $trashPath = '/files_trashbin/files/' . $location . static::getTrashFilename($filename, $timestamp); } } while (!$gotLock); |