From 33f87bde8d6e3a84f00065cd618ac39603b81390 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 17 Apr 2024 12:25:18 +0200 Subject: [PATCH 1/3] #13572 fix crontab bug --- pandora_console/include/functions_cron.php | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index f3755fd383..bd0f56f44e 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -989,3 +989,123 @@ function cron_list_table() ui_print_info_message(['no_close' => true, 'message' => __('There are no jobs') ]); } } + + +/** + * GetNextExecutionCron give string and return datetime with the date of the next execution + * + * @param string $cron String with cron. + * + * @return DateTime Datetime with the next execution. + */ +function GetNextExecutionCron($cron) +{ + // Parseamos el formato cron. + $cronsplit = preg_split('/\s+/', $cron); + $current_date = new DateTime(); + // Extract the current hour and minute. + $current_hour = (int) $current_date->format('H'); + $current_minute = (int) $current_date->format('i'); + + // If the current time has already passed, we increment the date to the next day. + if ($current_hour > $cronsplit[1] || ($current_hour == $cronsplit[1] && $current_minute >= $cronsplit[0])) { + $current_date->add(new DateInterval('P1D')); + } + + // Calculamos la próxima ejecución basada en el formato cron. + $next_minute = $current_date->format('i'); + $next_hour = $current_date->format('H'); + $next_day = $current_date->format('d'); + $next_month = $current_date->format('m'); + $next_day_week = $current_date->format('w'); + + // Minutes. + $minutes = cronToArray($cronsplit[0], 0, 59); + $next_minute = check_next_value($minutes, $next_minute); + + // Hours. + $hours = cronToArray($cronsplit[1], 0, 23); + $next_hour = check_next_value($hours, $next_hour); + + // Day of month. + $day_month = cronToArray($cronsplit[2], 1, 31); + $next_day = check_next_value($day_month, $next_day); + + // Month. + $month = cronToArray($cronsplit[3], 1, 12); + $next_month = check_next_value($month, $next_month); + + // Day of week. + $week_day = cronToArray($cronsplit[4], 0, 6); + $next_day_week = check_next_value($week_day, $next_day_week); + + // Next execution. + $next_execution = new DateTime(); + $next_execution->setTime($next_hour, $next_minute); + $next_execution->setDate($current_date->format('Y'), $next_month, $next_day); + + // If the next execution falls on a day of the week other than the current one, we adjust the date. + while ($next_execution->format('w') != $next_day_week) { + $next_execution->add(new DateInterval('P1D')); + } + + return $next_execution; +} + + +/** + * Split cron into array for checks. + * + * @param integer $cron + * @param mixed $min + * @param mixed $max + * @return void + */ +function cronToArray($cron, $min, $max) +{ + $values = []; + if ($cron == '*') { + for ($i = $min; $i <= $max; $i++) { + $values[] = $i; + } + } else { + $$elements = explode(',', $cron); + foreach ($$elements as $$element) { + if (strpos($$element, '/') !== false) { + $division = explode('/', $$element); + $start = $division[0]; + $count = $division[1]; + for ($i = $start; $i <= $max; $i += $count) { + if ($i >= $min && $i <= $max) { + $values[] = $i; + } + } + } else { + $values[] = $$element; + } + } + } + + sort($values); + return $values; +} + + +/** + * Check if the next value is valid. + * + * @param array $valores Values. + * @param interger $actual Value. + * + * @return integer Return the value. + */ +function check_next_value($valores, $actual) +{ + foreach ($valores as $valor) { + if ($valor >= $actual) { + return $valor; + } + } + + return $valores[0]; +} From fc3edbc6620244998a5a27bd5e8cfcf40800be46 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 8 May 2024 13:45:57 +0200 Subject: [PATCH 2/3] #13572 change GetNextExecutionCron internal function --- pandora_console/include/functions_cron.php | 127 +++++---------------- 1 file changed, 29 insertions(+), 98 deletions(-) diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index bd0f56f44e..0d313b7448 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -1000,112 +1000,43 @@ function cron_list_table() */ function GetNextExecutionCron($cron) { - // Parseamos el formato cron. + // Split cron. $cronsplit = preg_split('/\s+/', $cron); - $current_date = new DateTime(); - // Extract the current hour and minute. - $current_hour = (int) $current_date->format('H'); - $current_minute = (int) $current_date->format('i'); + // Set dates to use. + $current_day = new DateTime(); + $next_execution = new DateTime(); - // If the current time has already passed, we increment the date to the next day. - if ($current_hour > $cronsplit[1] || ($current_hour == $cronsplit[1] && $current_minute >= $cronsplit[0])) { - $current_date->add(new DateInterval('P1D')); + // Monthly schedule. + if ($cronsplit[2] !== '*') { + $next_execution->setDate($current_day->format('Y'), $current_day->format('m'), $cronsplit[2]); + $next_execution->setTime($cronsplit[1], $cronsplit[0]); + if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + $next_execution->setDate($current_day->format('Y'), ($current_day->format('m') + 1), $cronsplit[2]); + } + + return $next_execution; } - // Calculamos la próxima ejecución basada en el formato cron. - $next_minute = $current_date->format('i'); - $next_hour = $current_date->format('H'); - $next_day = $current_date->format('d'); - $next_month = $current_date->format('m'); - $next_day_week = $current_date->format('w'); + // Weekly schedule. + if ($cronsplit[4] !== '*') { + $next_execution->setISODate($current_day->format('Y'), $current_day->format('W'), $cronsplit[4]); + $next_execution->setTime($cronsplit[1], $cronsplit[0]); + if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + $next_execution->setISODate($current_day->format('Y'), ($current_day->format('W') + 1), $cronsplit[4]); + } - // Minutes. - $minutes = cronToArray($cronsplit[0], 0, 59); - $next_minute = check_next_value($minutes, $next_minute); + return $next_execution; + } - // Hours. - $hours = cronToArray($cronsplit[1], 0, 23); - $next_hour = check_next_value($hours, $next_hour); + // Daily schedule. + if ($cronsplit[2] === '*' && $cronsplit[3] === '*' && $cronsplit[4] === '*') { + $next_execution->setTime($cronsplit[1], $cronsplit[0]); + if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + $next_execution->setDate($current_day->format('Y'), $current_day->format('m'), ($current_day->format('d') + 1)); + } - // Day of month. - $day_month = cronToArray($cronsplit[2], 1, 31); - $next_day = check_next_value($day_month, $next_day); - - // Month. - $month = cronToArray($cronsplit[3], 1, 12); - $next_month = check_next_value($month, $next_month); - - // Day of week. - $week_day = cronToArray($cronsplit[4], 0, 6); - $next_day_week = check_next_value($week_day, $next_day_week); - - // Next execution. - $next_execution = new DateTime(); - $next_execution->setTime($next_hour, $next_minute); - $next_execution->setDate($current_date->format('Y'), $next_month, $next_day); - - // If the next execution falls on a day of the week other than the current one, we adjust the date. - while ($next_execution->format('w') != $next_day_week) { - $next_execution->add(new DateInterval('P1D')); + return $next_execution; } return $next_execution; } - - -/** - * Split cron into array for checks. - * - * @param integer $cron - * @param mixed $min - * @param mixed $max - * @return void - */ -function cronToArray($cron, $min, $max) -{ - $values = []; - if ($cron == '*') { - for ($i = $min; $i <= $max; $i++) { - $values[] = $i; - } - } else { - $$elements = explode(',', $cron); - foreach ($$elements as $$element) { - if (strpos($$element, '/') !== false) { - $division = explode('/', $$element); - $start = $division[0]; - $count = $division[1]; - for ($i = $start; $i <= $max; $i += $count) { - if ($i >= $min && $i <= $max) { - $values[] = $i; - } - } - } else { - $values[] = $$element; - } - } - } - - sort($values); - return $values; -} - - -/** - * Check if the next value is valid. - * - * @param array $valores Values. - * @param interger $actual Value. - * - * @return integer Return the value. - */ -function check_next_value($valores, $actual) -{ - foreach ($valores as $valor) { - if ($valor >= $actual) { - return $valor; - } - } - - return $valores[0]; -} From a3a86d0a08a22863c2b138069bdff5b061022110 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 8 May 2024 17:14:53 +0200 Subject: [PATCH 3/3] #13572 fix minutes date format --- pandora_console/include/functions_cron.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pandora_console/include/functions_cron.php b/pandora_console/include/functions_cron.php index 0d313b7448..97c854f443 100644 --- a/pandora_console/include/functions_cron.php +++ b/pandora_console/include/functions_cron.php @@ -1010,7 +1010,7 @@ function GetNextExecutionCron($cron) if ($cronsplit[2] !== '*') { $next_execution->setDate($current_day->format('Y'), $current_day->format('m'), $cronsplit[2]); $next_execution->setTime($cronsplit[1], $cronsplit[0]); - if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + if ($next_execution->format('Y-m-d H:i') <= $current_day->format('Y-m-d H:i')) { $next_execution->setDate($current_day->format('Y'), ($current_day->format('m') + 1), $cronsplit[2]); } @@ -1021,7 +1021,7 @@ function GetNextExecutionCron($cron) if ($cronsplit[4] !== '*') { $next_execution->setISODate($current_day->format('Y'), $current_day->format('W'), $cronsplit[4]); $next_execution->setTime($cronsplit[1], $cronsplit[0]); - if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + if ($next_execution->format('Y-m-d H:i') <= $current_day->format('Y-m-d H:i')) { $next_execution->setISODate($current_day->format('Y'), ($current_day->format('W') + 1), $cronsplit[4]); } @@ -1031,7 +1031,7 @@ function GetNextExecutionCron($cron) // Daily schedule. if ($cronsplit[2] === '*' && $cronsplit[3] === '*' && $cronsplit[4] === '*') { $next_execution->setTime($cronsplit[1], $cronsplit[0]); - if ($next_execution->format('Y-m-d H:m') <= $current_day->format('Y-m-d H:m')) { + if ($next_execution->format('Y-m-d H:i') <= $current_day->format('Y-m-d H:i')) { $next_execution->setDate($current_day->format('Y'), $current_day->format('m'), ($current_day->format('d') + 1)); }