Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port files trashbin events to IEventDispatcher/IEventListener #32018

Merged
merged 4 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 11 additions & 17 deletions apps/files/tests/Command/DeleteOrphanedFilesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

use OC\Files\View;
use OCA\Files\Command\DeleteOrphanedFiles;
use OCP\Files\IRootFolder;
use OCP\Files\StorageNotAvailableException;
use OCP\IDBConnection;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase;
Expand All @@ -23,25 +25,14 @@
*/
class DeleteOrphanedFilesTest extends TestCase {

/**
* @var DeleteOrphanedFiles
*/
private $command;

/**
* @var \OCP\IDBConnection
*/
private $connection;

/**
* @var string
*/
private $user1;
private DeleteOrphanedFiles $command;
private IDBConnection $connection;
private string $user1;

protected function setUp(): void {
parent::setUp();

$this->connection = \OC::$server->getDatabaseConnection();
$this->connection = \OCP\Server::get(IDBConnection::class);

$this->user1 = $this->getUniqueID('user1_');

Expand Down Expand Up @@ -90,12 +81,13 @@ public function testClearFiles(): void {
->disableOriginalConstructor()
->getMock();

$rootFolder = \OCP\Server::get(IRootFolder::class);

// scan home storage so that mounts are properly setup
\OC::$server->getRootFolder()->getUserFolder($this->user1)->getStorage()->getScanner()->scan('');
$rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan('');

$this->loginAsUser($this->user1);


$view = new View('/' . $this->user1 . '/');
$view->mkdir('files/test');

Expand Down Expand Up @@ -132,6 +124,8 @@ public function testClearFiles(): void {
$this->assertCount(0, $this->getFile($fileInfo->getId()), 'Asserts that file gets cleaned up');
$this->assertCount(0, $this->getMounts($numericStorageId), 'Asserts that mount gets cleaned up');

// Rescan folder to add back to cache before deleting
$rootFolder->getUserFolder($this->user1)->getStorage()->getScanner()->scan('');
// since we deleted the storage it might throw a (valid) StorageNotAvailableException
try {
$view->unlink('files/test');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
'OCA\\Files_Trashbin\\Exceptions\\CopyRecursiveException' => $baseDir . '/../lib/Exceptions/CopyRecursiveException.php',
'OCA\\Files_Trashbin\\Expiration' => $baseDir . '/../lib/Expiration.php',
'OCA\\Files_Trashbin\\Helper' => $baseDir . '/../lib/Helper.php',
'OCA\\Files_Trashbin\\Hooks' => $baseDir . '/../lib/Hooks.php',
'OCA\\Files_Trashbin\\Listener\\EventListener' => $baseDir . '/../lib/Listener/EventListener.php',
'OCA\\Files_Trashbin\\Listeners\\LoadAdditionalScripts' => $baseDir . '/../lib/Listeners/LoadAdditionalScripts.php',
'OCA\\Files_Trashbin\\Listeners\\SyncLivePhotosListener' => $baseDir . '/../lib/Listeners/SyncLivePhotosListener.php',
'OCA\\Files_Trashbin\\Migration\\Version1010Date20200630192639' => $baseDir . '/../lib/Migration/Version1010Date20200630192639.php',
Expand Down
2 changes: 1 addition & 1 deletion apps/files_trashbin/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ComposerStaticInitFiles_Trashbin
'OCA\\Files_Trashbin\\Exceptions\\CopyRecursiveException' => __DIR__ . '/..' . '/../lib/Exceptions/CopyRecursiveException.php',
'OCA\\Files_Trashbin\\Expiration' => __DIR__ . '/..' . '/../lib/Expiration.php',
'OCA\\Files_Trashbin\\Helper' => __DIR__ . '/..' . '/../lib/Helper.php',
'OCA\\Files_Trashbin\\Hooks' => __DIR__ . '/..' . '/../lib/Hooks.php',
'OCA\\Files_Trashbin\\Listener\\EventListener' => __DIR__ . '/..' . '/../lib/Listener/EventListener.php',
'OCA\\Files_Trashbin\\Listeners\\LoadAdditionalScripts' => __DIR__ . '/..' . '/../lib/Listeners/LoadAdditionalScripts.php',
'OCA\\Files_Trashbin\\Listeners\\SyncLivePhotosListener' => __DIR__ . '/..' . '/../lib/Listeners/SyncLivePhotosListener.php',
'OCA\\Files_Trashbin\\Migration\\Version1010Date20200630192639' => __DIR__ . '/..' . '/../lib/Migration/Version1010Date20200630192639.php',
Expand Down
22 changes: 13 additions & 9 deletions apps/files_trashbin/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@
use OCA\Files_Trashbin\Capabilities;
use OCA\Files_Trashbin\Events\BeforeNodeRestoredEvent;
use OCA\Files_Trashbin\Expiration;
use OCA\Files_Trashbin\Listener\EventListener;
use OCA\Files_Trashbin\Listeners\LoadAdditionalScripts;
use OCA\Files_Trashbin\Listeners\SyncLivePhotosListener;
use OCA\Files_Trashbin\Trash\ITrashManager;
use OCA\Files_Trashbin\Trash\TrashManager;
use OCA\Files_Trashbin\Trashbin;
use OCA\Files_Trashbin\UserMigration\TrashbinMigrator;
use OCP\App\IAppManager;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\User\Events\BeforeUserDeletedEvent;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;

Expand All @@ -47,19 +53,17 @@ public function register(IRegistrationContext $context): void {
);

$context->registerEventListener(BeforeNodeRestoredEvent::class, SyncLivePhotosListener::class);

$context->registerEventListener(NodeWrittenEvent::class, EventListener::class);
$context->registerEventListener(BeforeUserDeletedEvent::class, EventListener::class);
$context->registerEventListener(BeforeFileSystemSetupEvent::class, EventListener::class);

// pre and post-rename, disable trash logic for the copy+unlink case
$context->registerEventListener(BeforeNodeDeletedEvent::class, Trashbin::class);
}

public function boot(IBootContext $context): void {
$context->injectFn([$this, 'registerTrashBackends']);

// create storage wrapper on setup
\OCP\Util::connectHook('OC_Filesystem', 'preSetup', 'OCA\Files_Trashbin\Storage', 'setupStorage');
//Listen to delete user signal
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\Files_Trashbin\Hooks', 'deleteUser_hook');
//Listen to post write hook
\OCP\Util::connectHook('OC_Filesystem', 'post_write', 'OCA\Files_Trashbin\Hooks', 'post_write_hook');
// pre and post-rename, disable trash logic for the copy+unlink case
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Files_Trashbin\Trashbin', 'ensureFileScannedHook');
}

public function registerTrashBackends(ContainerInterface $serverContainer, LoggerInterface $logger, IAppManager $appManager, ITrashManager $trashManager): void {
Expand Down
29 changes: 0 additions & 29 deletions apps/files_trashbin/lib/Hooks.php

This file was deleted.

45 changes: 45 additions & 0 deletions apps/files_trashbin/lib/Listener/EventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace OCA\Files_Trashbin\Listener;

use OCA\Files_Trashbin\Storage;
use OCA\Files_Trashbin\Trashbin;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\User\Events\BeforeUserDeletedEvent;

/** @template-implements IEventListener<NodeWrittenEvent|BeforeUserDeletedEvent|BeforeFileSystemSetupEvent> */
class EventListener implements IEventListener {
private ?string $userId;

public function __construct(?string $userId = null) {
$this->userId = $userId;
}

public function handle(Event $event): void {
if ($event instanceof NodeWrittenEvent) {
// Resize trash
if (!empty($this->userId)) {

Check notice

Code scanning / Psalm

RiskyTruthyFalsyComparison Note

Operand of type null|string contains type string, which can be falsy and truthy. This can cause possibly unexpected behavior. Use strict comparison instead.
Trashbin::resizeTrash($this->userId);
}
}

// Clean up user specific settings if user gets deleted
if ($event instanceof BeforeUserDeletedEvent) {
Trashbin::deleteUser($event->getUser()->getUID());
}

if ($event instanceof BeforeFileSystemSetupEvent) {
Storage::setupStorage();
}
}
}
6 changes: 0 additions & 6 deletions apps/files_trashbin/lib/Storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,7 @@ class Storage extends Wrapper {

/**
* Storage constructor.
*
* @param array $parameters
* @param ITrashManager|null $trashManager
* @param IUserManager|null $userManager
* @param LoggerInterface|null $logger
* @param IEventDispatcher|null $eventDispatcher
* @param IRootFolder|null $rootFolder
*/
public function __construct(
$parameters,
Expand Down
24 changes: 16 additions & 8 deletions apps/files_trashbin/lib/Trashbin.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
use OC\Files\Cache\CacheEntry;
use OC\Files\Cache\CacheQueryBuilder;
use OC\Files\Filesystem;
use OC\Files\Node\File;
use OC\Files\Node\Folder;
use OC\Files\Node\NonExistingFile;
use OC\Files\Node\NonExistingFolder;
use OC\Files\View;
Expand All @@ -23,7 +21,12 @@
use OCA\Files_Trashbin\Events\NodeRestoredEvent;
use OCP\App\IAppManager;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
Expand All @@ -38,21 +41,20 @@
use OCP\Server;
use Psr\Log\LoggerInterface;

class Trashbin {
/** @template-implements IEventListener<BeforeNodeDeletedEvent> */
class Trashbin implements IEventListener {
come-nc marked this conversation as resolved.
Show resolved Hide resolved
// unit: percentage; 50% of available disk space/quota
public const DEFAULTMAXSIZE = 50;

/**
* Ensure we don't need to scan the file during the move to trash
* by triggering the scan in the pre-hook
*
* @param array $params
*/
public static function ensureFileScannedHook($params) {
public static function ensureFileScannedHook(Node $node): void {
try {
self::getUidAndFilename($params['path']);
self::getUidAndFilename($node->getPath());
} catch (NotFoundException $e) {
// nothing to scan for non existing files
// Nothing to scan for non existing files
}
}

Expand Down Expand Up @@ -1170,4 +1172,10 @@
return new NonExistingFile($rootFolder, $view, $fullPath);
}
}

public function handle(Event $event): void {
if ($event instanceof BeforeNodeDeletedEvent) {

Check notice

Code scanning / Psalm

RedundantConditionGivenDocblockType Note

Docblock-defined type OCP\Files\Events\Node\BeforeNodeDeletedEvent for $event is always OCP\Files\Events\Node\BeforeNodeDeletedEvent
self::ensureFileScannedHook($event->getNode());
}
}
}
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@
'OCP\\Files\\EntityTooLargeException' => $baseDir . '/lib/public/Files/EntityTooLargeException.php',
'OCP\\Files\\Events\\BeforeDirectFileDownloadEvent' => $baseDir . '/lib/public/Files/Events/BeforeDirectFileDownloadEvent.php',
'OCP\\Files\\Events\\BeforeFileScannedEvent' => $baseDir . '/lib/public/Files/Events/BeforeFileScannedEvent.php',
'OCP\\Files\\Events\\BeforeFileSystemSetupEvent' => $baseDir . '/lib/public/Files/Events/BeforeFileSystemSetupEvent.php',
'OCP\\Files\\Events\\BeforeFolderScannedEvent' => $baseDir . '/lib/public/Files/Events/BeforeFolderScannedEvent.php',
'OCP\\Files\\Events\\BeforeZipCreatedEvent' => $baseDir . '/lib/public/Files/Events/BeforeZipCreatedEvent.php',
'OCP\\Files\\Events\\FileCacheUpdated' => $baseDir . '/lib/public/Files/Events/FileCacheUpdated.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\Files\\EntityTooLargeException' => __DIR__ . '/../../..' . '/lib/public/Files/EntityTooLargeException.php',
'OCP\\Files\\Events\\BeforeDirectFileDownloadEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeDirectFileDownloadEvent.php',
'OCP\\Files\\Events\\BeforeFileScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeFileScannedEvent.php',
'OCP\\Files\\Events\\BeforeFileSystemSetupEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeFileSystemSetupEvent.php',
'OCP\\Files\\Events\\BeforeFolderScannedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeFolderScannedEvent.php',
'OCP\\Files\\Events\\BeforeZipCreatedEvent' => __DIR__ . '/../../..' . '/lib/public/Files/Events/BeforeZipCreatedEvent.php',
'OCP\\Files\\Events\\FileCacheUpdated' => __DIR__ . '/../../..' . '/lib/public/Files/Events/FileCacheUpdated.php',
Expand Down
5 changes: 5 additions & 0 deletions lib/private/Files/SetupManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IMountProvider;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\Events\BeforeFileSystemSetupEvent;
use OCP\Files\Events\InvalidateMountCacheEvent;
use OCP\Files\Events\Node\FilesystemTornDownEvent;
use OCP\Files\Mount\IMountManager;
Expand Down Expand Up @@ -227,8 +228,12 @@ private function oneTimeUserSetup(IUser $user) {

$prevLogging = Filesystem::logWarningWhenAddingStorageWrapper(false);

// TODO remove hook
OC_Hook::emit('OC_Filesystem', 'preSetup', ['user' => $user->getUID()]);

$event = new BeforeFileSystemSetupEvent($user);
$this->eventDispatcher->dispatchTyped($event);

Filesystem::logWarningWhenAddingStorageWrapper($prevLogging);

$userDir = '/' . $user->getUID() . '/files';
Expand Down
36 changes: 36 additions & 0 deletions lib/public/Files/Events/BeforeFileSystemSetupEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/

namespace OCP\Files\Events;

use OCP\EventDispatcher\Event;
use OCP\IUser;

/**
* Event triggered before the file system is setup
*
* @since 31.0.0
*/
class BeforeFileSystemSetupEvent extends Event {
/**
* @since 31.0.0
*/
public function __construct(
private IUser $user,
) {
parent::__construct();
}

/**
* @since 31.0.0
*/
public function getUser(): IUser {
return $this->user;
}
}
Loading
Loading