| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- <?php
- namespace App\Service\Cron\Job;
- use App\Repository\Access\AccessRepository;
- use App\Repository\Core\FileRepository;
- use App\Service\Cron\BaseCronJob;
- use App\Service\Cron\CronjobInterface;
- use App\Service\Storage\LocalStorage;
- use Doctrine\Common\Collections\Collection;
- use Doctrine\Common\Collections\Criteria;
- use Doctrine\ORM\EntityManagerInterface;
- use JetBrains\PhpStorm\Pure;
- /**
- * Cronjob that delete temporary files older than N days
- */
- class CleanTempFiles extends BaseCronJob implements CronjobInterface
- {
- /**
- * Delay before removing a temporary file (in days)
- */
- private const DELETE_OLDER_THAN = 7;
- /**
- * ID of the Access who author the file deletion
- */
- private const AUTHOR = 10984;
- /**
- * Delay before deleting the record of the temporary file from the DB
- */
- private const PURGE_RECORDS_OLDER_THAN = 365;
- /**
- * @param FileRepository $fileRepository
- * @param EntityManagerInterface $em
- * @param AccessRepository $accessRepository
- * @param LocalStorage $storage
- */
- #[Pure]
- public function __construct(
- private FileRepository $fileRepository,
- private EntityManagerInterface $em,
- private AccessRepository $accessRepository,
- private LocalStorage $storage
- ) {
- parent::__construct();
- }
- /**
- * Preview the result of the execution, without actually deleting anything
- */
- public function preview(): void
- {
- $files = $this->listFilesToDelete();
- $total = count($files);
- $this->ui->print($total . " temporary files to be removed");
- $this->ui->print("> Printing the first and last 50 :");
- $i = 0;
- foreach ($files as $file) {
- $i++;
- if ($i > 50 && ($total - $i) > 50) { continue; }
- if (($total - $i) === 50) {
- $this->ui->print(' (...)');
- }
- $this->ui->print(' * ' . $file->getPath());
- }
- $this->purgeDb(false);
- }
- /**
- * Proceed to the deletion of the files and the purge of the DB
- */
- public function execute(): void
- {
- $files = $this->listFilesToDelete();
- $this->deleteFiles($files);
- $this->purgeDb();
- }
- /**
- * List the files to delete in the DB
- *
- * @return Collection
- * @throws \Exception
- */
- private function listFilesToDelete(): Collection {
- $maxDate = new \DateTime(self::DELETE_OLDER_THAN . ' days ago');
- $this->ui->print('List temporary files created before ' . $maxDate->format('c'));
- $criteria = new Criteria();
- $criteria->where(
- Criteria::expr()?->andX(
- Criteria::expr()?->eq('isTemporaryFile', 1),
- Criteria::expr()?->orX(
- Criteria::expr()?->lt('createDate', $maxDate),
- Criteria::expr()?->isNull('createDate')
- )
- )
- );
- return $this->fileRepository->matching($criteria);
- }
- /**
- * Delete the files
- *
- * @param Collection $files
- */
- private function deleteFiles(Collection $files): void {
- $total = count($files);
- $this->ui->print($total . " temporary files to be removed");
- $author = $this->accessRepository->find(self::AUTHOR);
- if ($author === null) {
- throw new \RuntimeException('Access ' . self::AUTHOR . ' could not be found');
- }
- $this->ui->print('Deleting files...');
- $i = 0;
- $this->ui->progress(0, $total);
- foreach ($files as $file) {
- try {
- $i++;
- $this->ui->progress($i, $total);
- $this->storage->delete($file, $author);
- } catch (\RuntimeException $e) {
- $this->ui->print('ERROR : ' . $e->getMessage());
- }
- }
- $this->ui->print($i . ' files deleted');
- }
- /**
- * Purge the DB from temporary file records older than N days
- *
- * @param bool $commit
- * @throws \Exception
- */
- private function purgeDb(bool $commit = true): void {
- $maxDate = new \DateTime(self::PURGE_RECORDS_OLDER_THAN . ' days ago');
- $this->ui->print('Purge DB from records of files deleted before ' . $maxDate->format('c'));
- $this->em->beginTransaction();
- $queryBuilder = $this->em->createQueryBuilder();
- $q = $queryBuilder
- ->delete('File', 'f')
- ->where($queryBuilder->expr()->eq('f.isTemporaryFile', 1))
- ->andWhere($queryBuilder->expr()->lt('f.updateDate', ':maxDate'))
- ->setParameter('maxDate', $maxDate)
- ->getQuery();
- $purged = $q->getResult();
- if ($commit) {
- $this->em->commit();
- $this->ui->print('DB purged - ' . $purged . ' records permanently deleted');
- return;
- }
- $this->em->rollback();
- $this->ui->print('DB purged - ' . $purged . ' records would be permanently deleted');
- }
- }
|