setName('trashbin:cleanup') ->setDescription('Remove deleted files') ->addArgument( 'user_id', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'remove deleted files of the given user(s)' ) ->addOption( 'all-users', null, InputOption::VALUE_NONE, 'run action on all users' ); } protected function execute(InputInterface $input, OutputInterface $output): int { $userIds = $input->getArgument('user_id'); $verbose = $input->getOption('verbose'); if (!empty($userIds) && $input->getOption('all-users')) { throw new InvalidOptionException('Either specify a user_id or --all-users'); } elseif (!empty($userIds)) { foreach ($userIds as $userId) { $user = $this->userManager->get($userId); if ($user) { $output->writeln("Remove deleted files of $userId"); $this->removeDeletedFiles($user, $output, $verbose); } else { $output->writeln("Unknown user $userId"); return 1; } } } elseif ($input->getOption('all-users')) { $output->writeln('Remove deleted files for all users'); foreach ($this->userManager->getBackends() as $backend) { $name = get_class($backend); if ($backend instanceof IUserBackend) { $name = $backend->getBackendName(); } $output->writeln("Remove deleted files for users on backend $name"); $limit = 500; $offset = 0; do { $userIds = $backend->getUsers('', $limit, $offset); foreach ($userIds as $userId) { $output->writeln(" $userId"); $user = new LazyUser($userId, $this->userManager, null, $backend); $this->removeDeletedFiles($user, $output, $verbose); } $offset += $limit; } while (count($userIds) >= $limit); } } else { throw new InvalidOptionException('Either specify a user_id or --all-users'); } return 0; } /** * Remove deleted files for the given user. */ protected function removeDeletedFiles(IUser $user, OutputInterface $output, bool $verbose): void { $this->setupManager->tearDown(); $this->setupManager->setupForUser($user); $path = '/' . $user->getUID() . '/files_trashbin'; try { $node = $this->rootFolder->get($path); } catch (NotFoundException|NotPermittedException) { if ($verbose) { $output->writeln("No trash found for {$user->getUID()}"); } return; } if ($verbose) { $output->writeln('Deleting ' . Util::humanFileSize($node->getSize()) . " in trash for {$user->getUID()}."); } $node->delete(); if ($this->rootFolder->nodeExists($path)) { $output->writeln('Trash folder sill exists after attempting to delete it'); return; } $query = $this->dbConnection->getQueryBuilder(); $query->delete('files_trash') ->where($query->expr()->eq('user', $query->createParameter('uid'))) ->setParameter('uid', $user->getUID()); $query->executeStatement(); } }