mirror of
https://github.com/nextcloud/server.git
synced 2026-06-12 18:21:40 -04:00
refactor(trashbin): Move some parts of Trashbin to reusable services
Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
This commit is contained in:
parent
6ee28229d5
commit
042a773eba
14 changed files with 453 additions and 266 deletions
|
|
@ -42,6 +42,8 @@ return array(
|
|||
'OCA\\Files_Trashbin\\Sabre\\TrashRoot' => $baseDir . '/../lib/Sabre/TrashRoot.php',
|
||||
'OCA\\Files_Trashbin\\Sabre\\TrashbinPlugin' => $baseDir . '/../lib/Sabre/TrashbinPlugin.php',
|
||||
'OCA\\Files_Trashbin\\Service\\ConfigService' => $baseDir . '/../lib/Service/ConfigService.php',
|
||||
'OCA\\Files_Trashbin\\Service\\ExpireService' => $baseDir . '/../lib/Service/ExpireService.php',
|
||||
'OCA\\Files_Trashbin\\Service\\TrashFolderService' => $baseDir . '/../lib/Service/TrashFolderService.php',
|
||||
'OCA\\Files_Trashbin\\Storage' => $baseDir . '/../lib/Storage.php',
|
||||
'OCA\\Files_Trashbin\\Trash\\BackendNotFoundException' => $baseDir . '/../lib/Trash/BackendNotFoundException.php',
|
||||
'OCA\\Files_Trashbin\\Trash\\ITrashBackend' => $baseDir . '/../lib/Trash/ITrashBackend.php',
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ namespace Composer\Autoload;
|
|||
class ComposerStaticInitFiles_Trashbin
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'O' =>
|
||||
'O' =>
|
||||
array (
|
||||
'OCA\\Files_Trashbin\\' => 19,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'OCA\\Files_Trashbin\\' =>
|
||||
'OCA\\Files_Trashbin\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/../lib',
|
||||
),
|
||||
|
|
@ -57,6 +57,8 @@ class ComposerStaticInitFiles_Trashbin
|
|||
'OCA\\Files_Trashbin\\Sabre\\TrashRoot' => __DIR__ . '/..' . '/../lib/Sabre/TrashRoot.php',
|
||||
'OCA\\Files_Trashbin\\Sabre\\TrashbinPlugin' => __DIR__ . '/..' . '/../lib/Sabre/TrashbinPlugin.php',
|
||||
'OCA\\Files_Trashbin\\Service\\ConfigService' => __DIR__ . '/..' . '/../lib/Service/ConfigService.php',
|
||||
'OCA\\Files_Trashbin\\Service\\ExpireService' => __DIR__ . '/..' . '/../lib/Service/ExpireService.php',
|
||||
'OCA\\Files_Trashbin\\Service\\TrashFolderService' => __DIR__ . '/..' . '/../lib/Service/TrashFolderService.php',
|
||||
'OCA\\Files_Trashbin\\Storage' => __DIR__ . '/..' . '/../lib/Storage.php',
|
||||
'OCA\\Files_Trashbin\\Trash\\BackendNotFoundException' => __DIR__ . '/..' . '/../lib/Trash/BackendNotFoundException.php',
|
||||
'OCA\\Files_Trashbin\\Trash\\ITrashBackend' => __DIR__ . '/..' . '/../lib/Trash/ITrashBackend.php',
|
||||
|
|
|
|||
|
|
@ -7,10 +7,9 @@
|
|||
*/
|
||||
namespace OCA\Files_Trashbin\BackgroundJob;
|
||||
|
||||
use OC\Files\View;
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Helper;
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\TimedJob;
|
||||
use OCP\IAppConfig;
|
||||
|
|
@ -19,10 +18,12 @@ use Psr\Log\LoggerInterface;
|
|||
|
||||
class ExpireTrash extends TimedJob {
|
||||
public function __construct(
|
||||
private IAppConfig $appConfig,
|
||||
private IUserManager $userManager,
|
||||
private Expiration $expiration,
|
||||
private LoggerInterface $logger,
|
||||
readonly private IAppConfig $appConfig,
|
||||
readonly private IUserManager $userManager,
|
||||
readonly private Expiration $expiration,
|
||||
readonly private ExpireService $expireService,
|
||||
readonly private SetupManager $setupManager,
|
||||
readonly private LoggerInterface $logger,
|
||||
ITimeFactory $time,
|
||||
) {
|
||||
parent::__construct($time);
|
||||
|
|
@ -47,12 +48,7 @@ class ExpireTrash extends TimedJob {
|
|||
|
||||
foreach ($users as $user) {
|
||||
try {
|
||||
$uid = $user->getUID();
|
||||
if (!$this->setupFS($uid)) {
|
||||
continue;
|
||||
}
|
||||
$dirContent = Helper::getTrashFiles('/', $uid, 'mtime');
|
||||
Trashbin::deleteExpiredFiles($dirContent, $uid);
|
||||
$this->expireService->expireTrashForUser($user);
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->error('Error while expiring trashbin for user ' . $user->getUID(), ['exception' => $e]);
|
||||
}
|
||||
|
|
@ -61,28 +57,12 @@ class ExpireTrash extends TimedJob {
|
|||
|
||||
if ($stopTime < time()) {
|
||||
$this->appConfig->setValueInt('files_trashbin', 'background_job_expire_trash_offset', $offset);
|
||||
\OC_Util::tearDownFS();
|
||||
$this->setupManager->tearDown();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->appConfig->setValueInt('files_trashbin', 'background_job_expire_trash_offset', 0);
|
||||
\OC_Util::tearDownFS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on behalf on trash item owner
|
||||
*/
|
||||
protected function setupFS(string $user): bool {
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_Util::setupFS($user);
|
||||
|
||||
// Check if this user has a trashbin directory
|
||||
$view = new View('/' . $user);
|
||||
if (!$view->is_dir('/files_trashbin/files')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
$this->setupManager->tearDown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,32 +8,33 @@
|
|||
namespace OCA\Files_Trashbin\Command;
|
||||
|
||||
use OC\Command\FileAccess;
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Encryption\Users\Setup;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\Command\ICommand;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class Expire implements ICommand {
|
||||
use FileAccess;
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*/
|
||||
public function __construct(
|
||||
private $user,
|
||||
readonly private string $user,
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle() {
|
||||
$userManager = Server::get(IUserManager::class);
|
||||
if (!$userManager->userExists($this->user)) {
|
||||
// User has been deleted already
|
||||
return;
|
||||
public function handle(): void {
|
||||
try {
|
||||
$user = Server::get(IUserManager::class)->get($this->user);
|
||||
if (!$user) {
|
||||
return;
|
||||
}
|
||||
Server::get(ExpireService::class)->expireTrashForUser($user);
|
||||
Server::get(SetupManager::class)->execute();
|
||||
} catch (\Throwable $e) {
|
||||
Server::get(LoggerInterface::class)->error('Error while expiring trashbin for user ' . $this->user, ['exception' => $e]);
|
||||
}
|
||||
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_Util::setupFS($this->user);
|
||||
Trashbin::expire($this->user);
|
||||
\OC_Util::tearDownFS();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,11 @@
|
|||
*/
|
||||
namespace OCA\Files_Trashbin\Command;
|
||||
|
||||
use OC\Files\View;
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OCP\IUser;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IUserManager;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
|
@ -20,15 +19,12 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ExpireTrash extends Command {
|
||||
|
||||
/**
|
||||
* @param IUserManager|null $userManager
|
||||
* @param Expiration|null $expiration
|
||||
*/
|
||||
public function __construct(
|
||||
private LoggerInterface $logger,
|
||||
private ?IUserManager $userManager = null,
|
||||
private ?Expiration $expiration = null,
|
||||
readonly SetupManager $setupManager,
|
||||
readonly IRootFolder $rootFolder,
|
||||
readonly private IUserManager $userManager,
|
||||
readonly private Expiration $expiration,
|
||||
readonly private ExpireService $expireService,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
@ -55,10 +51,11 @@ class ExpireTrash extends Command {
|
|||
$users = $input->getArgument('user_id');
|
||||
if (!empty($users)) {
|
||||
foreach ($users as $user) {
|
||||
if ($this->userManager->userExists($user)) {
|
||||
$output->writeln("Remove deleted files of <info>$user</info>");
|
||||
$userObject = $this->userManager->get($user);
|
||||
$this->expireTrashForUser($userObject);
|
||||
$userObject = $this->userManager->get($user);
|
||||
if ($userObject) {
|
||||
$output->writeln("Remove deleted files of <info>$user</info>");
|
||||
$this->expireService->expireTrashForUser($userObject);
|
||||
$this->setupManager->tearDown();
|
||||
} else {
|
||||
$output->writeln("<error>Unknown user $user</error>");
|
||||
return 1;
|
||||
|
|
@ -71,41 +68,18 @@ class ExpireTrash extends Command {
|
|||
$users = $this->userManager->getSeenUsers();
|
||||
foreach ($users as $user) {
|
||||
$p->advance();
|
||||
$this->expireTrashForUser($user);
|
||||
try {
|
||||
$this->expireService->expireTrashForUser($user);
|
||||
$this->setupManager->tearDown();
|
||||
} catch (\Throwable $e) {
|
||||
$displayName = $user->getDisplayName();
|
||||
$output->writeln("<error>Error while expiring trashbin for user $displayName</error>");
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
$p->finish();
|
||||
$output->writeln('');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function expireTrashForUser(IUser $user) {
|
||||
try {
|
||||
$uid = $user->getUID();
|
||||
if (!$this->setupFS($uid)) {
|
||||
return;
|
||||
}
|
||||
Trashbin::expire($uid);
|
||||
} catch (\Throwable $e) {
|
||||
$this->logger->error('Error while expiring trashbin for user ' . $user->getUID(), ['exception' => $e]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on behalf on trash item owner
|
||||
* @param string $user
|
||||
* @return boolean
|
||||
*/
|
||||
protected function setupFS($user) {
|
||||
\OC_Util::tearDownFS();
|
||||
\OC_Util::setupFS($user);
|
||||
|
||||
// Check if this user has a trashbin directory
|
||||
$view = new View('/' . $user);
|
||||
if (!$view->is_dir('/files_trashbin/files')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,14 @@ declare(strict_types=1);
|
|||
namespace OCA\Files_Trashbin\Command;
|
||||
|
||||
use OC\Core\Command\Base;
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\Command\IBus;
|
||||
use OCP\IConfig;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\Util;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
|
@ -21,9 +24,9 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
|
||||
class Size extends Base {
|
||||
public function __construct(
|
||||
private IConfig $config,
|
||||
private IUserManager $userManager,
|
||||
private IBus $commandBus,
|
||||
readonly private IConfig $config,
|
||||
readonly private IUserManager $userManager,
|
||||
readonly private ExpireService $expireService,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
@ -53,7 +56,10 @@ class Size extends Base {
|
|||
}
|
||||
if ($user) {
|
||||
$this->config->setUserValue($user, 'files_trashbin', 'trashbin_size', (string)$parsedSize);
|
||||
$this->commandBus->push(new Expire($user));
|
||||
$userObject = $this->userManager->get($user);
|
||||
if ($userObject) {
|
||||
$this->expireService->scheduleExpirationJob($userObject);
|
||||
}
|
||||
} else {
|
||||
$this->config->setAppValue('files_trashbin', 'trashbin_size', (string)$parsedSize);
|
||||
$output->writeln('<info>Warning: changing the default trashbin size will automatically trigger cleanup of existing trashbins,</info>');
|
||||
|
|
|
|||
|
|
@ -9,18 +9,23 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Files_Trashbin\Listener;
|
||||
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
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\IUser;
|
||||
use OCP\IUserManager;
|
||||
use OCP\User\Events\BeforeUserDeletedEvent;
|
||||
|
||||
/** @template-implements IEventListener<NodeWrittenEvent|BeforeUserDeletedEvent|BeforeFileSystemSetupEvent> */
|
||||
class EventListener implements IEventListener {
|
||||
public function __construct(
|
||||
private ?string $userId = null,
|
||||
readonly private ExpireService $expireService,
|
||||
readonly private IUserManager $userManager,
|
||||
readonly private ?string $userId = null,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
@ -28,7 +33,10 @@ class EventListener implements IEventListener {
|
|||
if ($event instanceof NodeWrittenEvent) {
|
||||
// Resize trash
|
||||
if (!empty($this->userId)) {
|
||||
Trashbin::resizeTrash($this->userId);
|
||||
$user = $this->userManager->get($this->userId);
|
||||
if ($user) {
|
||||
$this->expireService->scheduleExpirationJobIfNeeded($user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
122
apps/files_trashbin/lib/Service/ExpireService.php
Normal file
122
apps/files_trashbin/lib/Service/ExpireService.php
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?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\Service;
|
||||
|
||||
use OCA\Files_Trashbin\Command\Expire;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OCP\Command\IBus;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\Files\NotPermittedException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUser;
|
||||
use OCP\Server;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
class ExpireService {
|
||||
public function __construct(
|
||||
readonly private TrashFolderService $trashFolderService,
|
||||
readonly private Expiration $expiration,
|
||||
readonly private IBus $ibus,
|
||||
readonly private LoggerInterface $logger,
|
||||
) {
|
||||
}
|
||||
|
||||
public function expireTrashForUser(IUser $user): void {
|
||||
$trashFolderRoot = $this->trashFolderService->getTrashFolderRoot($user);
|
||||
if (!$trashFolderRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
$availableSpace = $this->trashFolderService->getAvailableSpace($trashFolderRoot, $user);
|
||||
|
||||
try {
|
||||
/** @var Folder $trashFolder */
|
||||
$trashFolder = $trashFolderRoot->get('files');
|
||||
} catch (NotFoundException) {
|
||||
echo "bug";
|
||||
return; // Nothing to expire
|
||||
}
|
||||
|
||||
$nodes = $trashFolder->getDirectoryListing();
|
||||
|
||||
usort($nodes, fn (Node $a, Node $b): int => $a->getMTime() <=> $b->getMTime());
|
||||
|
||||
// delete all files older then $retention_obligation
|
||||
[$delSize, $count] = $this->deleteExpiredNodes($trashFolder, $nodes, $user);
|
||||
|
||||
$availableSpace += $delSize;
|
||||
|
||||
// delete files from trash until we meet the trash bin size limit again
|
||||
Trashbin::deleteNodes(array_slice($nodes, $count), $user, $availableSpace);
|
||||
}
|
||||
|
||||
public function scheduleExpirationJobIfNeeded(IUser $user): void {
|
||||
$trashFolderRoot = $this->trashFolderService->getTrashFolderRoot($user);
|
||||
if (!$trashFolderRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
$freeSpace = $this->trashFolderService->getAvailableSpace($trashFolderRoot, $user);
|
||||
|
||||
if ($freeSpace < 0) {
|
||||
$this->scheduleExpirationJob($user);
|
||||
}
|
||||
}
|
||||
|
||||
public function scheduleExpirationJob(IUser $user): void {
|
||||
// let the admin disable auto expire
|
||||
if ($this->expiration->isEnabled()) {
|
||||
$this->ibus->push(new Expire($user->getUID()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
private function deleteExpiredNodes(Folder $trashFolder, array $nodes, IUser $user) {
|
||||
/** @var Expiration $expiration */
|
||||
$expiration = Server::get(Expiration::class);
|
||||
$size = 0;
|
||||
$count = 0;
|
||||
foreach ($nodes as $node) {
|
||||
$timestamp = $node->getMTime();
|
||||
if (!$expiration->isExpired($timestamp)) {
|
||||
break; // Since the nodes are sorted by mtime, we can already abord
|
||||
}
|
||||
|
||||
try {
|
||||
$size += $this->trashFolderService->delete($trashFolder, $node, $user, $timestamp);
|
||||
$count++;
|
||||
} catch (NotPermittedException $e) {
|
||||
$this->logger->warning('Removing "' . $node->getName() . '" from trashbin failed for user "{user}"',
|
||||
[
|
||||
'exception' => $e,
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $user,
|
||||
]
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$this->logger->info(
|
||||
'Remove "' . $node->getName() . '" from trashbin for user "{user}" because it exceeds max retention obligation term.',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $user,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return [$size, $count];
|
||||
}
|
||||
}
|
||||
174
apps/files_trashbin/lib/Service/TrashFolderService.php
Normal file
174
apps/files_trashbin/lib/Service/TrashFolderService.php
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
<?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\Service;
|
||||
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\Files\NotFoundException;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\IUser;
|
||||
use OCP\Server;
|
||||
use OCP\Util;
|
||||
|
||||
/**
|
||||
* @psalm-type TrashFolderSpaceInfo array{available: int|float, used: int|float}
|
||||
*/
|
||||
class TrashFolderService {
|
||||
public function __construct(
|
||||
readonly private IRootFolder $rootFolder,
|
||||
readonly private IAppManager $appManager,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getTrashFolderRoot(IUser $user): false|Folder {
|
||||
$userRoot = $this->rootFolder->getUserFolder($user->getUID())->getParent();
|
||||
|
||||
try {
|
||||
/** @var Folder $folder */
|
||||
$folder = $userRoot->get('files_trashbin');
|
||||
return $folder;
|
||||
} catch (NotFoundException) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getTrashFolder(IUser $user): false|Folder {
|
||||
$rootTrashFolder = $this->getTrashFolderRoot($user);
|
||||
if (!$rootTrashFolder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var Folder $folder */
|
||||
try {
|
||||
/** @var Folder $folder */
|
||||
$folder = $rootTrashFolder->get('files');
|
||||
return $folder;
|
||||
} catch (NotFoundException) {
|
||||
return $rootTrashFolder->newFolder('files');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate remaining free space for trash bin
|
||||
*
|
||||
* @return int|float The available space
|
||||
*/
|
||||
public function getAvailableSpace(Folder $trashFolderRoot, IUser $user): int|float {
|
||||
$configuredTrashBinSize = TrashBin::getConfiguredTrashbinSize($user->getUID());
|
||||
$trashBinSize = $trashFolderRoot->getSize(false);
|
||||
if ($configuredTrashBinSize > -1) {
|
||||
return $configuredTrashBinSize - $trashBinSize;
|
||||
}
|
||||
|
||||
$softQuota = true;
|
||||
$quota = $user->getQuota();
|
||||
if ($quota === null || $quota === 'none') {
|
||||
$quota = $this->rootFolder->getFreeSpace();
|
||||
$softQuota = false;
|
||||
// inf or unknown free space
|
||||
if ($quota < 0) {
|
||||
$quota = PHP_INT_MAX;
|
||||
}
|
||||
} else {
|
||||
$quota = Util::computerFileSize($quota);
|
||||
// invalid quota
|
||||
if ($quota === false) {
|
||||
$quota = PHP_INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate available space for trash bin
|
||||
// subtract size of files and current trash bin size from quota
|
||||
if ($softQuota) {
|
||||
$userFolder = $trashFolderRoot->getParent();
|
||||
if (is_null($userFolder)) {
|
||||
return 0;
|
||||
}
|
||||
$free = $quota - $userFolder->getSize(false); // remaining free space for user
|
||||
if ($free > 0) {
|
||||
$availableSpace = ($free * Trashbin::DEFAULTMAXSIZE / 100) - $trashBinSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free - $trashBinSize;
|
||||
}
|
||||
} else {
|
||||
$availableSpace = $quota;
|
||||
}
|
||||
|
||||
return Util::numericToNumber($availableSpace);
|
||||
}
|
||||
|
||||
public static function delete(Folder $trashFolder, Node $node, IUser $user, $timestamp = null) {
|
||||
$size = 0;
|
||||
|
||||
if ($timestamp) {
|
||||
$query = Server::get(IDBConnection::class)->getQueryBuilder();
|
||||
$query->delete('files_trash')
|
||||
->where($query->expr()->eq('user', $query->createNamedParameter($user)))
|
||||
->andWhere($query->expr()->eq('id', $query->createNamedParameter($node->getName())))
|
||||
->andWhere($query->expr()->eq('timestamp', $query->createNamedParameter($timestamp)));
|
||||
$query->executeStatement();
|
||||
|
||||
$file = Trashbin::getTrashFilename($node->getName(), $timestamp);
|
||||
} else {
|
||||
$file = $node->getName();
|
||||
}
|
||||
|
||||
//$size += Trashbin::deleteVersions($view, $file, $node, $timestamp, $user);
|
||||
|
||||
try {
|
||||
$node = $trashFolder->get($file);
|
||||
} catch (NotFoundException) {
|
||||
return $size;
|
||||
}
|
||||
|
||||
if ($node instanceof Folder) {
|
||||
$size += Trashbin::calculateSize(new View('/' . $user . '/files_trashbin/files/' . $file));
|
||||
} elseif ($node instanceof File) {
|
||||
$size += $view->filesize('/files_trashbin/files/' . $file);
|
||||
}
|
||||
|
||||
Trashbin::emitTrashbinPreDelete('/files_trashbin/files/' . $file);
|
||||
$node->delete();
|
||||
Trashbin::emitTrashbinPostDelete('/files_trashbin/files/' . $file);
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $filename
|
||||
* @param ?int $timestamp
|
||||
*/
|
||||
private function deleteVersions(Folder $trashFolderRoot, $fileName, Node $node, ?int $timestamp, IUser $user): int|float {
|
||||
$size = 0;
|
||||
if ($this->appManager->isEnabledForUser('files_versions')) {
|
||||
$trashFolderRoot->get('versions/' . $fileName);
|
||||
if ($view->is_dir('files_trashbin/versions/' . $file)) {
|
||||
$size += Trashbin::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ namespace OCA\Files_Trashbin;
|
|||
use OC\Files\Cache\Cache;
|
||||
use OC\Files\Cache\CacheEntry;
|
||||
use OC\Files\Cache\CacheQueryBuilder;
|
||||
use OC\Files\FileInfo;
|
||||
use OC\Files\Filesystem;
|
||||
use OC\Files\Node\NonExistingFile;
|
||||
use OC\Files\Node\NonExistingFolder;
|
||||
|
|
@ -17,14 +18,13 @@ use OC\Files\View;
|
|||
use OC\User\NoUserException;
|
||||
use OC_User;
|
||||
use OCA\Files_Trashbin\AppInfo\Application;
|
||||
use OCA\Files_Trashbin\Command\Expire;
|
||||
use OCA\Files_Trashbin\Events\BeforeNodeRestoredEvent;
|
||||
use OCA\Files_Trashbin\Events\NodeRestoredEvent;
|
||||
use OCA\Files_Trashbin\Exceptions\CopyRecursiveException;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCA\Files_Versions\Storage;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Command\IBus;
|
||||
use OCP\EventDispatcher\Event;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\EventDispatcher\IEventListener;
|
||||
|
|
@ -42,6 +42,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;
|
||||
|
|
@ -350,17 +351,23 @@ class Trashbin implements IEventListener {
|
|||
|
||||
$trashStorage->releaseLock($trashInternalPath, ILockingProvider::LOCK_EXCLUSIVE, $lockingProvider);
|
||||
|
||||
self::scheduleExpire($user);
|
||||
$userManager = Server::get(IUserManager::class);
|
||||
$expireServie = Server::get(ExpireService::class);
|
||||
if ($userObject = $userManager->get($user)) {
|
||||
$expireServie->scheduleExpirationJob($userObject);
|
||||
}
|
||||
|
||||
// if owner !== user we also need to update the owners trash size
|
||||
if ($owner !== $user) {
|
||||
self::scheduleExpire($owner);
|
||||
if ($ownerObject = $userManager->get($owner)) {
|
||||
$expireServie->scheduleExpirationJob($ownerObject);
|
||||
}
|
||||
}
|
||||
|
||||
return $moveSuccessful;
|
||||
}
|
||||
|
||||
private static function getConfiguredTrashbinSize(string $user): int|float {
|
||||
public static function getConfiguredTrashbinSize(string $user): int|float {
|
||||
$config = Server::get(IConfig::class);
|
||||
$userTrashbinSize = $config->getUserValue($user, 'files_trashbin', 'trashbin_size', '-1');
|
||||
if (is_numeric($userTrashbinSize) && ($userTrashbinSize > -1)) {
|
||||
|
|
@ -643,7 +650,7 @@ class Trashbin implements IEventListener {
|
|||
*
|
||||
* @param string $path
|
||||
*/
|
||||
protected static function emitTrashbinPreDelete($path) {
|
||||
public static function emitTrashbinPreDelete($path) {
|
||||
\OC_Hook::emit('\OCP\Trashbin', 'preDelete', ['path' => $path]);
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +659,7 @@ class Trashbin implements IEventListener {
|
|||
*
|
||||
* @param string $path
|
||||
*/
|
||||
protected static function emitTrashbinPostDelete($path) {
|
||||
public static function emitTrashbinPostDelete($path) {
|
||||
\OC_Hook::emit('\OCP\Trashbin', 'delete', ['path' => $path]);
|
||||
}
|
||||
|
||||
|
|
@ -664,6 +671,7 @@ class Trashbin implements IEventListener {
|
|||
* @param int $timestamp of deletion time
|
||||
*
|
||||
* @return int|float size of deleted files
|
||||
* @throws NotPermittedException
|
||||
*/
|
||||
public static function delete($filename, $user, $timestamp = null) {
|
||||
$userRoot = \OC::$server->getUserFolder($user)->getParent();
|
||||
|
|
@ -704,32 +712,6 @@ class Trashbin implements IEventListener {
|
|||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $file
|
||||
* @param string $filename
|
||||
* @param ?int $timestamp
|
||||
*/
|
||||
private static function deleteVersions(View $view, $file, $filename, $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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether a file exists in trashbin
|
||||
*
|
||||
|
|
@ -762,113 +744,11 @@ class Trashbin implements IEventListener {
|
|||
return (bool)$query->executeStatement();
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate remaining free space for trash bin
|
||||
*
|
||||
* @param int|float $trashbinSize current size of the trash bin
|
||||
* @param string $user
|
||||
* @return int|float available free space for trash bin
|
||||
*/
|
||||
private static function calculateFreeSpace(int|float $trashbinSize, string $user): int|float {
|
||||
$configuredTrashbinSize = static::getConfiguredTrashbinSize($user);
|
||||
if ($configuredTrashbinSize > -1) {
|
||||
return $configuredTrashbinSize - $trashbinSize;
|
||||
}
|
||||
|
||||
$userObject = Server::get(IUserManager::class)->get($user);
|
||||
if (is_null($userObject)) {
|
||||
return 0;
|
||||
}
|
||||
$softQuota = true;
|
||||
$quota = $userObject->getQuota();
|
||||
if ($quota === null || $quota === 'none') {
|
||||
$quota = Filesystem::free_space('/');
|
||||
$softQuota = false;
|
||||
// inf or unknown free space
|
||||
if ($quota < 0) {
|
||||
$quota = PHP_INT_MAX;
|
||||
}
|
||||
} else {
|
||||
$quota = Util::computerFileSize($quota);
|
||||
// invalid quota
|
||||
if ($quota === false) {
|
||||
$quota = PHP_INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate available space for trash bin
|
||||
// subtract size of files and current trash bin size from quota
|
||||
if ($softQuota) {
|
||||
$userFolder = \OC::$server->getUserFolder($user);
|
||||
if (is_null($userFolder)) {
|
||||
return 0;
|
||||
}
|
||||
$free = $quota - $userFolder->getSize(false); // remaining free space for user
|
||||
if ($free > 0) {
|
||||
$availableSpace = ($free * self::DEFAULTMAXSIZE / 100) - $trashbinSize; // how much space can be used for versions
|
||||
} else {
|
||||
$availableSpace = $free - $trashbinSize;
|
||||
}
|
||||
} else {
|
||||
$availableSpace = $quota;
|
||||
}
|
||||
|
||||
return Util::numericToNumber($availableSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* resize trash bin if necessary after a new file was added to Nextcloud
|
||||
*
|
||||
* @param string $user user id
|
||||
*/
|
||||
public static function resizeTrash($user) {
|
||||
$size = self::getTrashbinSize($user);
|
||||
|
||||
$freeSpace = self::calculateFreeSpace($size, $user);
|
||||
|
||||
if ($freeSpace < 0) {
|
||||
self::scheduleExpire($user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up the trash bin
|
||||
*
|
||||
* @param string $user
|
||||
*/
|
||||
public static function expire($user) {
|
||||
$trashBinSize = self::getTrashbinSize($user);
|
||||
$availableSpace = self::calculateFreeSpace($trashBinSize, $user);
|
||||
|
||||
$dirContent = Helper::getTrashFiles('/', $user, 'mtime');
|
||||
|
||||
// delete all files older then $retention_obligation
|
||||
[$delSize, $count] = self::deleteExpiredFiles($dirContent, $user);
|
||||
|
||||
$availableSpace += $delSize;
|
||||
|
||||
// delete files from trash until we meet the trash bin size limit again
|
||||
self::deleteFiles(array_slice($dirContent, $count), $user, $availableSpace);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
*/
|
||||
private static function scheduleExpire($user) {
|
||||
// let the admin disable auto expire
|
||||
/** @var Application $application */
|
||||
$application = Server::get(Application::class);
|
||||
$expiration = $application->getContainer()->query('Expiration');
|
||||
if ($expiration->isEnabled()) {
|
||||
Server::get(IBus::class)->push(new Expire($user));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if the size limit for the trash bin is reached, we delete the oldest
|
||||
* files in the trash bin until we meet the limit again
|
||||
*
|
||||
* @param array $files
|
||||
* @param FileInfo[] $files
|
||||
* @param string $user
|
||||
* @param int|float $availableSpace available disc space
|
||||
* @return int|float size of deleted files
|
||||
|
|
@ -900,6 +780,40 @@ class Trashbin implements IEventListener {
|
|||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* if the size limit for the trash bin is reached, we delete the oldest
|
||||
* files in the trash bin until we meet the limit again
|
||||
*
|
||||
* @param Node[] $nodes
|
||||
* @return int|float size of deleted files
|
||||
*/
|
||||
public static function deleteNodes(array $nodes, IUser $user, int|float $availableSpace): int|float {
|
||||
/** @var Application $application */
|
||||
$application = Server::get(Application::class);
|
||||
$expiration = $application->getContainer()->get('Expiration');
|
||||
$size = 0;
|
||||
|
||||
if ($availableSpace < 0) {
|
||||
foreach ($nodes as $node) {
|
||||
if ($availableSpace < 0 && $expiration->isExpired($node->getMTime(), true)) {
|
||||
$tmp = self::delete($node->getName(), $user->getUID(), $node->getMTime());
|
||||
Server::get(LoggerInterface::class)->info(
|
||||
'remove "' . $node->getName() . '" (' . $tmp . 'B) to meet the limit of trash bin size (50% of available quota) for user "{user}"',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $user,
|
||||
]
|
||||
);
|
||||
$availableSpace += $tmp;
|
||||
$size += $tmp;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete files older then max storage time
|
||||
*
|
||||
|
|
@ -1108,18 +1022,6 @@ class Trashbin implements IEventListener {
|
|||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current size of trash bin from a given user
|
||||
*
|
||||
* @param string $user user who owns the trash bin
|
||||
* @return int|float trash bin size
|
||||
*/
|
||||
private static function getTrashbinSize(string $user): int|float {
|
||||
$view = new View('/' . $user);
|
||||
$fileInfo = $view->getFileInfo('/files_trashbin');
|
||||
return isset($fileInfo['size']) ? $fileInfo['size'] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if trash bin is empty for a given user
|
||||
*
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\Files_Trashbin\Tests\BackgroundJob;
|
||||
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Files_Trashbin\BackgroundJob\ExpireTrash;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\BackgroundJob\IJobList;
|
||||
use OCP\IAppConfig;
|
||||
|
|
@ -23,6 +25,8 @@ class ExpireTrashTest extends TestCase {
|
|||
private IAppConfig&MockObject $appConfig;
|
||||
private IUserManager&MockObject $userManager;
|
||||
private Expiration&MockObject $expiration;
|
||||
private ExpireService&MockObject $expireService;
|
||||
private SetupManager&MockObject $setupManager;
|
||||
private IJobList&MockObject $jobList;
|
||||
private LoggerInterface&MockObject $logger;
|
||||
private ITimeFactory&MockObject $time;
|
||||
|
|
@ -35,6 +39,8 @@ class ExpireTrashTest extends TestCase {
|
|||
$this->expiration = $this->createMock(Expiration::class);
|
||||
$this->jobList = $this->createMock(IJobList::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->expireService = $this->createMock(ExpireService::class);
|
||||
$this->setupManager = $this->createMock(SetupManager::class);
|
||||
|
||||
$this->time = $this->createMock(ITimeFactory::class);
|
||||
$this->time->method('getTime')
|
||||
|
|
@ -54,7 +60,7 @@ class ExpireTrashTest extends TestCase {
|
|||
->with('files_trashbin', 'background_job_expire_trash_offset', 0)
|
||||
->willReturn(0);
|
||||
|
||||
$job = new ExpireTrash($this->appConfig, $this->userManager, $this->expiration, $this->logger, $this->time);
|
||||
$job = new ExpireTrash($this->appConfig, $this->userManager, $this->expiration, $this->expireService, $this->setupManager, $this->logger, $this->time);
|
||||
$job->start($this->jobList);
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +71,7 @@ class ExpireTrashTest extends TestCase {
|
|||
$this->expiration->expects($this->never())
|
||||
->method('getMaxAgeAsTimestamp');
|
||||
|
||||
$job = new ExpireTrash($this->appConfig, $this->userManager, $this->expiration, $this->logger, $this->time);
|
||||
$job = new ExpireTrash($this->appConfig, $this->userManager, $this->expiration, $this->expireService, $this->setupManager, $this->logger, $this->time);
|
||||
$job->start($this->jobList);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@
|
|||
*/
|
||||
namespace OCA\Files_Trashbin\Tests\Command;
|
||||
|
||||
use OC\Files\SetupManager;
|
||||
use OCA\Files_Trashbin\Command\ExpireTrash;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Helper;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\Files\Node;
|
||||
use OCP\IConfig;
|
||||
|
|
@ -30,11 +33,14 @@ use Test\TestCase;
|
|||
*/
|
||||
class ExpireTrashTest extends TestCase {
|
||||
private Expiration $expiration;
|
||||
private Node $userFolder;
|
||||
private Folder $userFolder;
|
||||
private IRootFolder $rootFolder;
|
||||
private IConfig $config;
|
||||
private IUserManager $userManager;
|
||||
private IUser $user;
|
||||
private ITimeFactory $timeFactory;
|
||||
private ExpireService $expireService;
|
||||
private SetupManager $setupManager;
|
||||
|
||||
|
||||
protected function setUp(): void {
|
||||
|
|
@ -47,10 +53,13 @@ class ExpireTrashTest extends TestCase {
|
|||
|
||||
$userId = self::getUniqueID('user');
|
||||
$this->userManager = Server::get(IUserManager::class);
|
||||
$this->rootFolder = Server::get(IRootFolder::class);
|
||||
$this->user = $this->userManager->createUser($userId, $userId);
|
||||
$this->expireService = Server::get(ExpireService::class);
|
||||
$this->setupManager = Server::get(SetupManager::class);
|
||||
|
||||
$this->loginAsUser($userId);
|
||||
$this->userFolder = Server::get(IRootFolder::class)->getUserFolder($userId);
|
||||
$this->userFolder = $this->rootFolder->getUserFolder($userId);
|
||||
}
|
||||
|
||||
protected function tearDown(): void {
|
||||
|
|
@ -99,9 +108,11 @@ class ExpireTrashTest extends TestCase {
|
|||
->willReturn([$userId]);
|
||||
|
||||
$command = new ExpireTrash(
|
||||
Server::get(LoggerInterface::class),
|
||||
$this->setupManager,
|
||||
$this->rootFolder,
|
||||
Server::get(IUserManager::class),
|
||||
$this->expiration
|
||||
$this->expiration,
|
||||
$this->expireService,
|
||||
);
|
||||
|
||||
$this->invokePrivate($command, 'execute', [$inputInterface, $outputInterface]);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ use OCA\Files_Sharing\AppInfo\Application;
|
|||
use OCA\Files_Trashbin\AppInfo\Application as TrashbinApplication;
|
||||
use OCA\Files_Trashbin\Expiration;
|
||||
use OCA\Files_Trashbin\Helper;
|
||||
use OCA\Files_Trashbin\Service\ExpireService;
|
||||
use OCA\Files_Trashbin\Trashbin;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Utility\ITimeFactory;
|
||||
|
|
@ -177,6 +178,8 @@ class TrashbinTest extends \Test\TestCase {
|
|||
// every second file will get a date in the past so that it will get expired
|
||||
$manipulatedList = $this->manipulateDeleteTime($filesInTrash, $this->trashRoot1, $expiredDate);
|
||||
|
||||
$expireService = Server::get(ExpireService::class);
|
||||
$expireService->
|
||||
$testClass = new TrashbinForTesting();
|
||||
[$sizeOfDeletedFiles, $count] = $testClass->dummyDeleteExpiredFiles($manipulatedList, $expireAt);
|
||||
|
||||
|
|
@ -681,15 +684,6 @@ class TrashbinTest extends \Test\TestCase {
|
|||
// just a dummy class to make protected methods available for testing
|
||||
class TrashbinForTesting extends Trashbin {
|
||||
|
||||
/**
|
||||
* @param FileInfo[] $files
|
||||
* @param integer $limit
|
||||
*/
|
||||
public function dummyDeleteExpiredFiles($files) {
|
||||
// dummy value for $retention_obligation because it is not needed here
|
||||
return parent::deleteExpiredFiles($files, TrashbinTest::TEST_TRASHBIN_USER1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileInfo[] $files
|
||||
* @param integer $availableSpace
|
||||
|
|
|
|||
|
|
@ -351,12 +351,17 @@ class LDAP implements ILDAPWrapper {
|
|||
* @throws \Exception
|
||||
*/
|
||||
private function processLDAPError($resource, string $functionName, int $errorCode, string $errorMsg): void {
|
||||
$this->logger->debug('LDAP error {message} ({code}) after calling {func}', [
|
||||
$args = [
|
||||
'app' => 'user_ldap',
|
||||
'message' => $errorMsg,
|
||||
'code' => $errorCode,
|
||||
'func' => $functionName,
|
||||
]);
|
||||
];
|
||||
if ($errorCode === 1) {
|
||||
$this->logger->warning('LDAP error {message} ({code}) after calling {func}', $args);
|
||||
} else {
|
||||
$this->logger->debug('LDAP error {message} ({code}) after calling {func}', $args);
|
||||
}
|
||||
if ($functionName === 'ldap_get_entries'
|
||||
&& $errorCode === -4) {
|
||||
} elseif ($errorCode === 32) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue