Test Failed
Push — main ( d75e4f...57e80b )
by Dimitri
03:34 queued 01:38
created

FrequenciesTrait::everyTwoHours()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 1
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
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
Bug introduced by
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);
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
    public function everyOddHour($minute = null): self
180
    {
181
		$this->expression['min']  = $minute ?? '0';
182
        $this->expression['hour'] = '1-23/2';
183
184
        return $this;
185
    }
186
187
    /**
188
     * S'execute dans une plage horaire spécifique
189
     */
190
    public function betweenHours(int $fromHour, int $toHour): self
191
    {
192
        $this->expression['hour'] = $fromHour . '-' . $toHour;
193
194
        return $this;
195
    }
196
197
    /**
198
     * Fonctionne à des heures spécifiques choisies
199
     *
200
     * @param int|list<int> $hours
201
     */
202
    public function hours($hours = []): self
203
    {
204
        if (! is_array($hours)) {
205
            $hours = [$hours];
206
        }
207
208
        $this->expression['hour'] = implode(',', $hours);
209
210
        return $this;
211
    }
212
213
    /**
214
     * Définissez le temps d'exécution sur toutes les minutes ou toutes les x minutes.
215
     *
216
     * @param int|string|null $minute Lorsqu'il est défini, spécifie que le travail sera exécuté toutes les $minute minutes
217
     */
218
    public function everyMinute($minute = null): self
219
    {
220
        $this->expression['min'] = null === $minute ? '*' : '*/' . $minute;
221
222
        return $this;
223
    }
224
225
    /**
226
     * S'execute toutes les 2 minutes
227
     */
228
    public function everyTwoMinutes(): self
229
    {
230
        return $this->everyMinute(2);
231
    }
232
233
    /**
234
     * S'execute toutes les 3 minutes
235
     */
236
    public function everyThreeMinutes()
237
    {
238
        return $this->everyMinute(3);
239
    }
240
241
    /**
242
     * S'execute toutes les 4 minutes
243
     */
244
    public function everyFourMinutes()
245
    {
246
        return $this->everyMinute(4);
247
    }
248
249
    /**
250
     * S'execute toutes les 5 minutes
251
     */
252
    public function everyFiveMinutes(): self
253
    {
254
        return $this->everyMinute(5);
255
    }
256
257
    /**
258
     * S'execute toutes les 10 minutes
259
     */
260
    public function everyTenMinutes(): self
261
    {
262
		return $this->everyMinute(10);
263
    }
264
265
    /**
266
     * S'execute toutes les 15 minutes
267
     */
268
    public function everyFifteenMinutes(): self
269
    {
270
        return $this->everyMinute(15);
271
    }
272
273
    /**
274
     * S'execute toutes les 30 minutes
275
     */
276
    public function everyThirtyMinutes(): self
277
    {
278
        return $this->everyMinute(30);
279
    }
280
281
    /**
282
     * S'execute dans une plage de minutes spécifiée
283
     */
284
    public function betweenMinutes(int $fromMinute, int $toMinute): self
285
    {
286
        $this->expression['min'] = $fromMinute . '-' . $toMinute;
287
288
        return $this;
289
    }
290
291
    /**
292
     * S'execute sur un nombre de minutes spécifique choisi
293
     *
294
     * @param int|list<int> $minutes
295
     */
296
    public function minutes($minutes = []): self
297
    {
298
        if (! is_array($minutes)) {
299
            $minutes = [$minutes];
300
        }
301
302
        $this->expression['min'] = implode(',', $minutes);
303
304
        return $this;
305
    }
306
307
    /**
308
     * S'execute à des jours précis
309
     *
310
     * @param int|list<int> $days [0 : Dimanche - 6 : Samedi]
311
     */
312
    public function days($days): self
313
    {
314
        if (! is_array($days)) {
0 ignored issues
show
introduced by
The condition is_array($days) is always false.
Loading history...
315
            $days = [$days];
316
        }
317
318
        $this->expression['dayOfWeek'] = implode(',', $days);
319
320
        return $this;
321
    }
322
323
    /**
324
     * S'execute tous les dimanches à minuit, sauf si l'heure est transmise.
325
     */
326
    public function sundays(?string $time = null): self
