Direkte Ansicht der SDK-Dokumentation aus `vendor/README.md`.
# Leitwerk PHP SDK
Dieses ZIP enthält ein kleines PHP-7.4-kompatibles SDK für die serverseitige Arbeit mit Leitwerk.
## Ziel
Das SDK ist bewusst ohne Composer aufgebaut. Du kannst die `.php`-Dateien direkt in dein Projekt legen und sofort verwenden.
Aktuelle SDK-Version: `1.0.0`
## Enthalten
- Log-Ingest über `POST /api/ingest/logs`
- Namespace-Filter für Logs über `LeitwerkLogConfig`
- Push-SDK-Bootstrap über `GET /sdk/v1/bootstrap`
- VAPID-Key über `GET /api/push/vapid-public-key`
- Quell-Apps über `GET /api/push/source-apps`
- Push-Clients und Client-Keys
- Subscriptions speichern und löschen
- Trigger für Push-Versand
- Push-Nachrichten laden, anlegen und aktualisieren
## Voraussetzungen
- PHP 7.4
- cURL-Erweiterung
- JSON-Erweiterung
## Installation ohne Composer
1. ZIP herunterladen und entpacken.
2. Den Ordner `leitwerk-php-sdk` in dein Projekt kopieren.
3. Die Datei `leitwerk.php` einbinden.
```php
<?php
require __DIR__ . '/leitwerk-php-sdk/leitwerk.php';
use LeitwerkSdk\LeitwerkClient;
use LeitwerkSdk\LeitwerkLogConfig;
$leitwerk = new LeitwerkClient(
'https://leitwerk.example.com',
'dein-kunden-api-key',
15,
LeitwerkLogConfig::fromArray([
'allowedNamespaces' => [
'sync.orders.*',
'billing.invoice.created',
],
])
);
```
Optional kannst du als drittes Argument ein Timeout in Sekunden und als viertes Argument eine `LeitwerkLogConfig` setzen:
```php
<?php
$leitwerk = new LeitwerkClient(
'https://leitwerk.example.com',
'dein-kunden-api-key',
30
);
```
Wenn du später mit einem anderen Kunden-API-Key weiterarbeiten willst, nutze `withCustomerApiKey()`.
```php
<?php
$mandantA = new LeitwerkClient('https://leitwerk.example.com', 'api-key-a');
$mandantB = $mandantA->withCustomerApiKey('api-key-b');
```
## Schnellstart
### Log senden
```php
<?php
$response = $leitwerk->sendLog([
'message' => 'Synchronisierung gestartet',
'level' => 'info',
'namespace' => 'sync.orders.import',
'source' => 'php-worker',
'meta' => [
'batchId' => 42,
],
]);
if (!empty($response['skipped'])) {
var_dump('Log wurde lokal uebersprungen');
}
```
### Log-Namespaces per Konfiguration begrenzen
Die Log-Konfiguration arbeitet mit einer Punktnotation fuer Namespaces.
- `billing.invoice.created` erlaubt genau diesen Namespace
- `billing.invoice.*` erlaubt alle Unterbereiche wie `billing.invoice.failed`
- `billing.*` erlaubt alle tieferen Namespaces unterhalb von `billing`
Wichtig:
- `billing.*` matcht `billing.invoice.created`, aber nicht den nackten Namespace `billing` selbst.
- Wenn du auch `billing` selbst erlauben willst, brauchst du zusaetzlich die exakte Regel `billing`.
Beispiel fuer beides zusammen:
```txt
billing
billing.*
```
```php
<?php
use LeitwerkSdk\LeitwerkClient;
use LeitwerkSdk\LeitwerkLogConfig;
$logConfig = LeitwerkLogConfig::fromArray([
'allowedNamespaces' => [
'auth.login.*',
'sync.orders.*',
'billing.invoice.created',
],
]);
$leitwerk = new LeitwerkClient(
'https://leitwerk.example.com',
'dein-kunden-api-key',
15,
$logConfig
);
```
Wenn ein Log nicht in die erlaubten Regeln faellt, sendet `sendLog()` nichts an Leitwerk und gibt stattdessen lokal eine Skip-Antwort zurueck:
```php
<?php
[
'ok' => true,
'skipped' => true,
'sent' => false,
'reason' => 'namespace_not_allowed',
'namespace' => 'auth.logout',
]
```
### Push-Client mit Key anlegen
```php
<?php
$response = $leitwerk->createPushClient([
'firstName' => '',
'lastName' => '',
'label' => 'Hausmeister Nord',
'sourceApp' => 'hausmeister-app',
'externalRecipientKey' => 'hausmeister-nord',
]);
$clientKey = $response['plainTextKey'];
```
### Trigger senden
```php
<?php
$leitwerk->trigger([
'appId' => 'hausmeister-app',
'title' => 'Neue Aufgabe',
'body' => 'Bitte Eingangstür prüfen.',
'recipients' => [
'externalRecipientKeys' => ['hausmeister-nord'],
],
]);
```
## Browser-Flow
Wenn du für einen Browser einen `clientKeyEndpoint` bereitstellen willst, schau dir `examples/client-key-endpoint.php` an. Das Beispiel erzeugt serverseitig einen Push-Client-Key und gibt nur `{ clientKey }` an den Browser zurück.
## Methodenreferenz
### `__construct(string $baseUrl, ?string $customerApiKey = null, int $timeoutSeconds = 15, ?LeitwerkLogConfig $logConfig = null)`
- setzt Basis-URL, optionalen Standard-Kunden-API-Key und Timeout
- akzeptiert optional eine `LeitwerkLogConfig` fuer erlaubte Log-Namespaces
- entfernt einen abschließenden Slash in der Basis-URL automatisch
### `withCustomerApiKey(string $customerApiKey): self`
- gibt eine neue Client-Instanz mit anderem Standard-Kunden-API-Key zurück
- verändert die bestehende Instanz nicht
### `withLogConfig(LeitwerkLogConfig $logConfig): self`
- gibt eine neue Client-Instanz mit Log-Filter-Regeln zurück
- praktisch, wenn nur ein Teil deines Codes Logs senden darf
### `getVapidPublicKey(): array`
- lädt den öffentlichen VAPID-Key
- braucht keinen API-Key
### `getSdkBootstrap(array $query = []): array`
- lädt Bootstrap-Daten für SDK- oder Browser-Flows
- gibt das Query-Array unverändert als Query-Parameter weiter
### `getSourceApps(?string $apiKey = null): array`
- lädt die verfügbaren Quell-Apps
- nutzt den übergebenen oder den Standard-Kunden-API-Key
### `sendLog(array $payload, ?string $apiKey = null): array`
- sendet Logs an `POST /api/ingest/logs`
- typischer Payload: `message`, `level`, `namespace`, `source`, optional `meta`
- wenn eine `LeitwerkLogConfig` gesetzt ist, werden nur erlaubte Namespaces gesendet
- nicht erlaubte Logs werden lokal uebersprungen und nicht an Leitwerk uebertragen
### `shouldSendLog(array $payload): bool`
- prueft vorab, ob ein Log anhand der `LeitwerkLogConfig` gesendet werden darf
- liefert ohne gesetzte Log-Konfiguration immer `true`
### `createPushClient(array $payload, ?string $apiKey = null): array`
- legt einen Push-Client an
- liefert die API-Antwort unverändert zurück, inklusive `plainTextKey`, falls vorhanden
### `createBrowserClientKey(array $recipient, string $appId, ?string $apiKey = null): array`
- ergänzt automatisch `sourceApp` aus `appId`
- entfernt leere `externalRecipientKey`-Werte
- gibt eine browserfreundliche Antwort mit `clientKey`, `client`, `apiKey` und `plainTextKey` zurück
### `registerPushClient(array $payload, ?string $apiKey = null): array`
- registriert einen Client über den SDK-Endpunkt
- akzeptiert Kunden-API-Key oder Push-Client-Key
### `saveSubscription(array $payload, string $pushClientKey): array`
- speichert eine Subscription
- erwartet explizit einen Push-Client-Key
### `deleteSubscription(array $payload, string $pushClientKey): array`
- löscht eine Subscription
- erwartet ebenfalls explizit einen Push-Client-Key
### `trigger(array $payload, ?string $apiKey = null): array`
- löst Push direkt aus deinem Backend aus
- erwartet einen Kunden-API-Key
### `listNotifications(array $query = [], ?string $apiKey = null): array`
- lädt vorhandene Push-Nachrichten mit optionalen Filtern
- typische Query-Felder sind zum Beispiel `sourceApp` und `page`
### `getNotification(int $notificationId, ?string $apiKey = null): array`
- lädt eine einzelne Push-Nachricht per ID
- erwartet die numerische Notification-ID als erstes Argument
### `createNotification(array $payload, ?string $apiKey = null): array`
- legt eine neue Push-Nachricht an
- gibt den Payload unverändert an die API weiter
### `updateNotification(int $notificationId, array $payload, ?string $apiKey = null): array`
- aktualisiert eine bestehende Push-Nachricht
- erwartet zuerst die numerische Notification-ID und danach den Update-Payload
## Weitere Beispiele
- `examples/create-notification.php`
- `examples/list-notifications.php`
## Fehlerbehandlung
Bei API-Fehlern wirft das SDK `LeitwerkApiException`.
Damit bekommst du direkt:
- HTTP-Statuscode
- Raw-Response
- dekodierte JSON-Response, falls vorhanden
- `InvalidArgumentException`, wenn ein notwendiger Kunden-API-Key fehlt
- `RuntimeException` bei cURL-Fehlern, ungültigem JSON oder fehlendem `plainTextKey`
## Hinweis für diese App
Das ZIP wird beim Download direkt aus den Dateien in `resources/php-sdk/leitwerk-php-sdk` erzeugt. Wenn du dort etwas änderst, ist es sofort im nächsten Download enthalten.