04_FUNCTION_API.md 7.4 KB

Funktions-API

Überblick

Alle Funktionen stehen nach einem einzigen require zur Verfügung:

require_once __DIR__ . "/manage-client/lib/client.php";

Die Kommandozeile (bin/manage-client.php) und die Oberfläche (ui/panel.php) enthalten keine eigene Logik, sondern rufen genau diese Funktionen auf. Eine Funktion verhält sich deshalb identisch, egal wie sie ausgelöst wird.

Fehler werden als RuntimeException geworfen. Ausnahmen von dieser Regel sind ausdrücklich vermerkt.

Status

manageClientStatus(): array

Sammelaufruf für Oberflächen. Wirft nie: Jeder Fehler landet im Rückgabewert, damit eine Einstellungsseite auch bei nicht erreichbarem Server rendert.

[
    "instance"           => "mein-projekt-prod",
    "server_url"         => "https://manage.example.org",
    "configured"         => true,
    "version"            => "v1.2.3",   // "" wenn nicht ermittelbar
    "php_version"        => "8.3.6",
    "update"             => [...],      // Rückgabe von manageUpdateCheck(), oder null
    "update_error"       => null,       // Fehlermeldung, wenn die Prüfung scheiterte
    "backups"            => [...],      // Rückgabe von manageBackupList()
    "last_backup_at"     => "2026-08-20T09:21:04+00:00",
    "pending_migrations" => [...],
    "errors"             => [],         // nicht-fatale Warnungen
]

manageClientVersion(): string

Installierte Version, zum Beispiel "v1.2.3". Gibt "" zurück, wenn sie nicht ermittelbar ist; das ist kein Fehler, sondern "unbekannt".

manageClientConfigured(): bool

Ob Server-URL, Instanz und Token gesetzt sind.

Update

manageUpdateCheck(): array

Holt das Manifest und vergleicht die Versionen.

[
    "current"   => "v1.2.3",
    "latest"    => "v1.3.0",
    "available" => true,
    "manifest"  => [
        "version"      => "v1.3.0",
        "package_url"  => "https://…/api/v1/package.php?version=v1.3.0",
        "sha256"       => "…",
        "size"         => 421337,
        "published_at" => "2026-08-20T09:20:43+00:00",
    ],
]

Ist die installierte Version unbekannt, gilt available => true, damit eine Installation ohne lesbare Versionsdatei nicht dauerhaft blockiert.

manageUpdateApply(array $options = []): array

Lädt das Paket, prüft Größe und SHA-256, entpackt es, rollt es aus und führt anschließend den Post-Update-Schritt aus.

Optionen:

Option Bedeutung
force Auch ausrollen, wenn keine neuere Version vorliegt
skip_hook Nur Dateien ausrollen, weder Migrationen noch Callback ausführen

Rückgabe:

[
    "deployed"        => true,
    "from_version"    => "v1.2.3",
    "to_version"      => "v1.3.0",
    "copied"          => 128,
    "backed_up"       => 126,
    "skipped"         => 2,      // geschützte Pfade
    "removed_backups" => 1,
    "backup_dir"      => "/…/data/manage/updates/20260820-092114-v1.3.0",
    "hook"            => [...],  // siehe unten
]

Wirft, wenn das Ausrollen scheitert. Scheitert nur der Post-Update-Schritt, kehrt die Funktion normal zurück und hook["success"] ist false – die Dateien sind dann bereits ausgerollt. Aufrufer müssen beides unterscheiden; siehe 07_POST_UPDATE_HOOKS.

Wichtig: Das Ausrollen überschreibt Dateien im laufenden Betrieb. Es gibt keine Wartungsseite und keine Rücknahme. Die überschriebenen Dateien liegen als Kopie in backup_dir, aber ausschließlich für die manuelle Wiederherstellung.

manageUpdatePendingMigrations(): array

Noch nicht ausgeführte Migrationen in Ausführungsreihenfolge:

[["id" => "2026-08-20-01-add-index", "path" => "/…/migrations/2026-08-20-01-add-index.php"]]

manageUpdateRunMigrations(array $context = []): array

