
# Тригери дій

`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 очікує, що відфільтроване значення буде повернуто негайно.
