nextcloud/core/Command/Preview/Cleanup.php
Carl Schwan 09aea6312b
fix(preview): Don't abort cleanup of previews too early
If we don't find previews in the filecache, this is now normal. Don't
abort and instead delete previews from the new preview table instead.

Signed-off-by: Carl Schwan <carlschwan@kde.org>
2026-06-22 16:35:33 +02:00

107 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Core\Command\Preview;
use OC\Core\Command\Base;
use OC\Preview\PreviewService;
use OCP\DB\Exception;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Cleanup extends Base {
public function __construct(
private IRootFolder $rootFolder,
private LoggerInterface $logger,
private PreviewService $previewService,
) {
parent::__construct();
}
#[\Override]
protected function configure(): void {
$this
->setName('preview:cleanup')
->setDescription('Removes existing preview files');
}
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int {
if ($this->deletePreviewFromFileCacheTable($output) !== 0) {
return 1;
}
return $this->deletePreviewFromPreviewTable($output);
}
/**
* Delete from the new oc_previews table.
*/
private function deletePreviewFromPreviewTable(OutputInterface $output): int {
try {
$this->previewService->deleteAll();
return 0;
} catch (NotPermittedException|Exception $e) {
$this->logger->error("Previews can't be removed: exception occurred: " . $e->getMessage(), ['exception' => $e]);
$output->writeln("Previews can't be removed: " . $e->getMessage() . '. See the logs for more details.');
return 1;
}
}
/**
* Legacy in case there are still previews stored there.
*/
private function deletePreviewFromFileCacheTable(OutputInterface $output): int {
try {
$appDataFolder = $this->rootFolder->get($this->rootFolder->getAppDataDirectoryName());
if (!$appDataFolder instanceof Folder) {
$this->logger->error("Previews can't be removed: appdata is not a folder");
$output->writeln("Previews can't be removed: appdata is not a folder");
return 1;
}
/** @var Folder $previewFolder */
$previewFolder = $appDataFolder->get('preview');
} catch (NotFoundException $e) {
$this->logger->info("Legacy previews can't be removed: appdata folder can't be found", ['exception' => $e]);
return 0;
}
if (!$previewFolder->isDeletable()) {
$this->logger->error("Previews can't be removed: preview folder isn't deletable");
$output->writeln("Previews can't be removed: preview folder isn't deletable");
return 1;
}
try {
$previewFolder->delete();
$this->logger->debug('Preview folder deleted');
$output->writeln('Preview folder deleted', OutputInterface::VERBOSITY_VERBOSE);
} catch (NotFoundException $e) {
$output->writeln("Previews weren't deleted: preview folder was not found while deleting it");
$this->logger->error("Previews weren't deleted: preview folder was not found while deleting it", ['exception' => $e]);
return 1;
} catch (NotPermittedException $e) {
$output->writeln("Previews weren't deleted: you don't have the permission to delete preview folder");
$this->logger->error("Previews weren't deleted: you don't have the permission to delete preview folder", ['exception' => $e]);
return 1;
}
$output->writeln('Previews removed');
return 0;
}
}