Gardes du workflow Symfony : bloquer une transition

Une garde, dans le composant Workflow de Symfony, bloque une transition selon une condition : le rôle de l'utilisateur, une date, l'état de l'objet.

// workflow.yaml, sous la transition « annuler » : guard: "is_granted('ROLE_PATRON')"

#[AsGuardListener(workflow: 'reservation', transition: 'honorer')]
public function __invoke(GuardEvent $event): void
{
    $reservation = $event->getSubject();

    if ($reservation->getJour() > $this->horloge->now()->setTime(0, 0)) {
        $event->addTransitionBlocker(new TransitionBlocker('Le repas n\'a pas encore eu lieu.', 'pas-avant-le-repas'));
    }
}

Une règle simple tient dans une expression guard de la configuration, évaluée avec l'utilisateur connecté. Une règle qui demande du code devient un écouteur #[AsGuardListener], qui reçoit un GuardEvent et refuse avec addTransitionBlocker(). La garde s'applique partout : can(), apply(), et workflow_transitions() dans Twig, qui ne propose alors que les boutons permis. Pour expliquer un refus, buildTransitionBlockerList() rend les TransitionBlocker et leurs messages ; apply() sur une transition bloquée lève une NotEnabledTransitionException, d'où le can() préalable. Le piège : une comparaison fausse d'un caractère, >= au lieu de >, et la transition reste bloquée le jour même. Rien ne casse, le bouton disparaît simplement.

Les exercices font brancher les boutons du registre de Gorm sur le workflow des réservations, réserver l'annulation au patron et refuser d'honorer une réservation avant son jour, avec un message qui dit pourquoi ; puis retrouver, dans un registre « simplifié », pourquoi une réservation ne peut plus être honorée le soir même.

2 exercices font travailler cette notion, en écrivant du code dans le navigateur.

Dans les parcours

Notions voisines

DébogageWorkflowÉvénements du workflowMailer