contacts_events-8.x-1.x-dev/src/Cron/CronBase.php
src/Cron/CronBase.php
<?php namespace Drupal\contacts_events\Cron; use Drupal\Component\Datetime\DateTimePlus; use Drupal\Component\Datetime\Time; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Utility\Error; use Psr\Log\LogLevel; /** * A base class to help with controlling running of cron tasks. */ abstract class CronBase implements CronInterface { /** * The state service. * * @var \Drupal\Core\State\StateInterface */ protected $state; /** * The time service. * * @var \Drupal\Component\Datetime\Time */ protected $time; /** * The logger channel. * * @var \Drupal\Core\Logger\LoggerChannelInterface */ protected $logger; /** * The run interval. * * One of: * - Y: Yearly. * - m: Monthly. * - d: Daily. * - H: Hourly. * - i: Minutely. * * @var string */ protected $runInterval = 'd'; /** * A formatted date/time to run after. * * @var string */ protected $runAfterFormat = 'H:i:s'; /** * The format for the run after date/time or NULL for no restriction. * * Should contain be in the format of self::$runAfterFormat. * * @var string|null */ protected $runAfterTime = NULL; /** * Constructs the cron task. * * @param \Drupal\Core\State\StateInterface $state * The state service. * @param \Drupal\Component\Datetime\Time $time * The time service. * @param \Drupal\Core\Logger\LoggerChannelInterface|null $logger * Optionally, the logger channel. * * @throws \Exception * Thrown if the STATE_LAST_RUN constant is not set. */ public function __construct(StateInterface $state, Time $time, ?LoggerChannelInterface $logger = NULL) { if (!defined(static::class . '::STATE_LAST_RUN') || static::STATE_LAST_RUN === NULL) { throw new \Exception('The STATE_LAST_RUN state key constant must be set.'); } $this->state = $state; $this->time = $time; $this->logger = $logger; } /** * Set the logger. * * @param \Drupal\Core\Logger\LoggerChannelInterface|null $logger * Optionally, the logger channel. * * @return $this */ public function setLogger(LoggerChannelInterface $logger) { $this->logger = $logger; return $this; } /** * {@inheritdoc} */ public function invokeOnSchedule() { if (!$this->scheduledToRun()) { return; } $this->invoke(); } /** * {@inheritdoc} */ public function invoke() { try { $this->doInvoke(); $this->setLastRunTime(); } catch (\Exception $exception) { // Catch any errors and log them, if we have a logger. if ($this->logger) { $message = 'Error executing cron %cron_class: %type: @message in %function (line %line of %file).'; $variables = Error::decodeException($exception); $variables['%cron_class'] = static::class; $this->logger->log(LogLevel::ERROR, $message, $variables); } } } /** * Run the actual task. */ abstract protected function doInvoke(); /** * {@inheritdoc} */ public function scheduledToRun() { // Get our last run day. $last_run = $this->getLastRunTime(); $now = $this->getCurrentTime(); $format = 'Y-m-d H:i:s'; $split_pos = strpos($format, $this->runInterval); if ($split_pos === FALSE) { throw new \Exception('Invalid run interval.'); } $run_format = trim(substr($format, 0, $split_pos + 1), '- '); $after_format = trim(substr($format, $split_pos + 1), '- '); // If we have a last run, check it was before today. if ($last_run) { // If the last run was today (or future), we don't want to run. if ($last_run->format($run_format) >= $now->format($run_format)) { return FALSE; } } // If we have an $after, check that we are after that time. return !isset($this->runAfterTime) || ($now->format($after_format) >= $this->runAfterTime); } /** * Get the current time. * * @return \Drupal\Component\Datetime\DateTimePlus * The current time. */ protected function getCurrentTime() { return DateTimePlus::createFromTimestamp($this->time->getCurrentTime()); } /** * Get the last run time. * * @return \Drupal\Component\Datetime\DateTimePlus|null * The last run time or NULL if never. */ protected function getLastRunTime() { $timestamp = $this->state->get(static::STATE_LAST_RUN); return isset($timestamp) ? DateTimePlus::createFromTimestamp($timestamp) : NULL; } /** * Set the last run time. */ protected function setLastRunTime() { $this->state->set(static::STATE_LAST_RUN, $this->time->getCurrentTime()); } }