Führt die offenen Migrationen aus. Wirft nicht, sondern meldet:

[
    "success" => false,
    "applied" => ["2026-08-20-01-add-index"],
    "failed"  => "2026-08-20-02-backfill",
    "error"   => "SQLSTATE[42S22]: …",
    "pending" => 2,   // inklusive der fehlgeschlagenen
]

Backup

manageBackupCreate(string $trigger = "manual"): array

Erstellt ein lokales Archiv und lädt es hoch, sofern MANAGE_BACKUP_UPLOAD aktiv ist.

$trigger ist frei wählbar; üblich sind manual, automatic, cron, update. Nur automatic und cron zählen für die Intervallprüfung.

[
    "filename"       => "backup-20260820-092104.zip",
    "created_at"     => "2026-08-20T09:21:04+00:00",
    "trigger"        => "cron",
    "size"           => 427,
    "file_count"     => 3,
    "source_bytes"   => 63,
    "sha256"         => "…",
    "app_version"    => "v1.2.3",
    "database"       => null,   // oder ["tables" => 12, "rows" => 4711, …]
    "remote_uploads" => [
        ["target" => "Manage-Server", "type" => "manage", "success" => true, …],
    ],
]

Ein fehlgeschlagener Upload macht das lokale Archiv nicht ungültig: Der Fehler steht in remote_uploads[].error und im Protokoll, die Funktion wirft nicht. Wirft sie doch, ist das Archiv selbst nicht zustande gekommen.

Gleichzeitige Läufe werden über eine Sperrdatei verhindert; der zweite Lauf wirft sofort Es läuft bereits ein Backup.

manageBackupCreateAutomaticIfDue(): ?array

Erstellt ein Backup, wenn seit dem letzten automatischen Backup MANAGE_BACKUP_AUTO_INTERVAL_SECONDS vergangen sind, sonst null. Für Hosting ohne Cron gedacht; gehört auf eine selten geladene Adminseite.

manageBackupList(): array

Lokale Archive, neuestes zuerst. Selbstheilend: Einträge ohne Datei werden entfernt, Größen werden von der Festplatte aktualisiert.

manageBackupUpload(string $archivePath, array $meta = []): array

Lädt ein vorhandenes Archiv zum Manage-Server. Wird von manageBackupCreate() automatisch aufgerufen und ist nur für Sonderfälle einzeln nötig – etwa um ein Archiv nach einem Serverausfall nachzureichen.

manageBackupPath(string $filename): string

Absoluter Pfad eines lokalen Archivs. Validiert den Dateinamen streng, damit ein Download-Formular keinen beliebigen Pfad ausliefern kann.

Heartbeat

manageHeartbeatSend(): array

Meldet Version, PHP-Version, freien Speicher, offene Migrationen und den Zeitpunkt des letzten Backups. Die Antwort enthält nebenbei die Update-Information:

["success" => true, "latest" => "v1.3.0", "update_available" => true, "server_time" => "…"]

manageHeartbeatSendQuietly(): ?array

Wie oben, wirft aber nie und gibt bei Fehlern null zurück. Für Aufrufe innerhalb des Projekts, in denen ein nicht erreichbarer Server folgenlos bleiben soll.

Hilfsfunktionen

Funktion Zweck
manageFormatBytes(int $bytes): string 1.234.567 → 1,18 MB
manageClientLog(string $level, string $message, array $context = []): void Eine Zeile ins Client-Protokoll. Wirft nie
manageRemoteCapabilities(): array Welche konfigurierten Zieltypen dieses System unterstützt

Beispiel

require_once __DIR__ . "/manage-client/lib/client.php";

$check = manageUpdateCheck();
if ($check["available"]) {
    manageBackupCreate("update");          // vor dem Update sichern
    $result = manageUpdateApply();

    if (!$result["hook"]["success"]) {
        // Dateien sind ausgerollt, der Post-Update-Schritt nicht.
        error_log("Migration fehlgeschlagen: " . $result["hook"]["error"]);
    }
}

Ein Backup vor dem Update ist bewusst nicht eingebaut, sondern eine Zeile im Projekt – so bleibt sichtbar, dass es passiert.