327
    {
328
        return $this->setDayOfWeek(Scheduler::SUNDAY, $time);
329
    }
330
331
    /**
332
     * S'execute tous les lundi à minuit, sauf si l'heure est transmise.
333
     */
334
    public function mondays(?string $time = null): self
335
    {
336
        return $this->setDayOfWeek(Scheduler::MONDAY, $time);
337
    }
338
339
    /**
340
     * S'execute tous les mardi à minuit, sauf si l'heure est transmise.
341
     */
342
    public function tuesdays(?string $time = null): self
343
    {
344
        return $this->setDayOfWeek(Scheduler::TUESDAY, $time);
345
    }
346
347
    /**
348
     * S'execute tous les mercredi à minuit, sauf si l'heure est transmise.
349
     */
350
    public function wednesdays(?string $time = null): self
351
    {
352
        return $this->setDayOfWeek(Scheduler::WEDNESDAY, $time);
353
    }
354
355
    /**
356
     * S'execute tous les jeudi à minuit, sauf si l'heure est transmise.
357
     */
358
    public function thursdays(?string $time = null): self
359
    {
360
        return $this->setDayOfWeek(Scheduler::THURSDAY, $time);
361
    }
362
363
    /**
364
     * S'execute tous les vendredi à minuit, sauf si l'heure est transmise.
365
     */
366
    public function fridays(?string $time = null): self
367
    {
368
        return $this->setDayOfWeek(Scheduler::FRIDAY, $time);
369
    }
370
371
    /**
372
     * S'execute tous les samedi à minuit, sauf si l'heure est transmise.
373
     */
374
    public function saturdays(?string $time = null): self
375
    {
376
        return $this->setDayOfWeek(Scheduler::SATURDAY, $time);
377
    }
378
379
    /**
380
     * Devrait être exécuté le premier jour de chaque mois.
381
     */
382
    public function monthly(?string $time = null): self
383
    {
384
        return $this->monthlyOn(1, $time);
385
    }
386
387
	/**
388
     * S'execute mensuellement à un jour et une heure donnés.
389
     *
390
     * @param  int<1, 31>  $dayOfMonth
391
     */
392
    public function monthlyOn(int $dayOfMonth = 1, ?string $time = null): self
393
    {
394
        $min = $hour = 0;
395
396
        if (! empty($time)) {
397
            [$min, $hour] = $this->parseTime($time);
398
        }
399
400
        $this->expression['min']        = $min;
401
        $this->expression['hour']       = $hour;
402
        $this->expression['dayOfMonth'] = $dayOfMonth;
403
404
        return $this;
405
    }
406
407
    /**
408
     * S'execute à des jours précis du mois
409
     *
410
     * @param int|list<int> $days [1-31]
411
     */
412
    public function daysOfMonth($days): self
413
    {
414
        if (! is_array($days)) {
0 ignored issues
show
introduced by
The condition is_array($days) is always false.
Loading history...
415
            $days = [$days];
416
        }
417
418
        $this->expression['dayOfMonth'] = implode(',', $days);
419
420
        return $this;
421
    }
422
423
    /**
424
     * S'execute le dernier jours du mois
425
     */
426
    public function lastDayOfMonth(?string $time = null)
