aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/admin_audit/lib/Actions/Trashbin.php11
-rw-r--r--apps/admin_audit/lib/AppInfo/Application.php22
-rw-r--r--apps/files_trashbin/composer/composer/autoload_classmap.php4
-rw-r--r--apps/files_trashbin/composer/composer/autoload_static.php4
-rw-r--r--apps/files_trashbin/lib/Events/BeforeDeleteAllEvent.php31
-rw-r--r--apps/files_trashbin/lib/Events/BeforeNodeDeletedEvent.php25
-rw-r--r--apps/files_trashbin/lib/Events/DeleteAllEvent.php31
-rw-r--r--apps/files_trashbin/lib/Events/NodeDeletedEvent.php25
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashRoot.php3
-rw-r--r--apps/files_trashbin/lib/Trashbin.php188
-rw-r--r--build/psalm-baseline.xml3
-rw-r--r--lib/public/Files/Cache/CacheEntriesRemovedEvent.php31
12 files changed, 257 insertions, 121 deletions
diff --git a/apps/admin_audit/lib/Actions/Trashbin.php b/apps/admin_audit/lib/Actions/Trashbin.php
index c1e994da3a5..0a73b1d5235 100644
--- a/apps/admin_audit/lib/Actions/Trashbin.php
+++ b/apps/admin_audit/lib/Actions/Trashbin.php
@@ -7,16 +7,19 @@ declare(strict_types=1);
*/
namespace OCA\AdminAudit\Actions;
+use OCA\Files_Trashbin\Events\BeforeNodeDeletedEvent;
+use OCA\Files_Trashbin\Events\NodeRestoredEvent;
+
class Trashbin extends Action {
- public function delete(array $params): void {
+ public function delete(BeforeNodeDeletedEvent $beforeNodeDeletedEvent): void {
$this->log('File "%s" deleted from trash bin.',
- ['path' => $params['path']], ['path']
+ ['path' => $beforeNodeDeletedEvent->getSource()->getPath()], ['path']
);
}
- public function restore(array $params): void {
+ public function restore(NodeRestoredEvent $nodeRestoredEvent): void {
$this->log('File "%s" restored from trash bin.',
- ['path' => $params['filePath']], ['path']
+ ['path' => $nodeRestoredEvent->getTarget()], ['path']
);
}
}
diff --git a/apps/admin_audit/lib/AppInfo/Application.php b/apps/admin_audit/lib/AppInfo/Application.php
index 63a1d065bc8..1371debf03f 100644
--- a/apps/admin_audit/lib/AppInfo/Application.php
+++ b/apps/admin_audit/lib/AppInfo/Application.php
@@ -27,6 +27,8 @@ use OCA\AdminAudit\Listener\GroupManagementEventListener;
use OCA\AdminAudit\Listener\SecurityEventListener;
use OCA\AdminAudit\Listener\SharingEventListener;
use OCA\AdminAudit\Listener\UserManagementEventListener;
+use OCA\Files_Trashbin\Events\NodeRestoredEvent;
+use OCA\Files_Trashbin\Events\BeforeNodeDeletedEvent as TrashbinBeforeNodeDeletedEvent;
use OCA\Files_Versions\Events\VersionRestoredEvent;
use OCP\App\Events\AppDisableEvent;
use OCP\App\Events\AppEnableEvent;
@@ -44,6 +46,7 @@ use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeReadEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Events\Node\NodeCreatedEvent;
+use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeRenamedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\Group\Events\GroupCreatedEvent;
@@ -144,7 +147,7 @@ class Application extends App implements IBootstrap {
$eventDispatcher = $serverContainer->get(IEventDispatcher::class);
$this->sharingLegacyHooks($logger);
$this->fileHooks($logger, $eventDispatcher);
- $this->trashbinHooks($logger);
+ $this->trashbinHooks($logger, $eventDispatcher);
$this->versionsHooks($logger);
$this->tagHooks($logger, $eventDispatcher);
}
@@ -217,9 +220,20 @@ class Application extends App implements IBootstrap {
Util::connectHook('\OCP\Versions', 'delete', $versionsActions, 'delete');
}
- private function trashbinHooks(IAuditLogger $logger): void {
+ private function trashbinHooks(IAuditLogger $logger, IEventDispatcher $eventDispatcher): void {
$trashActions = new Trashbin($logger);
- Util::connectHook('\OCP\Trashbin', 'preDelete', $trashActions, 'delete');
- Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', $trashActions, 'restore');
+
+ $eventDispatcher->addListener(TrashbinBeforeNodeDeletedEvent::class,
+ function (TrashbinBeforeNodeDeletedEvent $event) use ($trashActions): void {
+ $trashActions->delete($event);
+ }
+ );
+
+ $eventDispatcher->addListener(
+ NodeRestoredEvent::class,
+ function (NodeRestoredEvent $event) use ($trashActions): void {
+ $trashActions->restore($event);
+ }
+ );
}
}
diff --git a/apps/files_trashbin/composer/composer/autoload_classmap.php b/apps/files_trashbin/composer/composer/autoload_classmap.php
index 23e2e7baff6..be2ec71eaf2 100644
--- a/apps/files_trashbin/composer/composer/autoload_classmap.php
+++ b/apps/files_trashbin/composer/composer/autoload_classmap.php
@@ -16,8 +16,12 @@ return array(
'OCA\\Files_Trashbin\\Command\\RestoreAllFiles' => $baseDir . '/../lib/Command/RestoreAllFiles.php',
'OCA\\Files_Trashbin\\Command\\Size' => $baseDir . '/../lib/Command/Size.php',
'OCA\\Files_Trashbin\\Controller\\PreviewController' => $baseDir . '/../lib/Controller/PreviewController.php',
+ 'OCA\\Files_Trashbin\\Events\\BeforeDeleteAllEvent' => $baseDir . '/../lib/Events/BeforeDeleteAllEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\BeforeNodeDeletedEvent' => $baseDir . '/../lib/Events/BeforeNodeDeletedEvent.php',
'OCA\\Files_Trashbin\\Events\\BeforeNodeRestoredEvent' => $baseDir . '/../lib/Events/BeforeNodeRestoredEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\DeleteAllEvent' => $baseDir . '/../lib/Events/DeleteAllEvent.php',
'OCA\\Files_Trashbin\\Events\\MoveToTrashEvent' => $baseDir . '/../lib/Events/MoveToTrashEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\NodeDeletedEvent' => $baseDir . '/../lib/Events/NodeDeletedEvent.php',
'OCA\\Files_Trashbin\\Events\\NodeRestoredEvent' => $baseDir . '/../lib/Events/NodeRestoredEvent.php',
'OCA\\Files_Trashbin\\Exceptions\\CopyRecursiveException' => $baseDir . '/../lib/Exceptions/CopyRecursiveException.php',
'OCA\\Files_Trashbin\\Expiration' => $baseDir . '/../lib/Expiration.php',
diff --git a/apps/files_trashbin/composer/composer/autoload_static.php b/apps/files_trashbin/composer/composer/autoload_static.php
index fc604299261..0606643c4fe 100644
--- a/apps/files_trashbin/composer/composer/autoload_static.php
+++ b/apps/files_trashbin/composer/composer/autoload_static.php
@@ -31,8 +31,12 @@ class ComposerStaticInitFiles_Trashbin
'OCA\\Files_Trashbin\\Command\\RestoreAllFiles' => __DIR__ . '/..' . '/../lib/Command/RestoreAllFiles.php',
'OCA\\Files_Trashbin\\Command\\Size' => __DIR__ . '/..' . '/../lib/Command/Size.php',
'OCA\\Files_Trashbin\\Controller\\PreviewController' => __DIR__ . '/..' . '/../lib/Controller/PreviewController.php',
+ 'OCA\\Files_Trashbin\\Events\\BeforeDeleteAllEvent' => __DIR__ . '/..' . '/../lib/Events/BeforeDeleteAllEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\BeforeNodeDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/BeforeNodeDeletedEvent.php',
'OCA\\Files_Trashbin\\Events\\BeforeNodeRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/BeforeNodeRestoredEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\DeleteAllEvent' => __DIR__ . '/..' . '/../lib/Events/DeleteAllEvent.php',
'OCA\\Files_Trashbin\\Events\\MoveToTrashEvent' => __DIR__ . '/..' . '/../lib/Events/MoveToTrashEvent.php',
+ 'OCA\\Files_Trashbin\\Events\\NodeDeletedEvent' => __DIR__ . '/..' . '/../lib/Events/NodeDeletedEvent.php',
'OCA\\Files_Trashbin\\Events\\NodeRestoredEvent' => __DIR__ . '/..' . '/../lib/Events/NodeRestoredEvent.php',
'OCA\\Files_Trashbin\\Exceptions\\CopyRecursiveException' => __DIR__ . '/..' . '/../lib/Exceptions/CopyRecursiveException.php',
'OCA\\Files_Trashbin\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
diff --git a/apps/files_trashbin/lib/Events/BeforeDeleteAllEvent.php b/apps/files_trashbin/lib/Events/BeforeDeleteAllEvent.php
new file mode 100644
index 00000000000..1cd519b8255
--- /dev/null
+++ b/apps/files_trashbin/lib/Events/BeforeDeleteAllEvent.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Files_Trashbin\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Node;
+
+/**
+ * Event send before emptying the trash.
+ * @since 32.0.0
+ */
+class BeforeDeleteAllEvent extends Event {
+
+ /**
+ * @param Node[] $deletedNodes
+ */
+ public function __construct(private readonly array $deletedNodes) {
+ }
+
+ /** @return Node[] */
+ public function getDeletedNodes(): array {
+ return $this->deletedNodes;
+ }
+}
diff --git a/apps/files_trashbin/lib/Events/BeforeNodeDeletedEvent.php b/apps/files_trashbin/lib/Events/BeforeNodeDeletedEvent.php
new file mode 100644
index 00000000000..7f1249a5a0c
--- /dev/null
+++ b/apps/files_trashbin/lib/Events/BeforeNodeDeletedEvent.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Trashbin\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Node;
+
+/**
+ * Event send before a node is deleted definitively.
+ * @since 32.0.0
+ */
+class BeforeNodeDeletedEvent extends Event {
+ public function __construct(private readonly Node $source) {
+ }
+
+ public function getSource(): Node {
+ return $this->source;
+ }
+}
diff --git a/apps/files_trashbin/lib/Events/DeleteAllEvent.php b/apps/files_trashbin/lib/Events/DeleteAllEvent.php
new file mode 100644
index 00000000000..5c19b1575be
--- /dev/null
+++ b/apps/files_trashbin/lib/Events/DeleteAllEvent.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Files_Trashbin\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Node;
+
+/**
+ * Event send before emptying the trash.
+ * @since 32.0.0
+ */
+class DeleteAllEvent extends Event {
+
+ /**
+ * @param Node[] $deletedNodes
+ */
+ public function __construct(private readonly array $deletedNodes) {
+ }
+
+ /** @return Node[] */
+ public function getDeletedNodes(): array {
+ return $this->deletedNodes;
+ }
+}
diff --git a/apps/files_trashbin/lib/Events/NodeDeletedEvent.php b/apps/files_trashbin/lib/Events/NodeDeletedEvent.php
new file mode 100644
index 00000000000..f493c10c7f1
--- /dev/null
+++ b/apps/files_trashbin/lib/Events/NodeDeletedEvent.php
@@ -0,0 +1,25 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Trashbin\Events;
+
+use OCP\EventDispatcher\Event;
+use OCP\Files\Node;
+
+/**
+ * Event send before a node is deleted definitively.
+ * @since 32.0.0
+ */
+class NodeDeletedEvent extends Event {
+ public function __construct(private Node $source) {
+ }
+
+ public function getSource(): Node {
+ return $this->source;
+ }
+}
diff --git a/apps/files_trashbin/lib/Sabre/TrashRoot.php b/apps/files_trashbin/lib/Sabre/TrashRoot.php
index dd89583d9a1..7e806cd7ca1 100644
--- a/apps/files_trashbin/lib/Sabre/TrashRoot.php
+++ b/apps/files_trashbin/lib/Sabre/TrashRoot.php
@@ -19,7 +19,6 @@ use Sabre\DAV\Exception\NotFound;
use Sabre\DAV\ICollection;
class TrashRoot implements ICollection {
-
public function __construct(
private IUser $user,
private ITrashManager $trashManager,
@@ -31,7 +30,7 @@ class TrashRoot implements ICollection {
throw new Forbidden('Not allowed to delete items from the trash bin');
}
- Trashbin::deleteAll();
+ Trashbin::deleteAll($this->user);
foreach ($this->trashManager->listTrashRoot($this->user) as $trashItem) {
$this->trashManager->removeItem($trashItem);
}
diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php
index 667066c2fca..7142ab07b9d 100644
--- a/apps/files_trashbin/lib/Trashbin.php
+++ b/apps/files_trashbin/lib/Trashbin.php
@@ -19,7 +19,9 @@ use OC\User\NoUserException;
use OC_User;
use OCA\Files_Trashbin\AppInfo\Application;
use OCA\Files_Trashbin\Command\Expire;
+use OCA\Files_Trashbin\Events\BeforeDeleteAllEvent;
use OCA\Files_Trashbin\Events\BeforeNodeRestoredEvent;
+use OCA\Files_Trashbin\Events\DeleteAllEvent;
use OCA\Files_Trashbin\Events\NodeRestoredEvent;
use OCA\Files_Trashbin\Exceptions\CopyRecursiveException;
use OCA\Files_Versions\Storage;
@@ -43,6 +45,7 @@ use OCP\FilesMetadata\IFilesMetadataManager;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IURLGenerator;
+use OCP\IUser;
use OCP\IUserManager;
use OCP\Lock\ILockingProvider;
use OCP\Lock\LockedException;
@@ -514,7 +517,6 @@ class Trashbin implements IEventListener {
$view->chroot('/' . $user . '/files');
$view->touch('/' . $location . '/' . $uniqueFilename, $mtime);
$view->chroot($fakeRoot);
- Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', ['filePath' => $targetPath, 'trashPath' => $sourcePath]);
$sourceNode = self::getNodeForPath($sourcePath);
$targetNode = self::getNodeForPath($targetPath);
@@ -587,49 +589,54 @@ class Trashbin implements IEventListener {
/**
* delete all files from the trash
*/
- public static function deleteAll() {
- $user = OC_User::getUser();
- $userRoot = \OC::$server->getUserFolder($user)->getParent();
- $view = new View('/' . $user);
- $fileInfos = $view->getDirectoryContent('files_trashbin/files');
+ public static function deleteAll(IUser $user) {
+ $rootFolder = Server::get(IRootFolder::class);
+ $dispatcher = Server::get(IEventDispatcher::class);
+ $dbConnection = Server::get(IDBConnection::class);
+
+ $userRoot = $rootFolder->getUserFolder($user->getUID())->getParent();
try {
- $trash = $userRoot->get('files_trashbin');
- } catch (NotFoundException $e) {
+ /** @var Folder $trashRoot */
+ $trashRoot = $userRoot->get('files_trashbin');
+ /** @var Folder $trashFilesRoot */
+ $trashFilesRoot = $trashRoot->get('files');
+ } catch (NotFoundException) {
+ return false;
+ } catch (NotPermittedException) {
return false;
}
- // Array to store the relative path in (after the file is deleted, the view won't be able to relativise the path anymore)
- $filePaths = [];
- foreach ($fileInfos as $fileInfo) {
- $filePaths[] = $view->getRelativePath($fileInfo->getPath());
- }
- unset($fileInfos); // save memory
-
- // Bulk PreDelete-Hook
- \OC_Hook::emit('\OCP\Trashbin', 'preDeleteAll', ['paths' => $filePaths]);
+ $trashNodes = $trashFilesRoot->getDirectoryListing();
+ $beforeDeleteAllEvent = new BeforeDeleteAllEvent($trashNodes);
+ $dispatcher->dispatchTyped($beforeDeleteAllEvent);
// Single-File Hooks
- foreach ($filePaths as $path) {
- self::emitTrashbinPreDelete($path);
+ foreach ($trashNodes as $trashNode) {
+ $event = new Events\BeforeNodeDeletedEvent($trashNode);
+ $dispatcher->dispatchTyped($event);
}
// actual file deletion
- $trash->delete();
+ $trashRoot->delete();
- $query = Server::get(IDBConnection::class)->getQueryBuilder();
+ $query = $dbConnection->getQueryBuilder();
$query->delete('files_trash')
- ->where($query->expr()->eq('user', $query->createNamedParameter($user)));
+ ->where($query->expr()->eq('user', $query->createNamedParameter($user->getUID())));
$query->executeStatement();
// Bulk PostDelete-Hook
- \OC_Hook::emit('\OCP\Trashbin', 'deleteAll', ['paths' => $filePaths]);
+ $deleteAllEvent = new DeleteAllEvent($trashNodes);
+ $dispatcher->dispatchTyped($deleteAllEvent);
// Single-File Hooks
- foreach ($filePaths as $path) {
- self::emitTrashbinPostDelete($path);
+ foreach ($trashNodes as $trashNode) {
+ $event = new Events\NodeDeletedEvent($trashNode);
+ $dispatcher->dispatchTyped($event);
}
+ unset($trashNodes); // save memory
+
$trash = $userRoot->newFolder('files_trashbin');
$trash->newFolder('files');
@@ -637,39 +644,31 @@ class Trashbin implements IEventListener {
}
/**
- * wrapper function to emit the 'preDelete' hook of \OCP\Trashbin before a file is deleted
- *
- * @param string $path
- */
- protected static function emitTrashbinPreDelete($path) {
- \OC_Hook::emit('\OCP\Trashbin', 'preDelete', ['path' => $path]);
- }
-
- /**
- * wrapper function to emit the 'delete' hook of \OCP\Trashbin after a file has been deleted
- *
- * @param string $path
- */
- protected static function emitTrashbinPostDelete($path) {
- \OC_Hook::emit('\OCP\Trashbin', 'delete', ['path' => $path]);
- }
-
- /**
- * delete file from trash bin permanently
+ * Delete file from trash bin permanently
*
* @param string $filename path to the file
- * @param string $user
- * @param int $timestamp of deletion time
- *
+ * @param ?int $timestamp of deletion time
* @return int|float size of deleted files
*/
- public static function delete($filename, $user, $timestamp = null) {
- $userRoot = \OC::$server->getUserFolder($user)->getParent();
- $view = new View('/' . $user);
+ public static function delete(string $filename, string $user, ?int $timestamp = null): int|float {
+ $rootFolder = Server::get(IRootFolder::class);
+ $appManager = Server::get(IAppManager::class);
+ $dispatcher = Server::get(IEventDispatcher::class);
+ $dbConnection = Server::get(IDBConnection::class);
+
+ $userRoot = $rootFolder->getUserFolder($user)->getParent();
+
+ try {
+ /** @var Folder $trashRoot */
+ $trashRoot = $userRoot->get('files_trashbin');
+ } catch (NotFoundException|NotPermittedException) {
+ return 0;
+ }
+
$size = 0;
if ($timestamp) {
- $query = Server::get(IDBConnection::class)->getQueryBuilder();
+ $query = $dbConnection->getQueryBuilder();
$query->delete('files_trash')
->where($query->expr()->eq('user', $query->createNamedParameter($user)))
->andWhere($query->expr()->eq('id', $query->createNamedParameter($filename)))
@@ -681,48 +680,52 @@ class Trashbin implements IEventListener {
$file = $filename;
}
- $size += self::deleteVersions($view, $file, $filename, $timestamp, $user);
+ if ($appManager->isEnabledForUser('files_versions')) {
+ Trashbin::deleteVersions($trashRoot, $file, $filename, $timestamp, $user);
+ }
try {
$node = $userRoot->get('/files_trashbin/files/' . $file);
- } catch (NotFoundException $e) {
+ } catch (NotFoundException) {
return $size;
}
- if ($node instanceof Folder) {
- $size += self::calculateSize(new View('/' . $user . '/files_trashbin/files/' . $file));
- } elseif ($node instanceof File) {
- $size += $view->filesize('/files_trashbin/files/' . $file);
- }
+ $size += $node->getSize();
+
+ $event = new Events\BeforeNodeDeletedEvent($node);
+ $dispatcher->dispatchTyped($event);
- self::emitTrashbinPreDelete('/files_trashbin/files/' . $file);
$node->delete();
- self::emitTrashbinPostDelete('/files_trashbin/files/' . $file);
+
+ $event = new Events\NodeDeletedEvent($node);
+ $dispatcher->dispatchTyped($event);
return $size;
}
/**
- * @param string $file
- * @param string $filename
- * @param ?int $timestamp
+ * Delete version files corresponding to a given file from trash bin permanently.
*/
- private static function deleteVersions(View $view, $file, $filename, $timestamp, string $user): int|float {
+ private static function deleteVersions(Folder $trashRoot, string $file, string $filename, ?int $timestamp, string $user): int|float {
$size = 0;
- if (Server::get(IAppManager::class)->isEnabledForUser('files_versions')) {
- if ($view->is_dir('files_trashbin/versions/' . $file)) {
- $size += self::calculateSize(new View('/' . $user . '/files_trashbin/versions/' . $file));
- $view->unlink('files_trashbin/versions/' . $file);
- } elseif ($versions = self::getVersionsFromTrash($filename, $timestamp, $user)) {
- foreach ($versions as $v) {
- if ($timestamp) {
- $size += $view->filesize('/files_trashbin/versions/' . static::getTrashFilename($filename . '.v' . $v, $timestamp));
- $view->unlink('/files_trashbin/versions/' . static::getTrashFilename($filename . '.v' . $v, $timestamp));
- } else {
- $size += $view->filesize('/files_trashbin/versions/' . $filename . '.v' . $v);
- $view->unlink('/files_trashbin/versions/' . $filename . '.v' . $v);
- }
+ try {
+ $fileVersion = $trashRoot->get('versions/' . $file);
+ } catch (NotFoundException) {
+ }
+
+ if ($fileVersion) {
+ $size += $fileVersion->getSize();
+ $fileVersion->delete();
+ } elseif ($versions = self::getVersionsFromTrash($filename, $timestamp, $user)) {
+ foreach ($versions as $v) {
+ if ($timestamp) {
+ $node = $trashRoot->get('/files_trashbin/versions/' . static::getTrashFilename($filename . '.v' . $v, $timestamp));
+ } else {
+ $node = $trashRoot->get('/files_trashbin/versions/' . $filename . '.v' . $v);
}
+
+ $size += $node->getSize();
+ $node->delete();
}
}
return $size;
@@ -1076,37 +1079,6 @@ class Trashbin implements IEventListener {
}
/**
- * get the size from a given root folder
- *
- * @param View $view file view on the root folder
- * @return int|float size of the folder
- */
- private static function calculateSize(View $view): int|float {
- $root = Server::get(IConfig::class)->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . $view->getAbsolutePath('');
- if (!file_exists($root)) {
- return 0;
- }
- $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($root), \RecursiveIteratorIterator::CHILD_FIRST);
- $size = 0;
-
- /**
- * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach
- * This bug is fixed in PHP 5.5.9 or before
- * See #8376
- */
- $iterator->rewind();
- while ($iterator->valid()) {
- $path = $iterator->current();
- $relpath = substr($path, strlen($root) - 1);
- if (!$view->is_dir($relpath)) {
- $size += $view->filesize($relpath);
- }
- $iterator->next();
- }
- return $size;
- }
-
- /**
* get current size of trash bin from a given user
*
* @param string $user user who owns the trash bin
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index 73dfeab49e4..5bf36ae6485 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -11,8 +11,6 @@
<code><![CDATA[ManagerEvent::EVENT_CREATE]]></code>
</DeprecatedConstant>
<DeprecatedMethod>
- <code><![CDATA[Util::connectHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', $trashActions, 'restore')]]></code>
- <code><![CDATA[Util::connectHook('\OCP\Trashbin', 'preDelete', $trashActions, 'delete')]]></code>
<code><![CDATA[Util::connectHook('\OCP\Versions', 'delete', $versionsActions, 'delete')]]></code>
<code><![CDATA[Util::connectHook(Share::class, 'post_set_expiration_date', $shareActions, 'updateExpirationDate')]]></code>
<code><![CDATA[Util::connectHook(Share::class, 'post_update_password', $shareActions, 'updatePassword')]]></code>
@@ -1857,7 +1855,6 @@
<DeprecatedMethod>
<code><![CDATA[Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', ['filePath' => Filesystem::normalizePath($file_path),
'trashPath' => Filesystem::normalizePath(static::getTrashFilename($filename, $timestamp))])]]></code>
- <code><![CDATA[Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_restore', ['filePath' => $targetPath, 'trashPath' => $sourcePath])]]></code>
<code><![CDATA[getAppValue]]></code>
<code><![CDATA[getUserFolder]]></code>
<code><![CDATA[getUserFolder]]></code>
diff --git a/lib/public/Files/Cache/CacheEntriesRemovedEvent.php b/lib/public/Files/Cache/CacheEntriesRemovedEvent.php
new file mode 100644
index 00000000000..277b7ee4ba6
--- /dev/null
+++ b/lib/public/Files/Cache/CacheEntriesRemovedEvent.php
@@ -0,0 +1,31 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\Files\Cache;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Meta-event wrapping multiple CacheEntryRemovedEvent for when an existing
+ * entry in the cache gets removed.
+ *
+ * @since 32.0.0
+ */
+class CacheEntriesRemovedEvent extends Event {
+ /**
+ * @param CacheEntryRemovedEvent[] $cacheEntryRemovedEvents
+ */
+ public function __construct(private readonly array $cacheEntryRemovedEvents) {}
+
+ /**
+ * @return CacheEntryRemovedEvent[]
+ */
+ public function getCacheEntryRemovedEvents(): array {
+ return $this->cacheEntryRemovedEvents;
+ }
+}