vendor/contao/core-bundle/src/Cron/Cron.php line 119

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of Contao.
  5.  *
  6.  * (c) Leo Feyer
  7.  *
  8.  * @license LGPL-3.0-or-later
  9.  */
  10. namespace Contao\CoreBundle\Cron;
  11. use Contao\CoreBundle\Entity\CronJob as CronJobEntity;
  12. use Contao\CoreBundle\Repository\CronJobRepository;
  13. use Cron\CronExpression;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Psr\Log\LoggerInterface;
  16. class Cron
  17. {
  18.     public const SCOPE_WEB 'web';
  19.     public const SCOPE_CLI 'cli';
  20.     /**
  21.      * @var CronJobRepository
  22.      */
  23.     private $repository;
  24.     /**
  25.      * @var EntityManagerInterface
  26.      */
  27.     private $entityManager;
  28.     /**
  29.      * @var LoggerInterface
  30.      */
  31.     private $logger;
  32.     /**
  33.      * @var array<CronJob>
  34.      */
  35.     private $cronJobs = [];
  36.     public function __construct(CronJobRepository $repositoryEntityManagerInterface $entityManagerLoggerInterface $logger null)
  37.     {
  38.         $this->repository $repository;
  39.         $this->entityManager $entityManager;
  40.         $this->logger $logger;
  41.     }
  42.     public function addCronJob(CronJob $cronjob): void
  43.     {
  44.         $this->cronJobs[] = $cronjob;
  45.     }
  46.     /**
  47.      * Run all the registered Contao cron jobs.
  48.      */
  49.     public function run(string $scope): void
  50.     {
  51.         // Validate scope
  52.         if (self::SCOPE_WEB !== $scope && self::SCOPE_CLI !== $scope) {
  53.             throw new \InvalidArgumentException('Invalid scope "'.$scope.'"');
  54.         }
  55.         /** @var array<CronJob> */
  56.         $cronJobsToBeRun = [];
  57.         $now = new \DateTimeImmutable();
  58.         try {
  59.             // Lock cron table
  60.             $this->repository->lockTable();
  61.             // Go through each cron job
  62.             foreach ($this->cronJobs as $cron) {
  63.                 $interval $cron->getInterval();
  64.                 $name $cron->getName();
  65.                 // Determine the last run date
  66.                 $lastRunDate null;
  67.                 /** @var CronJobEntity|null $lastRunEntity */
  68.                 $lastRunEntity $this->repository->findOneByName($name);
  69.                 if (null !== $lastRunEntity) {
  70.                     $lastRunDate $lastRunEntity->getLastRun();
  71.                 } else {
  72.                     $lastRunEntity = new CronJobEntity($name);
  73.                     $this->entityManager->persist($lastRunEntity);
  74.                 }
  75.                 // Check if the cron should be run
  76.                 $expression CronExpression::factory($interval);
  77.                 if (null !== $lastRunDate && $now $expression->getNextRunDate($lastRunDate)) {
  78.                     continue;
  79.                 }
  80.                 // Update the cron entry
  81.                 $lastRunEntity->setLastRun($now);
  82.                 // Add job to the crons to be run
  83.                 $cronJobsToBeRun[] = $cron;
  84.             }
  85.             $this->entityManager->flush();
  86.         } finally {
  87.             $this->repository->unlockTable();
  88.         }
  89.         // Execute all crons to be run
  90.         foreach ($cronJobsToBeRun as $cron) {
  91.             if (null !== $this->logger) {
  92.                 $this->logger->debug(sprintf('Executing cron job "%s"'$cron->getName()));
  93.             }
  94.             $cron($scope);
  95.         }
  96.     }
  97. }