427
    {
428
        $this->daily($time);
429
430
		return $this->daysOfMonth(Date::now()->endOfMonth()->getDay());
0 ignored issues
show
Bug introduced by
BlitzPHP\Utilities\Date:...>endOfMonth()->getDay() of type string is incompatible with the type BlitzPHP\Tasks\list|integer expected by parameter $days of BlitzPHP\Tasks\FrequenciesTrait::daysOfMonth(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

430
		return $this->daysOfMonth(/** @scrutinizer ignore-type */ Date::now()->endOfMonth()->getDay());
Loading history...
431
    }
432
433
    /**
434
     * Définissez le temps d'exécution sur tous les mois ou tous les x mois.
435
     *
436
     * @param int|string|null $month Lorsqu'il est défini, spécifie que le travail sera exécuté tous les $month mois
437
     */
438
    public function everyMonth($month = null): self
439
    {
440
        $this->expression['month'] = null === $month ? '*' : '*/' . $month;
441
442
        return $this;
443
    }
444
445
    /**
446
     * S'execute sur une plage de mois spécifique
447
     *
448
     * @param int $from Mois [1-12]
449
     * @param int $to   Mois [1-12]
450
     */
451
    public function betweenMonths(int $from, int $to): self
452
    {
453
        $this->expression['month'] = $from . '-' . $to;
454
455
        return $this;
456
    }
457
458
    /**
459
     * S'execute a des mois specifiques
460
     *
461
     * @param list<int> $months [1-12]
462
     */
463
    public function months(array $months = []): self
464
    {
465
        $this->expression['month'] = implode(',', $months);
466
467
        return $this;
468
    }
469
470
    /**
471
     * Devrait s'executer le premier jour de chaque trimestre,
472
     * exp. Jan 1, Apr 1, July 1, Oct 1
473
     */
474
    public function quarterly(?string $time = null): self
475
    {
476
        return $this->quarterlyOn(1, $time);
477
    }
478
479
	/**
480
     * S'execute tous les trimestres à un jour et une heure donnés.
481
     */
482
    public function quarterlyOn(int $dayOfQuarter = 1, ?string $time = null)
483
	{
484
        $min = $hour = 0;
485
486
        if (! empty($time)) {
487
            [$min, $hour] = $this->parseTime($time);
488
        }
489
490
        $this->expression['min']        = $min;
491
        $this->expression['hour']       = $hour;
492
        $this->expression['dayOfMonth'] = $dayOfQuarter;
493
494
        $this->everyMonth(3);
495
496
        return $this;
497
    }
498
499
    /**
500
     * Devrait s'executer le premier jour de l'annee.
501
     */
502
    public function yearly(?string $time = null): self
503
    {
504
        return $this->yearlyOn(1, 1, $time);
505
    }
506
507
	/**
508
     * S'execute chaque année à un mois, un jour et une heure donnés.
509
     *
510
     * @param  int<1, 31>  $dayOfMonth
511
     */
512
    public function yearlyOn(int $month = 1, int $dayOfMonth = 1, ?string $time = null): self
513
    {
514
        $min = $hour = 0;
515
516
        if (! empty($time)) {
517
            [$min, $hour] = $this->parseTime($time);
518
        }
519
520
        $this->expression['min']        = $min;
521
        $this->expression['hour']       = $hour;
522
        $this->expression['dayOfMonth'] = $dayOfMonth;
523
        $this->expression['month']      = $month;
524
525
        return $this;
526
    }
527
528
    /**
529
     * S'execute en semainde (du lundi au vendredi).
530
     */
531
    public function weekdays(?string $time = null): self
532
    {
533
        $min = $hour = 0;
534
535
        if (! empty($time)) {
536
            [$min, $hour] = $this->parseTime($time);
537
        }
538
539
        $this->expression['min']       = $min;
540
        $this->expression['hour']      = $hour;
541
        $this->expression['dayOfWeek'] = '1-5';
542
543
        return $this;
544
    }
545
546
    /**
547
     * S'execute les weekends (samedi et dimanche)
548
     */
549
    public function weekends(?string $time = null): self
550
    {
551
        $min = $hour = 0;
552
553
        if (! empty($time)) {
554
            [$min, $hour] = $this->parseTime($time);
555
        }
556
557
        $this->expression['min']       = $min;
558
        $this->expression['hour']      = $hour;
559
        $this->expression['dayOfWeek'] = '6-7';
560
561
        return $this;
562
    }
563
564
    /**
565
     * Fonction interne utilisée par les fonctions mondays(), etc.
566
     */
567
    protected function setDayOfWeek(int $day, ?string $time = null): self
568
    {
569
        $min = $hour = '*';
570
571
        if (! empty($time)) {
572
            [$min, $hour] = $this->parseTime($time);
573
        }
574
575
        $this->expression['min']       = $min;
576
        $this->expression['hour']      = $hour;
577
        $this->expression['dayOfWeek'] = $day;
578
579
        return $this;
580
    }
581
582
    /**
583
     * Analyse une chaîne de temps (comme 04:08pm) en minutes et en heures
584
     *
585
     * @return list<string>
586
     */
587
    protected function parseTime(string $time): array
588
    {
589
        $time = strtotime($time);
590
591
        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...
592
            date('i', $time), // mins
593
            date('G', $time),
594
        ];
595
    }
596
}
597