From 8879a4ae5cc4eb2592b9dab95b3948690191ac07 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Thu, 30 Apr 2026 03:00:21 +0200 Subject: [PATCH] cron --- modules/fx-rates/module.json | 3 +- partials/landingpages/modules/setup.php | 453 +++++++++++++++++------- src/App/ModuleCronScheduler.php | 162 ++++++--- src/App/ModuleManager.php | 1 + tools/module_scheduler_run.php | 36 +- 5 files changed, 468 insertions(+), 187 deletions(-) diff --git a/modules/fx-rates/module.json b/modules/fx-rates/module.json index 29319f2..a537279 100644 --- a/modules/fx-rates/module.json +++ b/modules/fx-rates/module.json @@ -25,11 +25,12 @@ { "name": "schedule_timezone", "label": "Scheduler-Zeitzone", "type": "text", "required": false, "help": "z.B. Europe/Berlin" } ] }, - "cron_tasks": [ + "scheduler_jobs": [ { "name": "rates_refresh", "label": "Kursabruf", "callback": "scheduled_refresh", + "mode": "multi", "default_enabled": true, "default_cron": "0 18 * * *", "default_timezone": "Europe/Berlin", diff --git a/partials/landingpages/modules/setup.php b/partials/landingpages/modules/setup.php index 89cf619..3b8364b 100644 --- a/partials/landingpages/modules/setup.php +++ b/partials/landingpages/modules/setup.php @@ -45,6 +45,14 @@ $current = modules()->settings($moduleName); $intervalTaskStatuses = modules()->intervalTaskStatuses($moduleName); $cronTaskDefinitions = modules()->cronTasks($moduleName); $cronTaskStatuses = modules()->cronTaskStatuses($moduleName); +$cronTaskStatusGroups = []; +foreach ($cronTaskStatuses as $cronTaskStatus) { + $cronGroupName = trim((string) ($cronTaskStatus['job_name'] ?? $cronTaskStatus['name'] ?? '')); + if ($cronGroupName === '') { + continue; + } + $cronTaskStatusGroups[$cronGroupName][] = $cronTaskStatus; +} $setupActions = modules()->hasFunction($moduleName, 'setup_actions') ? (array) module_fn($moduleName, 'setup_actions') : []; @@ -384,7 +392,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $current = array_replace_recursive($current, $payload); if ($cronTaskDefinitions !== []) { - $cronJobs = is_array($current['cron_jobs'] ?? null) ? $current['cron_jobs'] : []; + $postedSchedulerJobs = is_array($_POST['scheduler_jobs'] ?? null) ? $_POST['scheduler_jobs'] : []; + $schedulerJobs = []; foreach ($cronTaskDefinitions as $cronTask) { if (!is_array($cronTask)) { continue; @@ -394,26 +403,41 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { continue; } - $prefix = 'cron_job_' . preg_replace('/[^a-zA-Z0-9_]/', '_', $cronName); - $cronJobs[$cronName] = array_merge( - is_array($cronJobs[$cronName] ?? null) ? $cronJobs[$cronName] : [], - [ - 'enabled' => isset($_POST[$prefix . '_enabled']), - 'cron_expression' => trim((string) ($_POST[$prefix . '_cron_expression'] ?? ($cronTask['default_cron'] ?? ''))), - 'timezone' => trim((string) ($_POST[$prefix . '_timezone'] ?? ($cronTask['default_timezone'] ?? 'UTC'))), + $jobPayload = is_array($postedSchedulerJobs[$cronName] ?? null) ? $postedSchedulerJobs[$cronName] : []; + $entriesPayload = is_array($jobPayload['entries'] ?? null) ? $jobPayload['entries'] : []; + $entries = []; + foreach (array_values($entriesPayload) as $entryPayload) { + if (!is_array($entryPayload)) { + continue; + } + $cronExpression = trim((string) ($entryPayload['cron_expression'] ?? '')); + $timezone = trim((string) ($entryPayload['timezone'] ?? ($current['schedule_timezone'] ?? 'UTC'))); + if ($cronExpression === '' && $timezone === '') { + continue; + } + $entries[] = [ + 'enabled' => !empty($entryPayload['enabled']), + 'cron_expression' => $cronExpression, + 'timezone' => $timezone !== '' ? $timezone : 'UTC', 'builder' => [ - 'mode' => trim((string) ($_POST[$prefix . '_builder_mode'] ?? 'builder')), - 'kind' => trim((string) ($_POST[$prefix . '_builder_kind'] ?? 'daily')), - 'time' => trim((string) ($_POST[$prefix . '_builder_time'] ?? '18:00')), - 'interval_days' => max(1, (int) ($_POST[$prefix . '_builder_interval_days'] ?? 2)), - 'weekday' => trim((string) ($_POST[$prefix . '_builder_weekday'] ?? '1')), - 'month_day' => max(1, min(31, (int) ($_POST[$prefix . '_builder_month_day'] ?? 1))), - 'interval_hours' => max(1, (int) ($_POST[$prefix . '_builder_interval_hours'] ?? 6)), + 'mode' => trim((string) ($entryPayload['builder']['mode'] ?? 'builder')), + 'kind' => trim((string) ($entryPayload['builder']['kind'] ?? 'daily')), + 'time' => trim((string) ($entryPayload['builder']['time'] ?? '18:00')), + 'interval_days' => max(1, (int) ($entryPayload['builder']['interval_days'] ?? 2)), + 'weekday' => trim((string) ($entryPayload['builder']['weekday'] ?? '1')), + 'month_day' => max(1, min(31, (int) ($entryPayload['builder']['month_day'] ?? 1))), + 'interval_hours' => max(1, min(23, (int) ($entryPayload['builder']['interval_hours'] ?? 6))), ], - ] - ); + ]; + } + + if ((string) ($cronTask['mode'] ?? 'single') !== 'multi' && $entries !== []) { + $entries = [array_values($entries)[0]]; + } + + $schedulerJobs[$cronName] = ['entries' => $entries]; } - $current['cron_jobs'] = $cronJobs; + $current['scheduler_jobs'] = $schedulerJobs; } $postedTestGroup = (string)($_POST['test_db'] ?? ''); @@ -774,7 +798,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups) - +
@@ -783,56 +807,72 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)

Diese Jobs werden ueber den zentralen Nexus-Scheduler ausgefuehrt. Der System-Cron sollte den CLI-Runner jede Minute starten.

-
- - -
- - - - - - - Cron-Syntax: Minute Stunde Tag Monat Wochentag - - -
- - - - - - -
- Letzter Start: - Letzter Erfolg: - Naechster Lauf UTC: - Naechster Lauf lokal: - Status: - - Cron-Fehler: - + + +
+ + + + +
+ $task): ?> + +
+ + + Cron-Syntax: Minute Stunde Tag Monat Wochentag + + +
+ + + + + + +
+ Letzter Start: + Letzter Erfolg: + Naechster Lauf UTC: + Naechster Lauf lokal: + Status: + + Cron-Fehler: + + + + +
+
- -
+ +
+ +
+ +
+
@@ -1134,7 +1174,7 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups) - +
@@ -1143,56 +1183,72 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)

Diese Jobs werden ueber den zentralen Nexus-Scheduler ausgefuehrt. Der System-Cron sollte den CLI-Runner jede Minute starten.

-
- - -
- - - - - - - Cron-Syntax: Minute Stunde Tag Monat Wochentag - - -
- - - - - - -
- Letzter Start: - Letzter Erfolg: - Naechster Lauf UTC: - Naechster Lauf lokal: - Status: - - Cron-Fehler: - + + +
+ + + + +
+ $task): ?> + +
+ + + Cron-Syntax: Minute Stunde Tag Monat Wochentag + + +
+ + + + + + +
+ Letzter Start: + Letzter Erfolg: + Naechster Lauf UTC: + Naechster Lauf lokal: + Status: + + Cron-Fehler: + + + + +
+
- -
+ +
+ +
+ +
+
@@ -1336,9 +1392,19 @@ $activeDbGroup = $testGroup !== null && array_key_exists($testGroup, $dbGroups)