
# Триггеры действий

`Queuety::on_action()` позволяет превратить обычное действие WordPress в запуск надежного рабочего процесса.

Это создает удобный переход:

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

Это полезно, когда нужное событие уже возникает в WordPress, а затратная или длительная обработка должна выполняться асинхронно.

## Пример: проверка содержимого при сохранении записи

```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}",
);
```

В этом примере:

- `save_post` — это исходное событие WordPress
- `map` преобразует необработанные аргументы хука в простое состояние рабочего процесса
- `when` отсеивает ненужные события до постановки в очередь
- `idempotency_key` не дает повторным вызовам хука запускать дубликаты

## Что выполняется синхронно

Сам обработчик действия по-прежнему выполняется в рамках текущего запроса WordPress.

Это значит, что синхронно выполняются следующие части:

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

Только шаги рабочего процесса выполняются асинхронно после его запуска.

## Правила для данных

Сопоставленные данные должны содержать простые массивы, скалярные значения и `null`.

Не передавайте необработанные объекты WordPress, например `WP_Post`, прямо в состояние рабочего процесса. Сначала нормализуйте их в `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,
    ],
);
```

Ключи, начинающиеся с `_`, отклоняются, поскольку такие имена зарезервированы для внутреннего состояния рабочего процесса.

## Допустимые аргументы

WordPress требуется число `accepted_args` при регистрации обработчика действия.

По умолчанию Queuety определяет его по вашим обработчикам `map`, `when` и `idempotency_key`, поэтому в обычном случае дополнительная настройка не нужна:

```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,
    ],
);
```

Если нужно задать значение вручную, явно передайте `accepted_args`:

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

## Встроенные конструкторы рабочих процессов

Можно запустить зарегистрированный рабочий процесс по имени или использовать встроенный `WorkflowBuilder`.

Встроенные конструкторы удобны, когда рабочий процесс для конкретного хука определен в том же файле начальной настройки:

```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}",
);
```

## Когда этот подход подходит

Используйте триггеры действий, если:

- WordPress уже создает нужное вам событие
- обработка должна переживать тайм-ауты запросов или перезапуски исполнителя
- последующая работа может ветвиться, ожидать или требовать согласования
- для защиты от повторных вызовов хука нужна надежная идемпотентность

Вместо этого используйте прямой вызов `Queuety::dispatch()` или `Queuety::workflow()`, если работа не связана с границей события WordPress.

## Не для фильтров

`Queuety::on_action()` предназначен только для действий.

Фильтры — это синхронные преобразования во время обработки запроса. Обычно их следует выполнять синхронно, поскольку WordPress ожидает немедленного возврата отфильтрованного значения.
