Gestion de Workflow dans un projet Symfony2 : Le workflowBundle

Parfois dans un projet on a besoin de garantir un certain enchaînement d’état dans un ordre précis, pour cela la définition d’un workflow s’impose.

Ce bundle a pour intérêt de gérer les transitions de vos objets (produit, document, information etc.) d’une étape à une autre.
En d’autre mots l’automatisation des processus au sein de votre projet et l’historisation des étapes.

Quelques termes à retenir sur le WorkflowBundle:

  • Pour définir un workflow il faut décrire des process
  • Un process est défini par une série d’étapes (step) et on parcourt le process étape par étape
  • Chaque étape doit comporter au moins une transition vers une autre étape à l’exception d’un état final

Le WorkflowBundle fonctionne autour d’un objet model (une entité doctrine par exemple) implémentant une interface ModelInterface

Chaque fois qu’un objet ModelInterface tente d’accéder à une étape, un ModelState sera enregistré en base pour logger les informations et garder une trace des actions. Un ModelState contient un champ spécifique pour récupérer un ModelInterface.

Exemple

Prenons un exemple simple d’un blog, où un utilisateur enregistré peut créer un post et le publier, et où l’administrateur a des droits sur sa validation et sa suppression.

demo   draw.io

Voici la configuration du workflow:

Ce qui peut intéresser le bloggeur c’est de savoir quand sera validé son post, et si il y a eu un refus de savoir pourquoi. Le second avantage consiste également à gérer les droits sur le passage d’une étape à l’autre.

Partons de la première étape, le bloggeur termine son article, le soumet et démarre le processus automatiquement en passant son post dans la première étape draft (brouillon).

step1

Détaillons ce qu’il s’est passé en arrière plan

Pour valider un changement d’état, des events sont dispatchés et peuvent ainsi permettre d’y rapporter des erreurs et invalider le changement d’état.

1. Vérification des droits sur le passage du workflow

  • Le statut de l’objet Post n’évoluera pas si l’utlisateur ne dispose pas des droits requis
  • Si une étape en cas d’erreur (on_invalid) a été renseignée on essayera d’atteindre cette étape

2. Validation de l’étape

  • En cas d’erreur on reproduit le cheminement cité au-dessus en dispatchant un event contenant les informations sur l’étape
  • En cas de réussite une entrée en base est créée (ModelState). Le statut sera mit à jour ou non selon la configuration des paramètres dans le bundle (model_status) et un event sera également dispatché indiquant que l’étape a bien été atteinte

Un exemple de code pour démarrer un workflow et passer à l’étape suivante:

Cas où l’admin valide le post

Tout d’abord le bundle va vérifier que l’on ne tente pas d’atteindre une étape avant d’avoir passé les autres. On valide également que l’étape en cours possède bien le nom de celle à atteindre. (Voir ligne 56 dans le code précédent.)

Rappel: Tout ceci est à déterminer dans votre configuration yaml.

Nous pouvons imaginer que l’admin veuille ajouter une règle de validation automatique qui spécifie un quotas de x Post pour le bloggueur. Pour faire cette vérification il y a les events.

Events

Dans le bundle il existe deux types d’events.

  • StepEvent
  • ValidateStepEvent

Les noms des events sont spécifiques à la configuration du workflow, ils se manifestent sous la forme

  • `process_name.current_step_name.pre_validation`
  • `process_name.current_step_name.pre_validation_fail`
  • `process_name.step_name.bad_credentials`
  • `process_name.step_name.reached`
  • `process_name.step_name.validate`
  • `process_name.step_name.validation_fail`

Le `process_name.current_step_name.pre_validation` est dispatché avant d’essayer d’atteindre l’étape suivante. C’est-à-dire qu’on ne teste pas encore si l’utilisateur a les droits pour déclencher le changement d’étape. En cas d’erreur retourné dans cet event, on ne change pas de statut.

Le `process_name.step_name.bad_credentials` est dispatché lors d’un accès non autorisé par l’utilisateur.

Le `process_name.step_name.validation` est dispatché après la validation des droits de l’utilisateur.

Le `process_name.step_name.reached` est dispatché une fois le changement d’étape effectué.

Pour notre validation nous pouvons utiliser l’event de pré-validation qui retournera une erreur indiquant que le quotas est dépassé.

step2

step3
Ainsi nous disposons de fonctionnalités facilement utilisables pour gérer nos transitions.

https://github.com/lexik/LexikWorkflowBundle

Partagez cet article