
# Aktionsauslöser

Mit `Queuety::on_action()` kannst du eine normale WordPress-Aktion in den Start eines dauerhaften Workflows umwandeln.

So entsteht eine direkte Verbindung:

`WordPress action -> mapped payload -> durable workflow`

Das ist nützlich, wenn das relevante Ereignis bereits in WordPress vorliegt und die aufwendige oder lang laufende Reaktion asynchron erfolgen soll.

## Beispiel: Inhalte prüfen, wenn ein Beitrag gespeichert wird

```php
use Queuety\Queuety;

Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'post_type' => $post->post_type,
        'update' => $update,
    ],
    when: static fn ( int $post_id, object $post ): bool => 'post' === $post->post_type,
    idempotency_key: static fn ( int $post_id ): string => "save_post:{$post_id}",
);
```

In diesem Beispiel gilt:

- `save_post` ist weiterhin das ursprüngliche WordPress-Ereignis
- `map` wandelt rohe Hook-Argumente in einfachen Workflow-Zustand um
- `when` überspringt unerwünschte Ereignisse, bevor etwas eingereiht wird
- `idempotency_key` verhindert, dass wiederholte Hook-Aufrufe doppelte Läufe starten

## Was synchron ausgeführt wird

Der Aktions-Callback selbst wird weiterhin innerhalb der aktuellen WordPress-Anfrage ausgeführt.

Das bedeutet, dass diese Teile synchron ablaufen:

- `when`
- `map`
- `idempotency_key`

Nur die Workflow-Schritte laufen nach dem Start asynchron.

## Regeln für Nutzdaten

Zugeordnete Nutzdaten sollten einfache Arrays, Skalare und `null` enthalten.

Übergib keine rohen WordPress-Objekte wie `WP_Post` direkt an den Workflow-Zustand. Normalisiere sie zuerst innerhalb von `map()`:

```php
Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'post_type' => $post->post_type,
        'post_status' => $post->post_status,
        'update' => $update,
    ],
);
```

Schlüssel, die mit `_` beginnen, werden abgelehnt, weil diese Namen für den internen Workflow-Zustand reserviert sind.

## Zulässige Argumente

WordPress benötigt beim Registrieren eines Aktions-Callbacks eine Anzahl von `accepted_args`.

Standardmäßig leitet Queuety diesen Wert aus deinen Callbacks `map`, `when` und `idempotency_key` ab. Im üblichen Fall ist also keine zusätzliche Konfiguration nötig:

```php
Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'update' => $update,
    ],
);
```

Wenn du den Wert manuell überschreiben musst, übergib `accepted_args` ausdrücklich:

```php
Queuety::on_action(
    'comment_post',
    workflow: 'comment_review',
    accepted_args: 2,
);
```

## Inline-Workflow-Ersteller

Du kannst einen registrierten Workflow-Namen oder einen Inline-`WorkflowBuilder` starten.

Inline-Ersteller sind nützlich, wenn der Hook-spezifische Workflow in derselben Bootstrap-Datei definiert ist:

```php
$review = Queuety::workflow( 'comment_review' )
    ->then( ModerateCommentStep::class )
    ->then( NotifyModeratorStep::class );

Queuety::on_action(
    'comment_post',
    workflow: $review,
    map: static fn ( int $comment_id ): array => [
        'comment_id' => $comment_id,
    ],
    idempotency_key: static fn ( int $comment_id ): string => "comment:{$comment_id}",
);
```

## Wann sich das eignet

Verwende Aktionsauslöser, wenn:

- WordPress das gewünschte Ereignis bereits auslöst
- die Reaktion Anforderungs-Zeitüberschreitungen oder Neustarts von Workern überstehen soll
- die Folgeaufgabe verzweigt werden, warten oder eine Freigabe benötigen kann
- doppelte Hook-Aufrufe dauerhaft idempotent behandelt werden müssen

Verwende stattdessen einen direkten Aufruf von `Queuety::dispatch()` oder `Queuety::workflow()`, wenn die Arbeit nicht an eine WordPress-Ereignisgrenze gebunden ist.

## Nicht für Filter

`Queuety::on_action()` ist bewusst nur für Aktionen vorgesehen.

Filter sind synchrone Umwandlungen während einer Anfrage. Sie sollten in der Regel synchron bleiben, weil WordPress erwartet, dass ein gefilterter Wert sofort zurückgegeben wird.
