[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |