[ 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 DateTime; 8 use DateTimeInterface; 9 10 /** 11 * Day of month field. Allows: * , / - ? L W. 12 * 13 * 'L' stands for "last" and specifies the last day of the month. 14 * 15 * The 'W' character is used to specify the weekday (Monday-Friday) nearest the 16 * given day. As an example, if you were to specify "15W" as the value for the 17 * day-of-month field, the meaning is: "the nearest weekday to the 15th of the 18 * month". So if the 15th is a Saturday, the trigger will fire on Friday the 19 * 14th. If the 15th is a Sunday, the trigger will fire on Monday the 16th. If 20 * the 15th is a Tuesday, then it will fire on Tuesday the 15th. However if you 21 * specify "1W" as the value for day-of-month, and the 1st is a Saturday, the 22 * trigger will fire on Monday the 3rd, as it will not 'jump' over the boundary 23 * of a month's days. The 'W' character can only be specified when the 24 * day-of-month is a single day, not a range or list of days. 25 * 26 * @author Michael Dowling <[email protected]> 27 */ 28 class DayOfMonthField extends AbstractField 29 { 30 /** 31 * {@inheritdoc} 32 */ 33 protected $rangeStart = 1; 34 35 /** 36 * {@inheritdoc} 37 */ 38 protected $rangeEnd = 31; 39 40 /** 41 * Get the nearest day of the week for a given day in a month. 42 * 43 * @param int $currentYear Current year 44 * @param int $currentMonth Current month 45 * @param int $targetDay Target day of the month 46 * 47 * @return \DateTime|null Returns the nearest date 48 */ 49 private static function getNearestWeekday(int $currentYear, int $currentMonth, int $targetDay): ?DateTime 50 { 51 $tday = str_pad((string) $targetDay, 2, '0', STR_PAD_LEFT); 52 $target = DateTime::createFromFormat('Y-m-d', "$currentYear}-$currentMonth}-$tday}"); 53 54 if ($target === false) { 55 return null; 56 } 57 58 $currentWeekday = (int) $target->format('N'); 59 60 if ($currentWeekday < 6) { 61 return $target; 62 } 63 64 $lastDayOfMonth = $target->format('t'); 65 foreach ([-1, 1, -2, 2] as $i) { 66 $adjusted = $targetDay + $i; 67 if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) { 68 $target->setDate($currentYear, $currentMonth, $adjusted); 69 70 if ((int) $target->format('N') < 6 && (int) $target->format('m') === $currentMonth) { 71 return $target; 72 } 73 } 74 } 75 76 return null; 77 } 78 79 /** 80 * {@inheritdoc} 81 */ 82 public function isSatisfiedBy(DateTimeInterface $date, $value, bool $invert): bool 83 { 84 // ? states that the field value is to be skipped 85 if ('?' === $value) { 86 return true; 87 } 88 89 $fieldValue = $date->format('d'); 90 91 // Check to see if this is the last day of the month 92 if ('L' === $value) { 93 return $fieldValue === $date->format('t'); 94 } 95 96 // Check to see if this is the nearest weekday to a particular value 97 if (strpos($value, 'W')) { 98 // Parse the target day 99 $targetDay = (int) substr($value, 0, strpos($value, 'W')); 100 // Find out if the current day is the nearest day of the week 101 $nearest = self::getNearestWeekday( 102 (int) $date->format('Y'), 103 (int) $date->format('m'), 104 $targetDay 105 ); 106 if ($nearest) { 107 return $date->format('j') === $nearest->format('j'); 108 } 109 110 throw new \RuntimeException('Unable to return nearest weekday'); 111 } 112 113 return $this->isSatisfied((int) $date->format('d'), $value); 114 } 115 116 /** 117 * @inheritDoc 118 * 119 * @param \DateTime|\DateTimeImmutable $date 120 */ 121 public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface 122 { 123 if (! $invert) { 124 $date = $date->add(new \DateInterval('P1D')); 125 $date = $date->setTime(0, 0); 126 } else { 127 $date = $date->sub(new \DateInterval('P1D')); 128 $date = $date->setTime(23, 59); 129 } 130 131 return $this; 132 } 133 134 /** 135 * {@inheritdoc} 136 */ 137 public function validate(string $value): bool 138 { 139 $basicChecks = parent::validate($value); 140 141 // Validate that a list don't have W or L 142 if (false !== strpos($value, ',') && (false !== strpos($value, 'W') || false !== strpos($value, 'L'))) { 143 return false; 144 } 145 146 if (!$basicChecks) { 147 if ('?' === $value) { 148 return true; 149 } 150 151 if ('L' === $value) { 152 return true; 153 } 154 155 if (preg_match('/^(.*)W$/', $value, $matches)) { 156 return $this->validate($matches[1]); 157 } 158 159 return false; 160 } 161 162 return $basicChecks; 163 } 164 }
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 |