Issues (29)

src/FrequenciesTrait.php (4 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * This file is part of BlitzPHP Tasks.
7
 *
8
 * (c) 2025 Dimitri Sitchet Tomkeu <[email protected]>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13
14
namespace BlitzPHP\Tasks;
15
16
use BlitzPHP\Utilities\Date;
17
18
/**
19
 * Fournit les méthodes permettant d'attribuer des fréquences à des tâches individuelles.
20
 *
21
 * @credit <a href="https://tasks.codeigniter.com">CodeIgniter4 - CodeIgniter\Tasks\FrequenciesTrait</a>
22
 */
23
trait FrequenciesTrait
24
{
25
    /**
26
     * L'expression cron générée
27
     *
28
     * @var array<int|string, int|string>
29
     */
30
    protected array $expression = [
31
        'min'        => '*',
32
        'hour'       => '*',
33
        'dayOfMonth' => '*',
34
        'month'      => '*',
35
        'dayOfWeek'  => '*',
36
    ];
37
38
    /**
39
     * Si cette option est répertoriée, elle sera limitée à l'exécution dans ces environnements uniquement.
40
     *
41
     * @var list<string>
0 ignored issues
show
The type BlitzPHP\Tasks\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
42
     */
43
    protected $allowedEnvironments;
44
45
    /**
46
     * Planifie la tâche via une chaîne d'expression crontab brute.
47
     */
48
    public function cron(string $expression): self
49
    {
50
        $this->expression = explode(' ', $expression);
51
52
        return $this;
53
    }
54
55
    /**
56
     * Renvoie l'expression générée.
57
     */
58
    public function getExpression(): string
59
    {
60
        return implode(' ', array_values($this->expression));
61
    }
62
63
    /**
64
     * S'exécute tous les jours à l'heure indiquée
65
     */
66
    public function at(string $time): self
67
    {
68
        return $this->daily($time);
69
    }
70
71
    /**
72
     * S'exécute tous les jours à minuit, sauf si une chaîne d'heure est transmise (comme 04:08pm)
73
     */
74
    public function daily(?string $time = null): self
75
    {
76
        $min = $hour = 0;
77
78
        if (! empty($time)) {
79
            [$min, $hour] = $this->parseTime($time);
80
        }
81
82
        $this->expression['min']  = $min;
83
        $this->expression['hour'] = $hour;
84
85
        return $this;
86
    }
87
88
    /**
89
     * S'execute entre une temps de debut et de fin
90
     */
91
    public function between(string $startTime, string $endTime): self
92
    {
93
        [$minStart, $hourStart] = array_map('intval', $this->parseTime($startTime));
94
        [$minEnd, $hourEnd]     = array_map('intval', $this->parseTime($endTime));
95
96
        $this->betweenHours($hourStart, $hourEnd);
97
        $this->betweenMinutes($minStart, $minEnd);
98
99
        return $this;
100
    }
101
102
    /**
103
     * S'execute à une heure précise de la journée
104
     */
105
    public function time(string $time): self
106
    {
107
        [$min, $hour] = $this->parseTime($time);
108
109
        $this->expression['min']  = $min;
110
        $this->expression['hour'] = $hour;
111
112
        return $this;
113
    }
114
115
    /**
116
     * S'exécute au début de chaque heure à une minute précise.
117
     */
118
    public function hourly(?int $minute = null): self
119
    {
120
        return $this->everyHour(1, $minute ?? '00');
121
    }
122
123
    /**
124
     * S'exécute toutes les heures ou toutes les x heures
125
     *
126
     * @param int|string|null $minute
127
     */
128
    public function everyHour(int $hour = 1, $minute = null): self
129
    {
130
        $this->expression['min']  = $minute ?? '0';
131
        $this->expression['hour'] = ($hour === 1) ? '*' : '*/' . $hour;
132
133
        return $this;
134
    }
135
136
    /**
137
     * S'exécute toutes les 2 heures
138
     *
139
     * @param int|string|null $minute
140
     */
141
    public function everyTwoHours($minute = null): self
142
    {
143
        return $this->everyHour(2, $minute);
144
    }
145
146
    /**
147
     * S'exécute toutes les 3 heures
148
     *
149
     * @param int|string|null $minute
150
     */
151
    public function everyThreeHours($minute = null): self
152
    {
153
        return $this->everyHour(3, $minute);
154
    }
155
156
    /**
157
     * S'exécute toutes les 4 heures
158
     *
159
     * @param int|string|null $minute
160
     */
161
    public function everyFourHours($minute = null): self
162
    {
163
        return $this->everyHour(4, $minute);
164
    }
165
166
    /**
167
     * S'exécute toutes les 6 heures
168
     *
169
     * @param int|string|null $minute
170
     */
171
    public function everySixHours($minute = null): self
172
    {
173
        return $this->everyHour(6, $minute);
174
    }
175
176
    /**
177
     * S'execute toutes les heures impaires
178
     *
179
     * @param int|string|null $minute
180
     */
181
    public function everyOddHour($minute = null): self
182
    {
183
        $this->expression['min']  = $minute ?? '0';
184
        $this->expression['hour'] = '1-23/2';
185
186
        return $this;
187
    }
188
189
    /**
190
     * S'execute dans une plage horaire spécifique
191
     */
192
    public function betweenHours(int $fromHour, int $toHour): self
193
    {
194
        $this->expression['hour'] = $fromHour . '-' . $toHour;
195
196
        return $this;
197
    }
198
199
    /**
200
     * Fonctionne à des heures spécifiques choisies
201
     *
202
     * @param int|list<int> $hours
203
     */
204
    public function hours($hours = []): self
205
    {
206
        if (! is_array($hours)) {
207
            $hours = [$hours];
208
        }
209
210
        $this->expression['hour'] = implode(',', $hours);
211
212
        return $this;
213
    }
214
215
    /**
216
     * Définissez le temps d'exécution sur toutes les minutes ou toutes les x minutes.
217
     *
218
     * @param int|string|null $minute Lorsqu'il est défini, spécifie que le travail sera exécuté toutes les $minute minutes
219
     */
220
    public function everyMinute($minute = null): self
221
    {
222
        $this->expression['min'] = null === $minute ? '*' : '*/' . $minute;
223
224
        return $this;
225
    }
226
227
    /**
228
     * S'execute toutes les 2 minutes
229
     */
230
    public function everyTwoMinutes(): self
231
    {
232
        return $this->everyMinute(2);
233
    }
234
235
    /**
236
     * S'execute toutes les 3 minutes
237
     */
238
    public function everyThreeMinutes(): self
239
    {
240
        return $this->everyMinute(3);
241
    }
242
243
    /**
244
     * S'execute toutes les 4 minutes
245
     */
246
    public function everyFourMinutes(): self
247
    {
248
        return $this->everyMinute(4);
249
    }
250
251
    /**
252
     * S'execute toutes les 5 minutes
253
     */
254
    public function everyFiveMinutes(): self
255
    {
256
        return $this->everyMinute(5);
257
    }
258
259
    /**
260
     * S'execute toutes les 10 minutes
261
     */
262
    public function everyTenMinutes(): self
263
    {
264
        return $this->everyMinute(10);
265
    }
266
267
    /**
268
     * S'execute toutes les 15 minutes
269
     */
270
    public function everyFifteenMinutes(): self
271
    {
272
        return $this->everyMinute(15);
273
    }
274
275
    /**
276
     * S'execute toutes les 30 minutes
277
     */
278
    public function everyThirtyMinutes(): self
279
    {
280
        return $this->everyMinute(30);
281
    }
282
283
    /**
284
     * S'execute dans une plage de minutes spécifiée
285
     */
286
    public function betweenMinutes(int $fromMinute, int $toMinute): self
287
    {
288
        $this->expression['min'] = $fromMinute . '-' . $toMinute;
289
290
        return $this;
291
    }
292
293
    /**
294
     * S'execute sur un nombre de minutes spécifique choisi
295
     *
296
     * @param int|list<int> $minutes
297
     */
298
    public function minutes($minutes = []): self
299
    {
300
        if (! is_array($minutes)) {
301
            $minutes = [$minutes];
302
        }
303
304
        $this->expression['min'] = implode(',', $minutes);
305
306
        return $this;
307
    }
308
309
    /**
310
     * S'execute à des jours précis
311
     *
312
     * @param int|list<int> $days [0 : Dimanche - 6 : Samedi]
313
     */
314
    public function days($days): self
315
    {
316
        if (! is_array($days)) {
0 ignored issues
show
The condition is_array($days) is always false.
Loading history...
317
            $days = [$days];
318
        }
319
320
        $this->expression['dayOfWeek'] = implode(',', $days);
321
322
        return $this;
323
    }
324
325
    /**
326
     * S'execute tous les dimanches à minuit, sauf si l'heure est transmise.
327
     */
328
    public function sundays(?string $time = null): self
329
    {
330
        return $this->setDayOfWeek(Scheduler::SUNDAY, $time);
331
    }
332
333
    /**
334
     * S'execute tous les lundi à minuit, sauf si l'heure est transmise.
335
     */
336
    public function mondays(?string $time = null): self
337
    {
338
        return $this->setDayOfWeek(Scheduler::MONDAY, $time);
339
    }
340
341
    /**
342
     * S'execute tous les mardi à minuit, sauf si l'heure est transmise.
343
     */
344
    public function tuesdays(?string $time = null): self
345
    {
346
        return $this->setDayOfWeek(Scheduler::TUESDAY, $time);
347
    }
348
349
    /**
350
     * S'execute tous les mercredi à minuit, sauf si l'heure est transmise.
351
     */
352
    public function wednesdays(?string $time = null): self
353
    {
354
        return $this->setDayOfWeek(Scheduler::WEDNESDAY, $time);
355
    }
356
357
    /**
358
     * S'execute tous les jeudi à minuit, sauf si l'heure est transmise.
359
     */
360
    public function thursdays(?string $time = null): self
361
    {
362
        return $this->setDayOfWeek(Scheduler::THURSDAY, $time);
363
    }
364
365
    /**
366
     * S'execute tous les vendredi à minuit, sauf si l'heure est transmise.
367
     */
368
    public function fridays(?string $time = null): self
369
    {
370
        return $this->setDayOfWeek(Scheduler::FRIDAY, $time);
371
    }
372
373
    /**
374
     * S'execute tous les samedi à minuit, sauf si l'heure est transmise.
375
     */
376
    public function saturdays(?string $time = null): self
377
    {
378
        return $this->setDayOfWeek(Scheduler::SATURDAY, $time);
379
    }
380
381
    /**
382
     * Devrait être exécuté le premier jour de chaque mois.
383
     */
384
    public function monthly(?string $time = null): self
385
    {
386
        return $this->monthlyOn(1, $time);
387
    }
388
389
    /**
390
     * S'execute mensuellement à un jour et une heure donnés.
391
     *
392
     * @param int<1, 31> $dayOfMonth
393
     */
394
    public function monthlyOn(int $dayOfMonth = 1, ?string $time = null): self
395
    {
396
        $min = $hour = 0;
397
398
        if (! empty($time)) {
399
            [$min, $hour] = $this->parseTime($time);
400
        }
401
402
        $this->expression['min']        = $min;
403
        $this->expression['hour']       = $hour;
404
        $this->expression['dayOfMonth'] = $dayOfMonth;
405
406
        return $this;
407
    }
408
409
    /**
410
     * S'execute à des jours précis du mois
411
     *
412
     * @param int|list<int> $days [1-31]
413
     */
414
    public function daysOfMonth($days): self
415
    {
416
        if (! is_array($days)) {
0 ignored issues
show
The condition is_array($days) is always false.
Loading history...
417
            $days = [$days];
418
        }
419
420
        $this->expression['dayOfMonth'] = implode(',', $days);
421
422
        return $this;
423
    }
424
425
    /**
426
     * S'execute le dernier jours du mois
427
     */
428
    public function lastDayOfMonth(?string $time = null): self
429
    {
430
        $this->daily($time);
431
432
        return $this->daysOfMonth((int) Date::now()->endOfMonth()->getDay());
433
    }
434
435
    /**
436
     * Définissez le temps d'exécution sur tous les mois ou tous les x mois.
437
     *
438
     * @param int|string|null $month Lorsqu'il est défini, spécifie que le travail sera exécuté tous les $month mois
439
     */
440
    public function everyMonth($month = null): self
441
    {
442
        $this->expression['month'] = null === $month ? '*' : '*/' . $month;
443
444
        return $this;
445
    }
446
447
    /**
448
     * S'execute sur une plage de mois spécifique
449
     *
450
     * @param int $from Mois [1-12]
451
     * @param int $to   Mois [1-12]
452
     */
453
    public function betweenMonths(int $from, int $to): self
454
    {
455
        $this->expression['month'] = $from . '-' . $to;
456
457
        return $this;
458
    }
459
460
    /**
461
     * S'execute a des mois specifiques
462
     *
463
     * @param list<int> $months [1-12]
464
     */
465
    public function months(array $months = []): self
466
    {
467
        $this->expression['month'] = implode(',', $months);
468
469
        return $this;
470
    }
471
472
    /**
473
     * Devrait s'executer le premier jour de chaque trimestre,
474
     * exp. Jan 1, Apr 1, July 1, Oct 1
475
     */
476
    public function quarterly(?string $time = null): self
477
    {
478
        return $this->quarterlyOn(1, $time);
479
    }
480
481
    /**
482
     * S'execute tous les trimestres à un jour et une heure donnés.
483
     */
484
    public function quarterlyOn(int $dayOfQuarter = 1, ?string $time = null): self
485
    {
486
        $min = $hour = 0;
487
488
        if (! empty($time)) {
489
            [$min, $hour] = $this->parseTime($time);
490
        }
491
492
        $this->expression['min']        = $min;
493
        $this->expression['hour']       = $hour;
494
        $this->expression['dayOfMonth'] = $dayOfQuarter;
495
496
        $this->everyMonth(3);
497
498
        return $this;
499
    }
500
501
    /**
502
     * Devrait s'executer le premier jour de l'annee.
503
     */
504
    public function yearly(?string $time = null): self
505
    {
506
        return $this->yearlyOn(1, 1, $time);
507
    }
508
509
    /**
510
     * S'execute chaque année à un mois, un jour et une heure donnés.
511
     *
512
     * @param int<1, 31> $dayOfMonth
513
     */
514
    public function yearlyOn(int $month = 1, int $dayOfMonth = 1, ?string $time = null): self
515
    {
516
        $min = $hour = 0;
517
518
        if (! empty($time)) {
519
            [$min, $hour] = $this->parseTime($time);
520
        }
521
522
        $this->expression['min']        = $min;
523
        $this->expression['hour']       = $hour;
524
        $this->expression['dayOfMonth'] = $dayOfMonth;
525
        $this->expression['month']      = $month;
526
527
        return $this;
528
    }
529
530
    /**
531
     * S'execute en semainde (du lundi au vendredi).
532
     */
533
    public function weekdays(?string $time = null): self
534
    {
535
        $min = $hour = 0;
536
537
        if (! empty($time)) {
538
            [$min, $hour] = $this->parseTime($time);
539
        }
540
541
        $this->expression['min']       = $min;
542
        $this->expression['hour']      = $hour;
543
        $this->expression['dayOfWeek'] = '1-5';
544
545
        return $this;
546
    }
547
548
    /**
549
     * S'execute les weekends (samedi et dimanche)
550
     */
551
    public function weekends(?string $time = null): self
552
    {
553
        $min = $hour = 0;
554
555
        if (! empty($time)) {
556
            [$min, $hour] = $this->parseTime($time);
557
        }
558
559
        $this->expression['min']       = $min;
560
        $this->expression['hour']      = $hour;
561
        $this->expression['dayOfWeek'] = '6-7';
562
563
        return $this;
564
    }
565
566
    /**
567
     * Fonction interne utilisée par les fonctions mondays(), etc.
568
     */
569
    protected function setDayOfWeek(int $day, ?string $time = null): self
570
    {
571
        $min = $hour = '*';
572
573
        if (! empty($time)) {
574
            [$min, $hour] = $this->parseTime($time);
575
        }
576
577
        $this->expression['min']       = $min;
578
        $this->expression['hour']      = $hour;
579
        $this->expression['dayOfWeek'] = $day;
580
581
        return $this;
582
    }
583
584
    /**
585
     * Analyse une chaîne de temps (comme 04:08pm) en minutes et en heures
586
     *
587
     * @return list<string>
588
     */
589
    protected function parseTime(string $time): array
590
    {
591
        $time = strtotime($time);
592
593
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array(date('i', $time), date('G', $time)) returns the type array<integer,string> which is incompatible with the documented return type BlitzPHP\Tasks\list.
Loading history...
594
            date('i', $time), // mins
595
            date('G', $time),
596
        ];
597
    }
598
}
599