Branchement conditionnel
Les workflows peuvent passer à une étape nommée en fonction du résultat d’une étape précédente. Pour cela, l’étape renvoie une clé spéciale _next_step.
Si vous souhaitez précisément revenir à une étape précédente en fonction de l’état du workflow, consultez Répétitions. La boucle arrière reste ainsi explicite dans la définition du workflow au lieu d’être dissimulée dans une classe d’étape.
Étapes nommées
Nommez les étapes à l’aide du deuxième argument de ->then() :
use Queuety\Queuety;
Queuety::workflow( 'process_order' )
->then( ValidateOrderHandler::class, 'validate' )
->then( ChargePaymentHandler::class, 'charge' )
->then( FulfillOrderHandler::class, 'fulfill' )
->then( SendConfirmationHandler::class, 'confirm' )
->then( HandleFailureHandler::class, 'failure' )
->dispatch( [ 'order_id' => 123 ] );
Sans nom explicite, les étapes sont nommées selon leur index ('0', '1', '2', etc.).
La clé _next_step
Une étape peut renvoyer _next_step pour passer à une étape nommée et ignorer toutes celles qui la séparent de la cible. Les étapes situées après la cible s’exécutent toujours dans l’ordre : en l’absence de saut, le workflow passe simplement à l’étape suivante de la liste. Ainsi, dans l’exemple ci-dessus, une étape confirm réussie passe à failure, sauf si elle renvoie un _next_step qui l’ignore ou si HandleFailureHandler vérifie d’abord la présence d’une clé error :
use Queuety\Step;
class ValidateOrderHandler implements Step {
public function handle( array $state ): array {
$order = wc_get_order( $state['order_id'] );
if ( ! $order || $order->get_status() === 'cancelled' ) {
return [
'error' => 'Order is invalid or cancelled',
'_next_step' => 'failure',
];
}
return [
'order_total' => $order->get_total(),
'customer_id' => $order->get_customer_id(),
];
}
public function config(): array {
return [];
}
}
Lorsque ValidateOrderHandler renvoie _next_step => 'failure', le workflow ignore charge, fulfill et confirm, puis passe directement à l’étape failure. La clé _next_step est consommée par le moteur de workflow et n’est pas conservée dans l’état.
Modèles de branchement
Ignorer sous condition
class CheckInventoryHandler implements Step {
public function handle( array $state ): array {
$in_stock = check_inventory( $state['sku'] );
if ( ! $in_stock ) {
return [
'reason' => 'Out of stock',
'_next_step' => 'notify_backorder',
];
}
return [ 'inventory_reserved' => true ];
}
public function config(): array {
return [];
}
}
Terminaison anticipée
Passez à la dernière étape pour ignorer le traitement inutile :
class CheckCacheHandler implements Step {
public function handle( array $state ): array {
$cached = get_transient( "report_{$state['user_id']}" );
if ( $cached ) {
return [
'report_url' => $cached,
'_next_step' => 'done',
];
}
return [ 'cache_miss' => true ];
}
public function config(): array {
return [];
}
}
Exemple complet
Queuety::workflow( 'content_pipeline' )
->then( CheckCacheHandler::class, 'check_cache' )
->then( FetchDataHandler::class, 'fetch' )
->then( CallLLMHandler::class, 'generate' )
->then( SaveResultHandler::class, 'save' )
->then( ReturnCachedHandler::class, 'done' )
->dispatch( [ 'user_id' => 42 ] );
Si la vérification du cache trouve une entrée, le flux de travail passe directement de check_cache à done, en ignorant fetch, generate et save. En cas d’absence, les étapes s’exécutent dans l’ordre et save se poursuit également jusqu’à done ; ReturnCachedHandler doit donc gérer les deux parcours.