aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files_trashbin/lib/Helper.php24
-rw-r--r--apps/files_trashbin/lib/Sabre/AbstractTrashFolder.php7
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashFolder.php6
-rw-r--r--apps/files_trashbin/lib/Trash/LegacyTrashBackend.php4
-rw-r--r--apps/files_trashbin/lib/Trash/TrashItem.php2
-rw-r--r--apps/files_trashbin/lib/Trashbin.php16
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);