From 0c9eba5fa23cd7d2434a179375b839db20b45e35 Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Thu, 23 Jan 2025 15:13:52 +0100 Subject: [PATCH 1/5] feat: prise en compte du timezone dans la planification des taches --- src/CronExpression.php | 23 ++++++++++++++++++++- src/Task.php | 46 ++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/CronExpression.php b/src/CronExpression.php index 043da27..39c0f83 100644 --- a/src/CronExpression.php +++ b/src/CronExpression.php @@ -27,6 +27,11 @@ class CronExpression */ protected string $timezone; + /** + * Le fuseau horaire global à utiliser. + */ + private string $globalTimezone; + /** * La date/heure actuelle. Utilisée pour les tests. */ @@ -46,9 +51,25 @@ class CronExpression */ public function __construct(?string $timezone = null) { - $this->timezone = $timezone ?? config('app.timezone'); + if (null === $globalTimezone = config('tasks.timezone')) { + $globalTimezone = config('app.timezone'); + } + + $this->globalTimezone = $globalTimezone; + + $this->setTimezone($timezone); } + /** + * Définit le fuseau horaire global pour toutes les tâches de construction. + */ + public function setTimezone(?string $timezone = null): self + { + $this->timezone = $timezone ?? $this->globalTimezone; + + return $this; + } + /** * Vérifie si l'expression cron doit être exécutée. Permet d'utiliser un fuseau horaire personnalisé pour une tâche spécifique * diff --git a/src/Task.php b/src/Task.php index 7f64960..2b07211 100644 --- a/src/Task.php +++ b/src/Task.php @@ -48,18 +48,6 @@ class Task 'url', ]; - /** - * Type de l'action en cours. - */ - protected string $type; - - /** - * Le contenu actuel qu'on souhaite executer. - * - * @var mixed - */ - protected $action; - /** * S'il n'est pas vide, liste les environnements autorisés dans lesquels le programme peut être exécuté. * @@ -67,6 +55,11 @@ class Task */ protected array $environments = []; + /** + * Timezone dans lequel la tâche doit être traitée. + */ + protected ?string $timezone = null; + /** * Proprietés magiques emulées * @@ -75,18 +68,16 @@ class Task protected array $attributes = []; /** - * @param mixed $action + * @param string $type Type de l'action en cours. + * @param mixed $action Le contenu actuel qu'on souhaite executer. * * @throws TasksException */ - public function __construct(string $type, $action) + public function __construct(protected string $type, protected mixed $action) { if (! in_array($type, $this->types, true)) { throw TasksException::invalidTaskType($type); } - - $this->type = $type; - $this->action = $action; } /** @@ -109,10 +100,8 @@ public function getType(): string /** * Renvoie l'action enregistrée. - * - * @return mixed */ - public function getAction() + public function getAction(): mixed { return $this->action; } @@ -139,7 +128,7 @@ public function run() */ public function shouldRun(?string $testTime = null): bool { - $cron = service('cronExpression'); + $cron = service('cronExpression')->setTimezone($this->timezone); // Autoriser le réglage des heures pendant les tests if (! empty($testTime)) { @@ -164,8 +153,21 @@ public function environments(string ...$environments): self return $this; } + /** + * Définit le fuseau horaire pour l'exécution de la tâche. + * + * @param string $timezone L'identifiant du fuseau horaire à utiliser pour la tâche. + * Il doit s'agir d'une chaîne de caractères PHP valide (par exemple, 'America/New_York', 'Europe/Paris'). + */ + public function timezone(string $timezone): self + { + $this->timezone = $timezone; + + return $this; + } + /** - * Returns the date this was last ran. + * Renvoie la date à laquelle cette tâche a été exécutée pour la dernière fois. * * @return Date|string */ From a900294293bcdbaf892f00285ee2b1e9dbd35daa Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Thu, 23 Jan 2025 15:16:51 +0100 Subject: [PATCH 2/5] feat: passage des parametres aux taches ceci est notament utile pour l'execution des commandes via le nom de la classe plutot que celui de la commande --- src/Scheduler.php | 10 +++++----- src/Task.php | 10 +++++++++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Scheduler.php b/src/Scheduler.php index 044888c..414df0b 100644 --- a/src/Scheduler.php +++ b/src/Scheduler.php @@ -46,13 +46,13 @@ public function call(callable $func): Task /** * Planifie l'execution d'une commande. */ - public function command(string $command): Task + public function command(string $command, array $parameters = []): Task { - return $this->createTask('command', $command); + return $this->createTask('command', $command, $parameters); } /** - * Planifie l'exécution d'une fonction locale + * Planifie l'exécution d'une commande systeme */ public function shell(string $command): Task { @@ -80,9 +80,9 @@ public function url(string $url): Task /** * @param mixed $action */ - protected function createTask(string $type, $action): Task + protected function createTask(string $type, $action, array $parameters = []): Task { - $task = new Task($type, $action); + $task = new Task($type, $action, $parameters); $this->tasks[] = $task; return $task; diff --git a/src/Task.php b/src/Task.php index 2b07211..51cb931 100644 --- a/src/Task.php +++ b/src/Task.php @@ -73,7 +73,7 @@ class Task * * @throws TasksException */ - public function __construct(protected string $type, protected mixed $action) + public function __construct(protected string $type, protected mixed $action, protected array $parameters = []) { if (! in_array($type, $this->types, true)) { throw TasksException::invalidTaskType($type); @@ -106,6 +106,14 @@ public function getAction(): mixed return $this->action; } + /** + * Renvoie les paramètres de la tâche. + */ + public function getParameters(): array + { + return $this->parameters; + } + /** * Exécute l'action de cette tâche. * From 2bd1b9340808e76545fbd829f1849e7e7c7608de Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Thu, 23 Jan 2025 15:21:57 +0100 Subject: [PATCH 3/5] patch: ajout des constantes representants les jours de la semaine --- src/FrequenciesTrait.php | 14 +++++++------- src/Scheduler.php | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/FrequenciesTrait.php b/src/FrequenciesTrait.php index 0cd3366..336156b 100644 --- a/src/FrequenciesTrait.php +++ b/src/FrequenciesTrait.php @@ -221,7 +221,7 @@ public function days($days): self */ public function sundays(?string $time = null): self { - return $this->setDayOfWeek(0, $time); + return $this->setDayOfWeek(Scheduler::SUNDAY, $time); } /** @@ -229,7 +229,7 @@ public function sundays(?string $time = null): self */ public function mondays(?string $time = null): self { - return $this->setDayOfWeek(1, $time); + return $this->setDayOfWeek(Scheduler::MONDAY, $time); } /** @@ -237,7 +237,7 @@ public function mondays(?string $time = null): self */ public function tuesdays(?string $time = null): self { - return $this->setDayOfWeek(2, $time); + return $this->setDayOfWeek(Scheduler::TUESDAY, $time); } /** @@ -245,7 +245,7 @@ public function tuesdays(?string $time = null): self */ public function wednesdays(?string $time = null): self { - return $this->setDayOfWeek(3, $time); + return $this->setDayOfWeek(Scheduler::WEDNESDAY, $time); } /** @@ -253,7 +253,7 @@ public function wednesdays(?string $time = null): self */ public function thursdays(?string $time = null): self { - return $this->setDayOfWeek(4, $time); + return $this->setDayOfWeek(Scheduler::THURSDAY, $time); } /** @@ -261,7 +261,7 @@ public function thursdays(?string $time = null): self */ public function fridays(?string $time = null): self { - return $this->setDayOfWeek(5, $time); + return $this->setDayOfWeek(Scheduler::FRIDAY, $time); } /** @@ -269,7 +269,7 @@ public function fridays(?string $time = null): self */ public function saturdays(?string $time = null): self { - return $this->setDayOfWeek(6, $time); + return $this->setDayOfWeek(Scheduler::SATURDAY, $time); } /** diff --git a/src/Scheduler.php b/src/Scheduler.php index 414df0b..d374544 100644 --- a/src/Scheduler.php +++ b/src/Scheduler.php @@ -13,13 +13,25 @@ namespace BlitzPHP\Tasks; -use Closure; - /** * @credit CodeIgniter4 - CodeIgniter\Tasks\Scheduler */ class Scheduler { + const SUNDAY = 0; + + const MONDAY = 1; + + const TUESDAY = 2; + + const WEDNESDAY = 3; + + const THURSDAY = 4; + + const FRIDAY = 5; + + const SATURDAY = 6; + /** * @var list */ From deb1544ba9bb0d943c2e404a9acb5e20cd82046e Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Thu, 23 Jan 2025 15:23:59 +0100 Subject: [PATCH 4/5] feat: ajout de nouvelles methodes de frequences de programmation --- src/FrequenciesTrait.php | 160 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 151 insertions(+), 9 deletions(-) diff --git a/src/FrequenciesTrait.php b/src/FrequenciesTrait.php index 336156b..eea9b28 100644 --- a/src/FrequenciesTrait.php +++ b/src/FrequenciesTrait.php @@ -13,6 +13,8 @@ namespace BlitzPHP\Tasks; +use BlitzPHP\Utilities\Date; + /** * Fournit les méthodes permettant d'attribuer des fréquences à des tâches individuelles. * @@ -59,6 +61,14 @@ public function getExpression(): string } /** + * S'exécute tous les jours à l'heure indiquée + */ + public function at(string $time): self + { + return $this->daily($time); + } + + /** * S'exécute tous les jours à minuit, sauf si une chaîne d'heure est transmise (comme 04:08pm) */ public function daily(?string $time = null): self @@ -75,6 +85,20 @@ public function daily(?string $time = null): self return $this; } + /** + * S'execute entre une temps de debut et de fin + */ + public function between(string $startTime, string $endTime): self + { + [$minStart, $hourStart] = array_map('intval', $this->parseTime($startTime)); + [$minEnd, $hourEnd] = array_map('intval', $this->parseTime($endTime)); + + $this->betweenHours($hourStart, $hourEnd); + $this->betweenMinutes($minStart, $minEnd); + + return $this; + } + /** * S'execute à une heure précise de la journée */ @@ -89,14 +113,11 @@ public function time(string $time): self } /** - * S'exécute au début de chaque heure ou à une minute précise. + * S'exécute au début de chaque heure à une minute précise. */ public function hourly(?int $minute = null): self { - $this->expression['min'] = $minute ?? '00'; - $this->expression['hour'] = '*'; - - return $this; + return $this->everyHour(1, $minute); } /** @@ -112,6 +133,57 @@ public function everyHour(int $hour = 1, $minute = null): self return $this; } + /** + * S'exécute toutes les 2 heures + * + * @param int|string|null $minute + */ + public function everyTwoHours($minute = null): self + { + return $this->everyHour(2, $minute); + } + + /** + * S'exécute toutes les 3 heures + * + * @param int|string|null $minute + */ + public function everyThreeHours($minute = null): self + { + return $this->everyHour(3, $minute); + } + + /** + * S'exécute toutes les 4 heures + * + * @param int|string|null $minute + */ + public function everyFourHours($minute = null): self + { + return $this->everyHour(4, $minute); + } + + /** + * S'exécute toutes les 6 heures + * + * @param int|string|null $minute + */ + public function everySixHours($minute = null): self + { + return $this->everyHour(6, $minute); + } + + /** + * S'execute toutes les heures impaires + */ + public function everyOddHour($minute = null): self + { + $this->expression['min'] = $minute ?? '0'; + $this->expression['hour'] = '1-23/2'; + + return $this; + } + /** * S'execute dans une plage horaire spécifique */ @@ -150,6 +222,30 @@ public function everyMinute($minute = null): self return $this; } + /** + * S'execute toutes les 2 minutes + */ + public function everyTwoMinutes(): self + { + return $this->everyMinute(2); + } + + /** + * S'execute toutes les 3 minutes + */ + public function everyThreeMinutes() + { + return $this->everyMinute(3); + } + + /** + * S'execute toutes les 4 minutes + */ + public function everyFourMinutes() + { + return $this->everyMinute(4); + } + /** * S'execute toutes les 5 minutes */ @@ -158,6 +254,14 @@ public function everyFiveMinutes(): self return $this->everyMinute(5); } + /** + * S'execute toutes les 10 minutes + */ + public function everyTenMinutes(): self + { + return $this->everyMinute(10); + } + /** * S'execute toutes les 15 minutes */ @@ -276,6 +380,16 @@ public function saturdays(?string $time = null): self * Devrait être exécuté le premier jour de chaque mois. */ public function monthly(?string $time = null): self + { + return $this->monthlyOn(1, $time); + } + + /** + * S'execute mensuellement à un jour et une heure donnés. + * + * @param int<1, 31> $dayOfMonth + */ + public function monthlyOn(int $dayOfMonth = 1, ?string $time = null): self { $min = $hour = 0; @@ -285,7 +399,7 @@ public function monthly(?string $time = null): self $this->expression['min'] = $min; $this->expression['hour'] = $hour; - $this->expression['dayOfMonth'] = 1; + $this->expression['dayOfMonth'] = $dayOfMonth; return $this; } @@ -306,6 +420,16 @@ public function daysOfMonth($days): self return $this; } + /** + * S'execute le dernier jours du mois + */ + public function lastDayOfMonth(?string $time = null) + { + $this->daily($time); + + return $this->daysOfMonth(Date::now()->endOfMonth()->getDay()); + } + /** * Définissez le temps d'exécution sur tous les mois ou tous les x mois. * @@ -349,6 +473,14 @@ public function months(array $months = []): self */ public function quarterly(?string $time = null): self { + return $this->quarterlyOn(1, $time); + } + + /** + * S'execute tous les trimestres à un jour et une heure donnés. + */ + public function quarterlyOn(int $dayOfQuarter = 1, ?string $time = null) + { $min = $hour = 0; if (! empty($time)) { @@ -357,7 +489,7 @@ public function quarterly(?string $time = null): self $this->expression['min'] = $min; $this->expression['hour'] = $hour; - $this->expression['dayOfMonth'] = 1; + $this->expression['dayOfMonth'] = $dayOfQuarter; $this->everyMonth(3); @@ -368,6 +500,16 @@ public function quarterly(?string $time = null): self * Devrait s'executer le premier jour de l'annee. */ public function yearly(?string $time = null): self + { + return $this->yearlyOn(1, 1, $time); + } + + /** + * S'execute chaque année à un mois, un jour et une heure donnés. + * + * @param int<1, 31> $dayOfMonth + */ + public function yearlyOn(int $month = 1, int $dayOfMonth = 1, ?string $time = null): self { $min = $hour = 0; @@ -377,8 +519,8 @@ public function yearly(?string $time = null): self $this->expression['min'] = $min; $this->expression['hour'] = $hour; - $this->expression['dayOfMonth'] = 1; - $this->expression['month'] = 1; + $this->expression['dayOfMonth'] = $dayOfMonth; + $this->expression['month'] = $month; return $this; } From 8c884d77950bfbe1408ee189b1123b0829367178 Mon Sep 17 00:00:00 2001 From: Dimitri Sitchet Tomkeu Date: Thu, 23 Jan 2025 17:35:32 +0100 Subject: [PATCH 5/5] patch: utilisation du container pour l'execution des taches --- src/Task.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Task.php b/src/Task.php index 51cb931..4d02bba 100644 --- a/src/Task.php +++ b/src/Task.php @@ -13,6 +13,7 @@ namespace BlitzPHP\Tasks; +use BlitzPHP\Contracts\Container\ContainerInterface; use BlitzPHP\Tasks\Exceptions\TasksException; use BlitzPHP\Utilities\Date; use InvalidArgumentException; @@ -67,6 +68,8 @@ class Task */ protected array $attributes = []; + protected ContainerInterface $container; + /** * @param string $type Type de l'action en cours. * @param mixed $action Le contenu actuel qu'on souhaite executer. @@ -78,6 +81,8 @@ public function __construct(protected string $type, protected mixed $action, pro if (! in_array($type, $this->types, true)) { throw TasksException::invalidTaskType($type); } + + $this->container = service('container'); } /** @@ -106,14 +111,6 @@ public function getAction(): mixed return $this->action; } - /** - * Renvoie les paramètres de la tâche. - */ - public function getParameters(): array - { - return $this->parameters; - } - /** * Exécute l'action de cette tâche. * @@ -241,7 +238,7 @@ protected function runShell(): array */ protected function runClosure(): mixed { - return service('container')->call($this->getAction()); + return $this->container->call($this->getAction(), $this->parameters); } /**