PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.36.0
MailPoet – Newsletters, Email Marketing, and Automation v5.36.0
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor / dragonmantank / cron-expression / src / Cron / AbstractField.php
mailpoet / vendor / dragonmantank / cron-expression / src / Cron Last commit date
AbstractField.php 1 year ago CronExpression.php 8 months ago DayOfMonthField.php 1 year ago DayOfWeekField.php 1 year ago FieldFactory.php 1 year ago FieldFactoryInterface.php 1 year ago FieldInterface.php 1 year ago HoursField.php 1 year ago MinutesField.php 1 year ago MonthField.php 1 year ago index.php 1 year ago
AbstractField.php
205 lines
1 <?php
2 declare(strict_types=1);
3 namespace Cron;
4 if (!defined('ABSPATH')) exit;
5 use DateTimeInterface;
6 abstract class AbstractField implements FieldInterface
7 {
8 protected $fullRange = [];
9 protected $literals = [];
10 protected $rangeStart;
11 protected $rangeEnd;
12 public function __construct()
13 {
14 $this->fullRange = range($this->rangeStart, $this->rangeEnd);
15 }
16 public function isSatisfied(int $dateValue, string $value): bool
17 {
18 if ($this->isIncrementsOfRanges($value)) {
19 return $this->isInIncrementsOfRanges($dateValue, $value);
20 }
21 if ($this->isRange($value)) {
22 return $this->isInRange($dateValue, $value);
23 }
24 return '*' === $value || $dateValue === (int) $value;
25 }
26 public function isRange(string $value): bool
27 {
28 return false !== strpos($value, '-');
29 }
30 public function isIncrementsOfRanges(string $value): bool
31 {
32 return false !== strpos($value, '/');
33 }
34 public function isInRange(int $dateValue, $value): bool
35 {
36 $parts = array_map(
37 function ($value) {
38 $value = trim($value);
39 return $this->convertLiterals($value);
40 },
41 explode('-', $value, 2)
42 );
43 return $dateValue >= $parts[0] && $dateValue <= $parts[1];
44 }
45 public function isInIncrementsOfRanges(int $dateValue, string $value): bool
46 {
47 $chunks = array_map('trim', explode('/', $value, 2));
48 $range = $chunks[0];
49 $step = $chunks[1] ?? 0;
50 // No step or 0 steps aren't cool
51 if (null === $step || '0' === $step || 0 === $step) {
52 return false;
53 }
54 // Expand the * to a full range
55 if ('*' === $range) {
56 $range = $this->rangeStart . '-' . $this->rangeEnd;
57 }
58 // Generate the requested small range
59 $rangeChunks = explode('-', $range, 2);
60 $rangeStart = (int) $rangeChunks[0];
61 $rangeEnd = $rangeChunks[1] ?? $rangeStart;
62 $rangeEnd = (int) $rangeEnd;
63 if ($rangeStart < $this->rangeStart || $rangeStart > $this->rangeEnd || $rangeStart > $rangeEnd) {
64 throw new \OutOfRangeException('Invalid range start requested');
65 }
66 if ($rangeEnd < $this->rangeStart || $rangeEnd > $this->rangeEnd || $rangeEnd < $rangeStart) {
67 throw new \OutOfRangeException('Invalid range end requested');
68 }
69 // Steps larger than the range need to wrap around and be handled
70 // slightly differently than smaller steps
71 // UPDATE - This is actually false. The C implementation will allow a
72 // larger step as valid syntax, it never wraps around. It will stop
73 // once it hits the end. Unfortunately this means in future versions
74 // we will not wrap around. However, because the logic exists today
75 // per the above documentation, fixing the bug from #89
76 if ($step > $this->rangeEnd) {
77 $thisRange = [$this->fullRange[$step % \count($this->fullRange)]];
78 } else {
79 if ($step > ($rangeEnd - $rangeStart)) {
80 $thisRange[$rangeStart] = (int) $rangeStart;
81 } else {
82 $thisRange = range($rangeStart, $rangeEnd, (int) $step);
83 }
84 }
85 return \in_array($dateValue, $thisRange, true);
86 }
87 public function getRangeForExpression(string $expression, int $max): array
88 {
89 $values = [];
90 $expression = $this->convertLiterals($expression);
91 if (false !== strpos($expression, ',')) {
92 $ranges = explode(',', $expression);
93 $values = [];
94 foreach ($ranges as $range) {
95 $expanded = $this->getRangeForExpression($range, $this->rangeEnd);
96 $values = array_merge($values, $expanded);
97 }
98 return $values;
99 }
100 if ($this->isRange($expression) || $this->isIncrementsOfRanges($expression)) {
101 if (!$this->isIncrementsOfRanges($expression)) {
102 [$offset, $to] = explode('-', $expression);
103 $offset = $this->convertLiterals($offset);
104 $to = $this->convertLiterals($to);
105 $stepSize = 1;
106 } else {
107 $range = array_map('trim', explode('/', $expression, 2));
108 $stepSize = $range[1] ?? 0;
109 $range = $range[0];
110 $range = explode('-', $range, 2);
111 $offset = $range[0];
112 $to = $range[1] ?? $max;
113 }
114 $offset = '*' === $offset ? $this->rangeStart : $offset;
115 if ($stepSize >= $this->rangeEnd) {
116 $values = [$this->fullRange[$stepSize % \count($this->fullRange)]];
117 } else {
118 for ($i = $offset; $i <= $to; $i += $stepSize) {
119 $values[] = (int) $i;
120 }
121 }
122 sort($values);
123 } else {
124 $values = [$expression];
125 }
126 return $values;
127 }
128 protected function convertLiterals(string $value): string
129 {
130 if (\count($this->literals)) {
131 $key = array_search(strtoupper($value), $this->literals, true);
132 if (false !== $key) {
133 return (string) $key;
134 }
135 }
136 return $value;
137 }
138 public function validate(string $value): bool
139 {
140 $value = $this->convertLiterals($value);
141 // All fields allow * as a valid value
142 if ('*' === $value) {
143 return true;
144 }
145 // Validate each chunk of a list individually
146 if (false !== strpos($value, ',')) {
147 foreach (explode(',', $value) as $listItem) {
148 if (!$this->validate($listItem)) {
149 return false;
150 }
151 }
152 return true;
153 }
154 if (false !== strpos($value, '/')) {
155 [$range, $step] = explode('/', $value);
156 // Don't allow numeric ranges
157 if (is_numeric($range)) {
158 return false;
159 }
160 return $this->validate($range) && filter_var($step, FILTER_VALIDATE_INT);
161 }
162 if (false !== strpos($value, '-')) {
163 if (substr_count($value, '-') > 1) {
164 return false;
165 }
166 $chunks = explode('-', $value);
167 $chunks[0] = $this->convertLiterals($chunks[0]);
168 $chunks[1] = $this->convertLiterals($chunks[1]);
169 if ('*' === $chunks[0] || '*' === $chunks[1]) {
170 return false;
171 }
172 return $this->validate($chunks[0]) && $this->validate($chunks[1]);
173 }
174 if (!is_numeric($value)) {
175 return false;
176 }
177 if (false !== strpos($value, '.')) {
178 return false;
179 }
180 // We should have a numeric by now, so coerce this into an integer
181 $value = (int) $value;
182 return \in_array($value, $this->fullRange, true);
183 }
184 protected function timezoneSafeModify(DateTimeInterface $dt, string $modification): DateTimeInterface
185 {
186 $timezone = $dt->getTimezone();
187 $dt = $dt->setTimezone(new \DateTimeZone("UTC"));
188 $dt = $dt->modify($modification);
189 $dt = $dt->setTimezone($timezone);
190 return $dt;
191 }
192 protected function setTimeHour(DateTimeInterface $date, bool $invert, int $originalTimestamp): DateTimeInterface
193 {
194 $date = $date->setTime((int)$date->format('H'), ($invert ? 59 : 0));
195 // setTime caused the offset to change, moving time in the wrong direction
196 $actualTimestamp = $date->format('U');
197 if ((! $invert) && ($actualTimestamp <= $originalTimestamp)) {
198 $date = $this->timezoneSafeModify($date, "+1 hour");
199 } elseif ($invert && ($actualTimestamp >= $originalTimestamp)) {
200 $date = $this->timezoneSafeModify($date, "-1 hour");
201 }
202 return $date;
203 }
204 }
205