This commit is contained in:
Carl Schwan 2026-06-13 13:10:55 +08:00 committed by GitHub
commit 58fa39de6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 48 additions and 11 deletions

View file

@ -46,17 +46,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) === '/') {
@ -74,6 +87,7 @@ class Helper {
'etag' => '',
'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
'fileid' => $entry->getId(),
'is_trash_root' => !$hasFileTrashEntry,
];
if ($originalPath) {
if ($originalPath !== '.') {

View file

@ -21,6 +21,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);
}

View file

@ -14,6 +14,10 @@ use OCA\Files_Trashbin\Trashbin;
class TrashFolder extends AbstractTrashFolder {
#[\Override]
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());
}
}
}

View file

@ -46,12 +46,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,

View file

@ -46,7 +46,7 @@ class TrashItem implements ITrashItem {
#[\Override]
public function isRootItem(): bool {
return substr_count($this->getTrashPath(), '/') === 1;
return substr_count($this->getTrashPath(), '/') === 1 || str_ends_with($this->trashPath, strval($this->deletedTime));
}
#[\Override]

View file

@ -269,9 +269,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);
@ -284,7 +296,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);