CleanUp.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\Files_Trashbin\Command;
  8. use OCP\Files\IRootFolder;
  9. use OCP\IDBConnection;
  10. use OCP\IUserBackend;
  11. use OCP\IUserManager;
  12. use Symfony\Component\Console\Command\Command;
  13. use Symfony\Component\Console\Exception\InvalidOptionException;
  14. use Symfony\Component\Console\Input\InputArgument;
  15. use Symfony\Component\Console\Input\InputInterface;
  16. use Symfony\Component\Console\Input\InputOption;
  17. use Symfony\Component\Console\Output\OutputInterface;
  18. class CleanUp extends Command {
  19. public function __construct(
  20. protected IRootFolder $rootFolder,
  21. protected IUserManager $userManager,
  22. protected IDBConnection $dbConnection,
  23. ) {
  24. parent::__construct();
  25. }
  26. protected function configure() {
  27. $this
  28. ->setName('trashbin:cleanup')
  29. ->setDescription('Remove deleted files')
  30. ->addArgument(
  31. 'user_id',
  32. InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
  33. 'remove deleted files of the given user(s)'
  34. )
  35. ->addOption(
  36. 'all-users',
  37. null,
  38. InputOption::VALUE_NONE,
  39. 'run action on all users'
  40. );
  41. }
  42. protected function execute(InputInterface $input, OutputInterface $output): int {
  43. $users = $input->getArgument('user_id');
  44. $verbose = $input->getOption('verbose');
  45. if ((!empty($users)) and ($input->getOption('all-users'))) {
  46. throw new InvalidOptionException('Either specify a user_id or --all-users');
  47. } elseif (!empty($users)) {
  48. foreach ($users as $user) {
  49. if ($this->userManager->userExists($user)) {
  50. $output->writeln("Remove deleted files of <info>$user</info>");
  51. $this->removeDeletedFiles($user, $output, $verbose);
  52. } else {
  53. $output->writeln("<error>Unknown user $user</error>");
  54. return 1;
  55. }
  56. }
  57. } elseif ($input->getOption('all-users')) {
  58. $output->writeln('Remove deleted files for all users');
  59. foreach ($this->userManager->getBackends() as $backend) {
  60. $name = get_class($backend);
  61. if ($backend instanceof IUserBackend) {
  62. $name = $backend->getBackendName();
  63. }
  64. $output->writeln("Remove deleted files for users on backend <info>$name</info>");
  65. $limit = 500;
  66. $offset = 0;
  67. do {
  68. $users = $backend->getUsers('', $limit, $offset);
  69. foreach ($users as $user) {
  70. $output->writeln(" <info>$user</info>");
  71. $this->removeDeletedFiles($user, $output, $verbose);
  72. }
  73. $offset += $limit;
  74. } while (count($users) >= $limit);
  75. }
  76. } else {
  77. throw new InvalidOptionException('Either specify a user_id or --all-users');
  78. }
  79. return 0;
  80. }
  81. /**
  82. * remove deleted files for the given user
  83. */
  84. protected function removeDeletedFiles(string $uid, OutputInterface $output, bool $verbose): void {
  85. \OC_Util::tearDownFS();
  86. \OC_Util::setupFS($uid);
  87. $path = '/' . $uid . '/files_trashbin';
  88. if ($this->rootFolder->nodeExists($path)) {
  89. $node = $this->rootFolder->get($path);
  90. if ($verbose) {
  91. $output->writeln('Deleting <info>' . \OC_Helper::humanFileSize($node->getSize()) . "</info> in trash for <info>$uid</info>.");
  92. }
  93. $node->delete();
  94. if ($this->rootFolder->nodeExists($path)) {
  95. $output->writeln('<error>Trash folder sill exists after attempting to delete it</error>');
  96. return;
  97. }
  98. $query = $this->dbConnection->getQueryBuilder();
  99. $query->delete('files_trash')
  100. ->where($query->expr()->eq('user', $query->createParameter('uid')))
  101. ->setParameter('uid', $uid);
  102. $query->executeStatement();
  103. } else {
  104. if ($verbose) {
  105. $output->writeln("No trash found for <info>$uid</info>");
  106. }
  107. }
  108. }
  109. }