Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
99.34% |
303 / 305 |
|
96.08% |
49 / 51 |
CRAP | |
0.00% |
0 / 1 |
Cron | |
99.34% |
303 / 305 |
|
96.08% |
49 / 51 |
135 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
create | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setBuffer | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getBuffer | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasSeconds | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getSeconds | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMinutes | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getHours | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDaysOfTheMonth | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMonths | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDaysOfTheWeek | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
schedule | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
getSchedule | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasSchedule | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
updateSchedule | |
96.55% |
28 / 29 |
|
0.00% |
0 / 1 |
14 | |||
everySecond | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
every5Seconds | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
every10Seconds | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
every15Seconds | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
every20Seconds | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
every30Seconds | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
seconds | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
4 | |||
everyMinute | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
every5Minutes | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
every10Minutes | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
every15Minutes | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
every20Minutes | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
every30Minutes | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
minutes | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
hours | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
5 | |||
hourly | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
daily | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
dailyAt | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
weekly | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
monthly | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
quarterly | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
yearly | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
5 | |||
weekdays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
weekends | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
sundays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
mondays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
tuesdays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
wednesdays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
thursdays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
fridays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
saturdays | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
between | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
render | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
evaluate | |
100.00% |
47 / 47 |
|
100.00% |
1 / 1 |
43 | |||
__toString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
evaluateExpression | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
5.03 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Queue\Process; |
15 | |
16 | /** |
17 | * Cron class |
18 | * |
19 | * @category Pop |
20 | * @package Pop\Queue |
21 | * @author Nick Sagona, III <dev@nolainteractive.com> |
22 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
23 | * @license http://www.popphp.org/license New BSD License |
24 | * @version 2.0.0 |
25 | */ |
26 | class Cron |
27 | { |
28 | |
29 | /** |
30 | * Schedule string |
31 | * @var ?string |
32 | */ |
33 | protected ?string $schedule = null; |
34 | |
35 | /** |
36 | * Seconds |
37 | * - Not a standard cron unit of time. The smallest time interval supported by cron is 1 minute. |
38 | * This is to support time intervals less than minute and down to 1 second. |
39 | * @var array |
40 | */ |
41 | protected array $seconds = []; |
42 | |
43 | /** |
44 | * Minutes |
45 | * @var array |
46 | */ |
47 | protected array $minutes = []; |
48 | |
49 | /** |
50 | * Hours |
51 | * @var array |
52 | */ |
53 | protected array $hours = []; |
54 | |
55 | /** |
56 | * Days of the month |
57 | * @var array |
58 | */ |
59 | protected array $daysOfTheMonth = []; |
60 | |
61 | /** |
62 | * Months |
63 | * @var array |
64 | */ |
65 | protected array $months = []; |
66 | |
67 | /** |
68 | * Days of the week |
69 | * @var array |
70 | */ |
71 | protected array $daysOfTheWeek = []; |
72 | |
73 | /** |
74 | * Time buffer |
75 | * @var int |
76 | */ |
77 | protected int $buffer = 0; |
78 | |
79 | /** |
80 | * Constructor |
81 | * |
82 | * Instantiate the cron object |
83 | * |
84 | * @param ?string $schedule |
85 | * @param int $buffer |
86 | */ |
87 | public function __construct(?string $schedule = null, int $buffer = 0) |
88 | { |
89 | if ($schedule !== null) { |
90 | $this->schedule($schedule); |
91 | } |
92 | $this->setBuffer($buffer); |
93 | } |
94 | |
95 | /** |
96 | * Factory |
97 | * |
98 | * @param ?string $schedule |
99 | * @return Cron |
100 | */ |
101 | public static function create(?string $schedule = null): Cron |
102 | { |
103 | return new self($schedule); |
104 | } |
105 | |
106 | /** |
107 | * Set buffer |
108 | * |
109 | * @param int $buffer |
110 | * @return Cron |
111 | */ |
112 | public function setBuffer(int $buffer): Cron |
113 | { |
114 | $this->buffer = $buffer; |
115 | return $this; |
116 | } |
117 | |
118 | /** |
119 | * Get buffer |
120 | * |
121 | * @return int |
122 | */ |
123 | public function getBuffer(): int |
124 | { |
125 | return $this->buffer; |
126 | } |
127 | |
128 | /** |
129 | * Has seconds |
130 | * |
131 | * @return bool |
132 | */ |
133 | public function hasSeconds(): bool |
134 | { |
135 | return !empty($this->seconds); |
136 | } |
137 | |
138 | /** |
139 | * Get seconds |
140 | * |
141 | * @return array |
142 | */ |
143 | public function getSeconds(): array |
144 | { |
145 | return $this->seconds; |
146 | } |
147 | |
148 | /** |
149 | * Get minutes |
150 | * |
151 | * @return array |
152 | */ |
153 | public function getMinutes(): array |
154 | { |
155 | return $this->minutes; |
156 | } |
157 | |
158 | /** |
159 | * Get hours |
160 | * |
161 | * @return array |
162 | */ |
163 | public function getHours(): array |
164 | { |
165 | return $this->hours; |
166 | } |
167 | |
168 | /** |
169 | * Get days of the month |
170 | * |
171 | * @return array |
172 | */ |
173 | public function getDaysOfTheMonth(): array |
174 | { |
175 | return $this->daysOfTheMonth; |
176 | } |
177 | |
178 | /** |
179 | * Get months |
180 | * |
181 | * @return array |
182 | */ |
183 | public function getMonths(): array |
184 | { |
185 | return $this->months; |
186 | } |
187 | |
188 | /** |
189 | * Get days of the week |
190 | * |
191 | * @return array |
192 | */ |
193 | public function getDaysOfTheWeek(): array |
194 | { |
195 | return $this->daysOfTheWeek; |
196 | } |
197 | |
198 | /** |
199 | * Set cron schedule |
200 | * |
201 | * min hour dom month dow |
202 | * * * * * * |
203 | * |
204 | * - OR non-standard - |
205 | * |
206 | * sec min hour dom month dow |
207 | * * * * * * * |
208 | * |
209 | * @param string $schedule |
210 | * @return Cron |
211 | */ |
212 | public function schedule(string $schedule): Cron |
213 | { |
214 | $schedule = preg_replace('!\s+!', ' ', trim($schedule)); |
215 | |
216 | if (substr_count($schedule, ' ') >= 4) { |
217 | $this->schedule = $schedule; |
218 | |
219 | if (substr_count($schedule, ' ') == 5) { |
220 | list($sec, $min, $hour, $dom, $month, $dow) = explode(' ', $this->schedule); |
221 | $this->seconds = [$sec]; |
222 | } else { |
223 | list($min, $hour, $dom, $month, $dow) = explode(' ', $this->schedule); |
224 | } |
225 | |
226 | $this->minutes = [$min]; |
227 | $this->hours = [$hour]; |
228 | $this->daysOfTheMonth = [$dom]; |
229 | $this->months = [$month]; |
230 | $this->daysOfTheWeek = [$dow]; |
231 | } |
232 | |
233 | return $this; |
234 | } |
235 | |
236 | /** |
237 | * Get schedule string |
238 | * |
239 | * @return ?string |
240 | */ |
241 | public function getSchedule(): ?string |
242 | { |
243 | return $this->schedule; |
244 | } |
245 | |
246 | /** |
247 | * Has schedule string |
248 | * |
249 | * @return bool |
250 | */ |
251 | public function hasSchedule(): bool |
252 | { |
253 | return ($this->schedule !== null); |
254 | } |
255 | |
256 | /** |
257 | * Update cron schedule |
258 | * @return Cron |
259 | */ |
260 | public function updateSchedule(): Cron |
261 | { |
262 | $schedule = []; |
263 | |
264 | // Minutes |
265 | if (count($this->seconds) > 1) { |
266 | $schedule[] = implode(',', $this->seconds); |
267 | } else if (isset($this->seconds[0])) { |
268 | $schedule[] = $this->seconds[0]; |
269 | } |
270 | |
271 | // Minutes |
272 | if (count($this->minutes) > 1) { |
273 | $schedule[] = implode(',', $this->minutes); |
274 | } else if (isset($this->minutes[0])) { |
275 | $schedule[] = $this->minutes[0]; |
276 | } |
277 | |
278 | // Hours |
279 | if (count($this->hours) > 1) { |
280 | $schedule[] = implode(',', $this->hours); |
281 | } else if (isset($this->hours[0])) { |
282 | $schedule[] = $this->hours[0]; |
283 | } |
284 | |
285 | // DOM |
286 | if (count($this->daysOfTheMonth) > 1) { |
287 | $schedule[] = implode(',', $this->daysOfTheMonth); |
288 | } else if (isset($this->daysOfTheMonth[0])) { |
289 | $schedule[] = $this->daysOfTheMonth[0]; |
290 | } |
291 | |
292 | // Months |
293 | if (count($this->months) > 1) { |
294 | $schedule[] = implode(',', $this->months); |
295 | } else if (isset($this->months[0])) { |
296 | $schedule[] = $this->months[0]; |
297 | } |
298 | |
299 | // DOW |
300 | if (count($this->daysOfTheWeek) > 1) { |
301 | $schedule[] = implode(',', $this->daysOfTheWeek); |
302 | } else if (isset($this->daysOfTheWeek[0])) { |
303 | $schedule[] = $this->daysOfTheWeek[0]; |
304 | } |
305 | |
306 | if (empty($schedule)) { |
307 | throw new Exception('Error: The cron schedule has not been set.'); |
308 | } |
309 | |
310 | $this->schedule = implode(' ', $schedule); |
311 | return $this; |
312 | } |
313 | |
314 | /** |
315 | * Set job schedule to every second |
316 | * |
317 | * @return Cron |
318 | */ |
319 | public function everySecond(): Cron |
320 | { |
321 | $this->seconds = ['*']; |
322 | $this->minutes = ['*']; |
323 | $this->hours = ['*']; |
324 | $this->daysOfTheMonth = ['*']; |
325 | $this->months = ['*']; |
326 | $this->daysOfTheWeek = ['*']; |
327 | |
328 | return $this->updateSchedule(); |
329 | } |
330 | |
331 | /** |
332 | * Set job schedule to every 5 seconds |
333 | * |
334 | * @return Cron |
335 | */ |
336 | public function every5Seconds(): Cron |
337 | { |
338 | $this->seconds = ['*/5']; |
339 | $this->minutes = ['*']; |
340 | $this->hours = ['*']; |
341 | $this->daysOfTheMonth = ['*']; |
342 | $this->months = ['*']; |
343 | $this->daysOfTheWeek = ['*']; |
344 | |
345 | return $this->updateSchedule(); |
346 | } |
347 | |
348 | /** |
349 | * Set job schedule to every 10 seconds |
350 | * |
351 | * @return Cron |
352 | */ |
353 | public function every10Seconds(): Cron |
354 | { |
355 | $this->seconds = ['*/10']; |
356 | $this->minutes = ['*']; |
357 | $this->hours = ['*']; |
358 | $this->daysOfTheMonth = ['*']; |
359 | $this->months = ['*']; |
360 | $this->daysOfTheWeek = ['*']; |
361 | |
362 | return $this->updateSchedule(); |
363 | } |
364 | |
365 | /** |
366 | * Set job schedule to every 15 seconds |
367 | * |
368 | * @return Cron |
369 | */ |
370 | public function every15Seconds(): Cron |
371 | { |
372 | $this->seconds = ['*/15']; |
373 | $this->minutes = ['*']; |
374 | $this->hours = ['*']; |
375 | $this->daysOfTheMonth = ['*']; |
376 | $this->months = ['*']; |
377 | $this->daysOfTheWeek = ['*']; |
378 | |
379 | return $this->updateSchedule(); |
380 | } |
381 | |
382 | /** |
383 | * Set job schedule to every 20 seconds |
384 | * |
385 | * @return Cron |
386 | */ |
387 | public function every20Seconds(): Cron |
388 | { |
389 | $this->seconds = ['*/20']; |
390 | $this->minutes = ['*']; |
391 | $this->hours = ['*']; |
392 | $this->daysOfTheMonth = ['*']; |
393 | $this->months = ['*']; |
394 | $this->daysOfTheWeek = ['*']; |
395 | |
396 | return $this->updateSchedule(); |
397 | } |
398 | |
399 | /** |
400 | * Set job schedule to every 30 seconds |
401 | * |
402 | * @return Cron |
403 | */ |
404 | public function every30Seconds(): Cron |
405 | { |
406 | $this->seconds = ['*/30']; |
407 | $this->minutes = ['*']; |
408 | $this->hours = ['*']; |
409 | $this->daysOfTheMonth = ['*']; |
410 | $this->months = ['*']; |
411 | $this->daysOfTheWeek = ['*']; |
412 | |
413 | return $this->updateSchedule(); |
414 | } |
415 | |
416 | /** |
417 | * Set job schedule to by specific seconds |
418 | * |
419 | * @param mixed $seconds |
420 | * @return Cron |
421 | */ |
422 | public function seconds(mixed $seconds): Cron |
423 | { |
424 | if (is_string($seconds) && (str_contains($seconds, ','))) { |
425 | $seconds = explode(',' , $seconds); |
426 | } else if (is_numeric($seconds)) { |
427 | $seconds = [(int)$seconds]; |
428 | } else { |
429 | $seconds = [$seconds]; |
430 | } |
431 | |
432 | $this->seconds = array_map('trim', $seconds); |
433 | $this->minutes = ['*']; |
434 | $this->hours = ['*']; |
435 | $this->daysOfTheMonth = ['*']; |
436 | $this->months = ['*']; |
437 | $this->daysOfTheWeek = ['*']; |
438 | |
439 | return $this->updateSchedule(); |
440 | } |
441 | |
442 | /** |
443 | * Set job schedule to every minute |
444 | * |
445 | * @return Cron |
446 | */ |
447 | public function everyMinute(): Cron |
448 | { |
449 | $this->minutes = ['*']; |
450 | $this->hours = ['*']; |
451 | $this->daysOfTheMonth = ['*']; |
452 | $this->months = ['*']; |
453 | $this->daysOfTheWeek = ['*']; |
454 | |
455 | return $this->updateSchedule(); |
456 | } |
457 | |
458 | /** |
459 | * Set job schedule to every 5 minutes |
460 | * |
461 | * @return Cron |
462 | */ |
463 | public function every5Minutes(): Cron |
464 | { |
465 | $this->minutes = ['*/5']; |
466 | $this->hours = ['*']; |
467 | $this->daysOfTheMonth = ['*']; |
468 | $this->months = ['*']; |
469 | $this->daysOfTheWeek = ['*']; |
470 | |
471 | return $this->updateSchedule(); |
472 | } |
473 | |
474 | /** |
475 | * Set job schedule to every 10 minutes |
476 | * |
477 | * @return Cron |
478 | */ |
479 | public function every10Minutes(): Cron |
480 | { |
481 | $this->minutes = ['*/10']; |
482 | $this->hours = ['*']; |
483 | $this->daysOfTheMonth = ['*']; |
484 | $this->months = ['*']; |
485 | $this->daysOfTheWeek = ['*']; |
486 | |
487 | return $this->updateSchedule(); |
488 | } |
489 | |
490 | /** |
491 | * Set job schedule to every 15 minutes |
492 | * |
493 | * @return Cron |
494 | */ |
495 | public function every15Minutes(): Cron |
496 | { |
497 | $this->minutes = ['*/15']; |
498 | $this->hours = ['*']; |
499 | $this->daysOfTheMonth = ['*']; |
500 | $this->months = ['*']; |
501 | $this->daysOfTheWeek = ['*']; |
502 | |
503 | return $this->updateSchedule(); |
504 | } |
505 | |
506 | /** |
507 | * Set job schedule to every 20 minutes |
508 | * |
509 | * @return Cron |
510 | */ |
511 | public function every20Minutes(): Cron |
512 | { |
513 | $this->minutes = ['*/20']; |
514 | $this->hours = ['*']; |
515 | $this->daysOfTheMonth = ['*']; |
516 | $this->months = ['*']; |
517 | $this->daysOfTheWeek = ['*']; |
518 | |
519 | return $this->updateSchedule(); |
520 | } |
521 | |
522 | /** |
523 | * Set job schedule to every 30 minutes |
524 | * |
525 | * @return Cron |
526 | */ |
527 | public function every30Minutes(): Cron |
528 | { |
529 | $this->minutes = ['*/30']; |
530 | $this->hours = ['*']; |
531 | $this->daysOfTheMonth = ['*']; |
532 | $this->months = ['*']; |
533 | $this->daysOfTheWeek = ['*']; |
534 | |
535 | return $this->updateSchedule(); |
536 | } |
537 | |
538 | /** |
539 | * Set job schedule to by specific minutes |
540 | * |
541 | * @param mixed $minutes |
542 | * @return Cron |
543 | */ |
544 | public function minutes(mixed $minutes): Cron |
545 | { |
546 | if (is_string($minutes) && (str_contains($minutes, ','))) { |
547 | $minutes = explode(',' , $minutes); |
548 | } else if (is_numeric($minutes)) { |
549 | $minutes = [(int)$minutes]; |
550 | } else { |
551 | $minutes = [$minutes]; |
552 | } |
553 | |
554 | $this->minutes = array_map('trim', $minutes); |
555 | $this->hours = ['*']; |
556 | $this->daysOfTheMonth = ['*']; |
557 | $this->months = ['*']; |
558 | $this->daysOfTheWeek = ['*']; |
559 | |
560 | return $this->updateSchedule(); |
561 | } |
562 | |
563 | /** |
564 | * Set job schedule to by specific hours |
565 | * |
566 | * @param mixed $hours |
567 | * @param mixed $minutes |
568 | * @return Cron |
569 | */ |
570 | public function hours(mixed $hours, mixed $minutes = null): Cron |
571 | { |
572 | if ($minutes !== null) { |
573 | $this->minutes($minutes); |
574 | } else { |
575 | $this->minutes = [0]; |
576 | } |
577 | |
578 | if (is_string($hours) && (str_contains($hours, ','))) { |
579 | $hours = explode(',' , $hours); |
580 | } else if (is_numeric($hours)) { |
581 | $hours = [(int)$hours]; |
582 | } else { |
583 | $hours = [$hours]; |
584 | } |
585 | |
586 | $this->hours = array_map('trim', $hours); |
587 | $this->daysOfTheMonth = ['*']; |
588 | $this->months = ['*']; |
589 | $this->daysOfTheWeek = ['*']; |
590 | |
591 | return $this->updateSchedule(); |
592 | } |
593 | |
594 | /** |
595 | * Set job schedule to hourly |
596 | * |
597 | * @param mixed $minutes |
598 | * @return Cron |
599 | */ |
600 | public function hourly(mixed $minutes = null): Cron |
601 | { |
602 | if ($minutes !== null) { |
603 | $this->minutes($minutes); |
604 | } else { |
605 | $this->minutes = [0]; |
606 | } |
607 | |
608 | $this->hours = ['*']; |
609 | $this->daysOfTheMonth = ['*']; |
610 | $this->months = ['*']; |
611 | $this->daysOfTheWeek = ['*']; |
612 | |
613 | return $this->updateSchedule(); |
614 | } |
615 | |
616 | /** |
617 | * Set job schedule to daily (alias to hours) |
618 | * |
619 | * @param mixed $hours |
620 | * @param mixed $minutes |
621 | * @return Cron |
622 | */ |
623 | public function daily(mixed $hours, mixed $minutes = null): Cron |
624 | { |
625 | return $this->hours($hours, $minutes); |
626 | } |
627 | |
628 | /** |
629 | * Set job schedule to daily at specific time, i.e. 14:30 |
630 | * |
631 | * @param string $time |
632 | * @return Cron |
633 | */ |
634 | public function dailyAt(string $time): Cron |
635 | { |
636 | list($hour, $minute) = explode(':', $time); |
637 | $this->daily($hour, $minute); |
638 | return $this; |
639 | } |
640 | |
641 | /** |
642 | * Set job schedule to weekly |
643 | * |
644 | * @param mixed $day |
645 | * @param mixed $hours |
646 | * @param mixed $minutes |
647 | * @return Cron |
648 | */ |
649 | public function weekly(mixed $day, mixed $hours = null, mixed $minutes = null): Cron |
650 | { |
651 | if ($minutes !== null) { |
652 | $this->minutes($minutes); |
653 | } else { |
654 | $this->minutes = [0]; |
655 | } |
656 | |
657 | if ($hours !== null) { |
658 | $this->hours = [$hours]; |
659 | } else { |
660 | $this->hours = [0]; |
661 | } |
662 | |
663 | $this->daysOfTheMonth = ['*']; |
664 | $this->months = ['*']; |
665 | $this->daysOfTheWeek = [$day]; |
666 | |
667 | return $this->updateSchedule(); |
668 | } |
669 | |
670 | /** |
671 | * Set job schedule to monthly |
672 | * |
673 | * @param mixed $day |
674 | * @param mixed $hours |
675 | * @param mixed $minutes |
676 | * @return Cron |
677 | */ |
678 | public function monthly(mixed $day, mixed $hours = null, mixed $minutes = null): Cron |
679 | { |
680 | if ($minutes !== null) { |
681 | $this->minutes($minutes); |
682 | } else { |
683 | $this->minutes = [0]; |
684 | } |
685 | |
686 | if ($hours !== null) { |
687 | $this->hours = [$hours]; |
688 | } else { |
689 | $this->hours = [0]; |
690 | } |
691 | |
692 | $this->daysOfTheMonth = [$day]; |
693 | $this->months = ['*']; |
694 | $this->daysOfTheWeek = ['*']; |
695 | |
696 | return $this->updateSchedule(); |
697 | } |
698 | |
699 | /** |
700 | * Set job schedule to quarterly |
701 | * |
702 | * @param mixed $hours |
703 | * @param mixed $minutes |
704 | * @return Cron |
705 | */ |
706 | public function quarterly(mixed $hours = null, mixed $minutes = null): Cron |
707 | { |
708 | if ($minutes !== null) { |
709 | $this->minutes($minutes); |
710 | } else { |
711 | $this->minutes = [0]; |
712 | } |
713 | |
714 | if ($hours !== null) { |
715 | $this->hours = [$hours]; |
716 | } else { |
717 | $this->hours = [0]; |
718 | } |
719 | |
720 | $this->daysOfTheMonth = ['1']; |
721 | $this->months = [1,4,7,10]; |
722 | $this->daysOfTheWeek = ['*']; |
723 | |
724 | return $this->updateSchedule(); |
725 | } |
726 | |
727 | /** |
728 | * Set job schedule to yearly |
729 | * |
730 | * @param bool $endOfYear |
731 | * @param mixed $hours |
732 | * @param mixed $minutes |
733 | * @return Cron |
734 | */ |
735 | public function yearly(bool $endOfYear = false, mixed $hours = null, mixed $minutes = null): Cron |
736 | { |
737 | if ($minutes !== null) { |
738 | $this->minutes($minutes); |
739 | } else { |
740 | $this->minutes = [0]; |
741 | } |
742 | |
743 | if ($hours !== null) { |
744 | $this->hours = [$hours]; |
745 | } else { |
746 | $this->hours = [0]; |
747 | } |
748 | |
749 | $this->daysOfTheMonth = ($endOfYear) ? ['31'] : ['1']; |
750 | $this->months = ($endOfYear) ? ['12'] : ['1']; |
751 | $this->daysOfTheWeek = ['*']; |
752 | |
753 | return $this->updateSchedule(); |
754 | } |
755 | |
756 | /** |
757 | * Set job schedule to weekdays |
758 | * |
759 | * @return Cron |
760 | */ |
761 | public function weekdays(): Cron |
762 | { |
763 | $this->daysOfTheWeek = ['1', '2', '3', '4', '5']; |
764 | return $this->updateSchedule(); |
765 | } |
766 | |
767 | /** |
768 | * Set job schedule to weekends |
769 | * |
770 | * @return Cron |
771 | */ |
772 | public function weekends(): Cron |
773 | { |
774 | $this->daysOfTheWeek = ['0', '6']; |
775 | return $this->updateSchedule(); |
776 | } |
777 | |
778 | /** |
779 | * Set job schedule to Sundays |
780 | * |
781 | * @return Cron |
782 | */ |
783 | public function sundays(): Cron |
784 | { |
785 | $this->daysOfTheWeek = ['0']; |
786 | return $this->updateSchedule(); |
787 | } |
788 | |
789 | /** |
790 | * Set job schedule to Mondays |
791 | * |
792 | * @return Cron |
793 | */ |
794 | public function mondays(): Cron |
795 | { |
796 | $this->daysOfTheWeek = ['1']; |
797 | return $this->updateSchedule(); |
798 | } |
799 | |
800 | /** |
801 | * Set job schedule to Tuesdays |
802 | * |
803 | * @return Cron |
804 | */ |
805 | public function tuesdays(): Cron |
806 | { |
807 | $this->daysOfTheWeek = ['2']; |
808 | return $this->updateSchedule(); |
809 | } |
810 | |
811 | /** |
812 | * Set job schedule to Wednesdays |
813 | * |
814 | * @return Cron |
815 | */ |
816 | public function wednesdays(): Cron |
817 | { |
818 | $this->daysOfTheWeek = ['3']; |
819 | return $this->updateSchedule(); |
820 | } |
821 | |
822 | /** |
823 | * Set job schedule to Thursdays |
824 | * |
825 | * @return Cron |
826 | */ |
827 | public function thursdays(): Cron |
828 | { |
829 | $this->daysOfTheWeek = ['4']; |
830 | return $this->updateSchedule(); |
831 | } |
832 | |
833 | /** |
834 | * Set job schedule to Fridays |
835 | * |
836 | * @return Cron |
837 | */ |
838 | public function fridays(): Cron |
839 | { |
840 | $this->daysOfTheWeek = ['5']; |
841 | return $this->updateSchedule(); |
842 | } |
843 | |
844 | /** |
845 | * Set job schedule to Saturdays |
846 | * |
847 | * @return Cron |
848 | */ |
849 | public function saturdays(): Cron |
850 | { |
851 | $this->daysOfTheWeek = ['6']; |
852 | return $this->updateSchedule(); |
853 | } |
854 | |
855 | /** |
856 | * Set job schedule to between two hours |
857 | * |
858 | * @param int $start |
859 | * @param int $end |
860 | * @return Cron |
861 | */ |
862 | public function between(int $start, int $end): Cron |
863 | { |
864 | $this->hours = [$start . '-' . $end]; |
865 | return $this->updateSchedule(); |
866 | } |
867 | |
868 | /** |
869 | * Render the cron schedule string |
870 | * |
871 | * @return string |
872 | */ |
873 | public function render(): string |
874 | { |
875 | if (empty($this->schedule)) { |
876 | $this->updateSchedule(); |
877 | } |
878 | return $this->schedule; |
879 | } |
880 | |
881 | /** |
882 | * Evaluate the set cron schedule value against a time value |
883 | * |
884 | * $buffer = 0; strict evaluation to the 00 second |
885 | * $buffer = 1-59; gives up to a minute buffer to account for any delay in processing |
886 | * $buffer = -1; disregards the seconds value for a loose evaluation |
887 | * |
888 | * @param mixed $time |
889 | * @param ?int $buffer |
890 | * @throws Exception |
891 | * @return bool |
892 | */ |
893 | public function evaluate(mixed $time = null, ?int $buffer = null): bool |
894 | { |
895 | if ($time === null) { |
896 | $time = time(); |
897 | } else if (is_string($time)) { |
898 | $time = strtotime($time); |
899 | if ($time === false) { |
900 | throw new Exception('Error: That time value is not valid.'); |
901 | } |
902 | } |
903 | |
904 | if ($buffer !== null) { |
905 | $this->setBuffer($buffer); |
906 | } |
907 | |
908 | $second = (int)date('s', $time); |
909 | $minute = (int)date('i', $time); |
910 | $hour = (int)date('G', $time); |
911 | $dayOfTheMonth = (int)date('j', $time); |
912 | $month = (int)date('n', $time); |
913 | $dayOfTheWeek = (int)date('w', $time); |
914 | $secondsPassed = (in_array($second, $this->seconds) || ($this->seconds == ['*'])); |
915 | $minutesPassed = (in_array($minute, $this->minutes) || ($this->minutes == ['*'])); |
916 | $hoursPassed = (in_array($hour, $this->hours) || ($this->hours == ['*'])); |
917 | $domPassed = (in_array($dayOfTheMonth, $this->daysOfTheMonth) || ($this->daysOfTheMonth == ['*'])); |
918 | $monthPassed = (in_array($month, $this->months) || ($this->months == ['*'])); |
919 | $dowPassed = (in_array($dayOfTheWeek, $this->daysOfTheWeek) || ($this->daysOfTheWeek == ['*'])); |
920 | |
921 | if ((!$secondsPassed) && (count($this->seconds) == 1) && is_string($this->seconds[0])) { |
922 | $secondsPassed = (($this->evaluateExpression($this->seconds[0], $second))); |
923 | } |
924 | if ((!$minutesPassed) && (count($this->minutes) == 1) && is_string($this->minutes[0])) { |
925 | $minutesPassed = (($this->evaluateExpression($this->minutes[0], $minute))); |
926 | } |
927 | if ((!$hoursPassed) && (count($this->hours) == 1) && is_string($this->hours[0])) { |
928 | $hoursPassed = (($this->evaluateExpression($this->hours[0], $hour))); |
929 | } |
930 | if ((!$domPassed) && (count($this->daysOfTheMonth) == 1) && is_string($this->daysOfTheMonth[0])) { |
931 | $domPassed = (($this->evaluateExpression($this->daysOfTheMonth[0], $dayOfTheMonth))); |
932 | } |
933 | if ((!$monthPassed) && (count($this->months) == 1) && is_string($this->months[0])) { |
934 | $monthPassed = (($this->evaluateExpression($this->months[0], $month))); |
935 | } |
936 | if ((!$dowPassed) && (count($this->daysOfTheWeek) == 1) && is_string($this->daysOfTheWeek[0])) { |
937 | $dowPassed = (($this->evaluateExpression($this->daysOfTheWeek[0], $dayOfTheWeek))); |
938 | } |
939 | |
940 | if ($this->hasSeconds()) { |
941 | return (($dowPassed) && |
942 | ($monthPassed) && |
943 | ($domPassed) && |
944 | ($hoursPassed) && |
945 | ($minutesPassed) && |
946 | ($secondsPassed)); |
947 | } else { |
948 | // Check every minute schedule |
949 | if (($this->schedule == '* * * * *')) { |
950 | return (($this->buffer < 0) || ($second <= $this->buffer)); |
951 | // Validate the schedule |
952 | } else { |
953 | return (($dowPassed) && |
954 | ($monthPassed) && |
955 | ($domPassed) && |
956 | ($hoursPassed) && |
957 | ($minutesPassed) && |
958 | (($this->buffer < 0) || ($second <= $this->buffer))); |
959 | } |
960 | } |
961 | } |
962 | |
963 | /** |
964 | * To string method |
965 | * |
966 | * @return string |
967 | */ |
968 | public function __toString(): string |
969 | { |
970 | return $this->render(); |
971 | } |
972 | |
973 | /** |
974 | * Determine if the value satisfies the schedule expression |
975 | * |
976 | * @param string $expression |
977 | * @param mixed $value |
978 | * @return bool |
979 | */ |
980 | protected function evaluateExpression(string $expression, mixed $value): bool |
981 | { |
982 | if (str_contains($expression, ',')) { |
983 | $values = array_map('trim', explode(',', $expression)); |
984 | return in_array($value, $values); |
985 | } else if (str_contains($expression, '/')) { |
986 | $step = (int)substr($expression, (strpos($expression, '/') + 1)); |
987 | return (($value % $step) == 0); |
988 | } else if (str_contains($expression, '-')) { |
989 | list($min, $max) = explode('-', $expression); |
990 | return (($value >= $min) && ($value <= $max)); |
991 | } |
992 | |
993 | return false; |
994 | } |
995 | |
996 | } |