Es können Informationen zum Status des Dienstes oder zu verwalteten Aufträgen abgefragt werden.
Außerdem ist es möglich, eigene CLI-Skripte zu registrieren, die von diesem Dienst verwaltet und ausgeführt werden sollen.
Einzelheiten können den folgenden Abschnitten entnommen werden.
Das ist eine für den Ausdruck optimierte Ansicht des gesamten Kapitels inkl. Unterseiten. Druckvorgang starten.
Howto
1 - Service API
Benachbarte Module fragen den Status des Moduls über eine stabile, schreibgeschützte Schnittstelle (CronjobService) ab, anstatt auf dessen interne Dienste zurückzugreifen. Überprüfen Sie zunächst die Verfügbarkeit –
das Modul ist möglicherweise nicht installiert, und die Klasse kann nur automatisch geladen werden, wenn die Datei
module.php
geladen wurde:
<?php
use Schwendinger\Webtrees\Module\Cronjob\Services\CronjobService;
if (class_exists(CronjobService::class) && CronjobService::isFunctional()) {
$status = CronjobService::jobStatus('mymodule:backup'); // null = unknown job
$age = CronjobService::lastTickAge(); // seconds since last tick
$listened = CronjobService::listenedEvents(); // event name => job names
}| Frage | Methode(n) |
|---|---|
| Ist der Dienst funktionsfähig? | isFunctional(), problems() (Codes: module_disabled, not_migrated, cron_library_missing, tick_stale) |
| Welche Funktionen sind aktiviert? | features() (watch, pseudo_events, route_events), watchStatus() |
| Wann wurde der letzte Tick ausgeführt? | lastTick() / lastTickAge() – beide Trigger-Typen (Marker-Datei data/cronjob/tick.last) |
| Ist ein Job aktiviert / wann wurde er zuletzt ausgeführt? | isJobEnabled($name), jobStatus($name), lastRun($name) – Jobnamen sind mit einem Namespace versehen (<Modul>:<Name>) |
| Auf welche Ereignisse wird gewartet? | listenedEvents(), listenersFor($event); Kataloge: eventCatalog(), pseudoEvents(), routeEvents() |
| Aktionen (die einzigen beiden) | runJobNow($name) (wird beim nächsten Tick in die Warteschlange gestellt), pushEvent($name, $payload) (Ereigniswarteschlange) |
Vertrag: Schreibgeschützte Methoden lösen niemals einen Fehler aus, wenn das Schema fehlt (sichere Standardwerte),
Beschreibungen sind Quelltext-Strings (werden niemals vorab übersetzt), und lastRun() schließt bewusst
die Job-Ausgabe aus, da diese personenbezogene Daten enthalten kann.
2 - Selbst-Registrierung
Andere Module können ihre geplanten Jobs anbieten, damit sie in der Admin-UI erscheinen, ohne dass jemand die Registry manuell editiert. Dazu können zwei Wege beschritten werden (ein Modul kann beide verwenden) - beide werden automatisch bei jedem Tick entdeckt, wobei dies nur für aktivierte Module gilt:
Marker-Methode
getCronJobs(): array in der Modul-module.php
-Klasse, die dasselbe Format zurückgibt. Entsprechend: getModuleEvents(): array, getModuleCommands(): array.
Manifest-Datei (empfohlen)
Bereitstellung einer Datei im Modulverzeichnis (modules_v4/<module>/cron-jobs.php), die ein Array von Job-Spezifikationen zurückgibt:
<?php
// modules_v4/linkenhancer/cron-jobs.php
declare(strict_types=1);
return [
[
'name' => 'link-index',
'title' => 'Update the link index',
'triggers' => [
['type' => 'time', 'cron' => '*/30 * * * *'],
],
'command_type' => 'module',
'command' => 'modules_v4/linkenhancer/cli/build-link-index.php',
'args' => '--limit=5000',
],
];Übersetzbare title / description-Texte in einem Manifest sollten in MoreI18N::translate() (Identitäts-Markierung) gesetzt werden,
damit xgettext sie aufnimmt — die Übersetzung erfolgt zur Render-Zeit, nie beim laden des Manifests.
Job-Spezifikations-Felder
| Schlüssel | Erforderlich | Bedeutung |
|---|---|---|
name | ja | Slug a-z 0-9 _ -, max. 64; gespeichert als <module>:<name> |
title | nein | menschlicher Name (Default = name) |
triggers | ja | Liste von Trigger-Einträgen, mindestens einer |
command_type | ja | module oder core |
command | ja | der Befehl |
args | nein | einfache Option/Wert-Tokens |
enabled | nein | Default false — entdeckte Jobs werden deaktiviert erstellt |
timeout_sec | nein | Default 300, Bereich 30 - 3600 |
Sobald ein entdeckter Job eingefügt ist, ist er unter Admin-Kontrolle: spätere Ticks überschreiben ihn nie.
Ereignisse ankündigen
Dasselbe Manifest kann auch Ereignisse ankündigen, die das Modul auslöst (damit sie im
Ereignis-Katalog und in den Vorschlägen des Job-Formulars erscheinen). Anstelle einer
einfachen Job-Liste kann das Manifest ein assoziatives Array mit optionalen jobs- und
events-Listen zurückgeben (eine einfache Liste bedeutet weiterhin „nur Jobs"):
<?php
// modules_v4/linkenhancer/cron-jobs.php
declare(strict_types=1);
return [
'jobs' => [
[
'name' => 'link-index',
'triggers' => [
['type' => 'time', 'cron' => '*/30 * * * *'],
// A job may combine several triggers:
// ['type' => 'event', 'event' => 'linkenhancer:index-dirty'],
],
'command_type' => 'module',
'command' => 'modules_v4/linkenhancer/cli/build-link-index.php',
],
],
'events' => [
['name' => 'index-dirty', 'description' => 'The link index is out of date.', 'payload' => ['tree']],
],
];- Ein angekündigtes Ereignis ist namespaced
<module>:<name>(wie die angebotenen Job-Schlüssel). - Der
event-Wert eines Ereignis-Triggers, der keinen Doppelpunkt trägt, wird automatisch namespaced<module>:<event>; ein Name, der bereits einen Doppelpunkt hat (z.B.cronjob:log-edit-update), bleibt unverändert. - Entsprechende Marker-Methode:
getModuleEvents(): array(dasselbe Event-Spec-Format).
Event-Spezifikations-Felder
| Schlüssel | Erforderlich | Bedeutung |
|---|---|---|
name | ja | Slug a-z 0-9 _ - (gespeichert als <module>:<name>) |
description | nein | wird im Ereignis-Katalog angezeigt (Übersetzungsschlüssel, max. 255) |
payload | nein | Liste von Payload-Parameter-Namen (max. 8), wird im Katalog angezeigt |
Befehle ankündigen
Dasselbe Manifest kann auch Befehle ankündigen, die ein Job ausführen kann, mit ihren
verfügbaren Parametern. Eine einfache Manifest-Liste bedeutet weiterhin „nur Jobs"; um
Befehle anzukündigen, gibt das Manifest die assoziative Form mit einer commands-Liste zurück:
// modules_v4/linkenhancer/cron-jobs.php
declare(strict_types=1);
return [
'jobs' => [ /* … */ ],
'commands' => [
[
'command' => 'modules_v4/linkenhancer/cli/build-link-index.php',
// 'command_type' => 'module', // optional - derived from the command value
'description' => 'Rebuild the link index incrementally.',
'params' => [
['name' => '--limit', 'optional' => true, 'default' => '5000', 'description' => 'max records per run'],
['name' => '--since', 'optional' => true, 'description' => 'only changes since this timestamp'],
],
],
],
];Command-Spezifikations-Felder
| Schlüssel | Erforderlich | Bedeutung |
|---|---|---|
command | ja | ein modules_v4/…/cli/*.php-Pfad oder ein erlaubter Core-Befehl, max. 255 |
command_type | nein | module oder core (wird bei weggelassenem Wert aus command abgeleitet) |
description | nein | wird im Befehl-Katalog angezeigt (Übersetzungsschlüssel, max. 255) |
params | nein | Liste von Parameter-Deskriptoren (max. 8) |
Jeder Parameter-Deskriptor hat name (das Option-Token, z.B. --limit), optional
(Bool, Default true — auf false setzen für eine erforderliche Option), default
(ein optionaler Wert) und description (optional). Entsprechende Marker-Methode:
getModuleCommands(): array (dasselbe Command-Spec-Format).
Kurations-Regel: Ein Modul, das Befehle ankündigt, kuratiert seine eigene Befehlsliste — die glob-basierte Entdeckung listet seine Skripte nicht mehr auf, sodass interne Skripte (
tick.php,watch.php,wrap.php,smoke-job.php) nicht als Job-Befehle angeboten werden. Ein Modul, das nichts ankündigt, fällt auf die glob-Entdeckung seinercli/-Skripte zurück (abwärtskompatibel).