[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/dragonmantank/cron-expression/src/Cron/ -> DayOfWeekField.php (source)

   1  <?php
   2  
   3  declare(strict_types=1);
   4  
   5  namespace Cron;
   6  
   7  use DateTimeInterface;
   8  use InvalidArgumentException;
   9  
  10  /**
  11   * Day of week field.  Allows: * / , - ? L #.
  12   *
  13   * Days of the week can be represented as a number 0-7 (0|7 = Sunday)
  14   * or as a three letter string: SUN, MON, TUE, WED, THU, FRI, SAT.
  15   *
  16   * 'L' stands for "last". It allows you to specify constructs such as
  17   * "the last Friday" of a given month.
  18   *
  19   * '#' is allowed for the day-of-week field, and must be followed by a
  20   * number between one and five. It allows you to specify constructs such as
  21   * "the second Friday" of a given month.
  22   */
  23  class DayOfWeekField extends AbstractField
  24  {
  25      /**
  26       * {@inheritdoc}
  27       */
  28      protected $rangeStart = 0;
  29  
  30      /**
  31       * {@inheritdoc}
  32       */
  33      protected $rangeEnd = 7;
  34  
  35      /**
  36       * @var array Weekday range
  37       */
  38      protected $nthRange;
  39  
  40      /**
  41       * {@inheritdoc}
  42       */
  43      protected $literals = [1 => 'MON', 2 => 'TUE', 3 => 'WED', 4 => 'THU', 5 => 'FRI', 6 => 'SAT', 7 => 'SUN'];
  44  
  45      /**
  46       * Constructor
  47       */
  48      public function __construct()
  49      {
  50          $this->nthRange = range(1, 5);
  51          parent::__construct();
  52      }
  53  
  54      /**
  55       * @inheritDoc
  56       */
  57      public function isSatisfiedBy(DateTimeInterface $date, $value, bool $invert): bool
  58      {
  59          if ('?' === $value) {
  60              return true;
  61          }
  62  
  63          // Convert text day of the week values to integers
  64          $value = $this->convertLiterals($value);
  65  
  66          $currentYear = (int) $date->format('Y');
  67          $currentMonth = (int) $date->format('m');
  68          $lastDayOfMonth = (int) $date->format('t');
  69  
  70          // Find out if this is the last specific weekday of the month
  71          if (strpos($value, 'L')) {
  72              $weekday = $this->convertLiterals(substr($value, 0, strpos($value, 'L')));
  73              $weekday %= 7;
  74  
  75              $daysInMonth = (int) $date->format('t');
  76              $remainingDaysInMonth = $daysInMonth - (int) $date->format('d');
  77              return (($weekday === (int) $date->format('w')) && ($remainingDaysInMonth < 7));
  78          }
  79  
  80          // Handle # hash tokens
  81          if (strpos($value, '#')) {
  82              [$weekday, $nth] = explode('#', $value);
  83  
  84              if (!is_numeric($nth)) {
  85                  throw new InvalidArgumentException("Hashed weekdays must be numeric, {$nth} given");
  86              } else {
  87                  $nth = (int) $nth;
  88              }
  89  
  90              // 0 and 7 are both Sunday, however 7 matches date('N') format ISO-8601
  91              if ('0' === $weekday) {
  92                  $weekday = 7;
  93              }
  94  
  95              $weekday = (int) $this->convertLiterals((string) $weekday);
  96  
  97              // Validate the hash fields
  98              if ($weekday < 0 || $weekday > 7) {
  99                  throw new InvalidArgumentException("Weekday must be a value between 0 and 7. {$weekday} given");
 100              }
 101  
 102              if (!\in_array($nth, $this->nthRange, true)) {
 103                  throw new InvalidArgumentException("There are never more than 5 or less than 1 of a given weekday in a month, {$nth} given");
 104              }
 105  
 106              // The current weekday must match the targeted weekday to proceed
 107              if ((int) $date->format('N') !== $weekday) {
 108                  return false;
 109              }
 110  
 111              $tdate = clone $date;
 112              $tdate = $tdate->setDate($currentYear, $currentMonth, 1);
 113              $dayCount = 0;
 114              $currentDay = 1;
 115              while ($currentDay < $lastDayOfMonth + 1) {
 116                  if ((int) $tdate->format('N') === $weekday) {
 117                      if (++$dayCount >= $nth) {
 118                          break;
 119                      }
 120                  }
 121                  $tdate = $tdate->setDate($currentYear, $currentMonth, ++$currentDay);
 122              }
 123  
 124              return (int) $date->format('j') === $currentDay;
 125          }
 126  
 127          // Handle day of the week values
 128          if (false !== strpos($value, '-')) {
 129              $parts = explode('-', $value);
 130              if ('7' === $parts[0]) {
 131                  $parts[0] = 0;
 132              } elseif ('0' === $parts[1]) {
 133                  $parts[1] = 7;
 134              }
 135              $value = implode('-', $parts);
 136          }
 137  
 138          // Test to see which Sunday to use -- 0 == 7 == Sunday
 139          $format = \in_array(7, array_map(function ($value) {
 140              return (int) $value;
 141          }, str_split($value)), true) ? 'N' : 'w';
 142          $fieldValue = (int) $date->format($format);
 143  
 144          return $this->isSatisfied($fieldValue, $value);
 145      }
 146  
 147      /**
 148       * @inheritDoc
 149       */
 150      public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface
 151      {
 152          if (! $invert) {
 153              $date = $date->add(new \DateInterval('P1D'));
 154              $date = $date->setTime(0, 0);
 155          } else {
 156              $date = $date->sub(new \DateInterval('P1D'));
 157              $date = $date->setTime(23, 59);
 158          }
 159  
 160          return $this;
 161      }
 162  
 163      /**
 164       * {@inheritdoc}
 165       */
 166      public function validate(string $value): bool
 167      {
 168          $basicChecks = parent::validate($value);
 169  
 170          if (!$basicChecks) {
 171              if ('?' === $value) {
 172                  return true;
 173              }
 174  
 175              // Handle the # value
 176              if (false !== strpos($value, '#')) {
 177                  $chunks = explode('#', $value);
 178                  $chunks[0] = $this->convertLiterals($chunks[0]);
 179  
 180                  if (parent::validate($chunks[0]) && is_numeric($chunks[1]) && \in_array((int) $chunks[1], $this->nthRange, true)) {
 181                      return true;
 182                  }
 183              }
 184  
 185              if (preg_match('/^(.*)L$/', $value, $matches)) {
 186                  return $this->validate($matches[1]);
 187              }
 188  
 189              return false;
 190          }
 191  
 192          return $basicChecks;
 193      }
 194  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer