• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Jeu de la vie et rendus de la mort
Jeu de la vie et rendus de la mort
9 septembre 2019
Exprimez vos émotions en regex !
Exprimez vos émotions en regex !
24 octobre 2019
Ressources > Articles techniques > Simplifiez vos applications avec le composant Workflow de Symfony

Simplifiez vos applications avec le composant Workflow de Symfony

Article écrit par Benoit Delesalle

Quand on doit mettre en place un workflow dans une application web, on peut rapidement se perdre lorsqu’il s’agit de le manipuler. Dans cet article, nous allons voir comment se simplifier la vie en utilisant le composant Workflow dans une application Symfony.

Mais dis-moi Jamy, c’est quoi un workflow ?

Un workflow, c’est tout simplement un ensemble de règles qui régit un processus de notre application. Prenons un exemple pour mieux comprendre.

Imaginons que notre application soit un site e-commerce et que nous devons gérer l’état d’une commande. Pour cet exemple, on peut se dire que les états possibles d’une commande sont les suivants :

  • created : lorsqu’un client ajoute des produits à son panier.
  • waiting_for_payment : lorsque le client a validé son panier mais qu’il n’a pas encore payé sa commande.
  • awaiting_delivery : lorsque le client a payé sa commande mais qu’elle n’a pas encore été prise en compte par la société de livraison.
  • in_delivering : lorsque la commande a été prise en charge par la société de livraison.
  • delivered : lorsque la commande est bien arrivée à destination.
  • canceled : lorsque le client a annulé sa commande ou a abandonné son panier.

Maintenant que nous avons nos états, nous devons nous demander comment passer de l’un à l’autre. Dans notre exemple, nous ne pouvons pas passer de l’état « waiting_for_payment » à l’état « in_delivering » sans avoir reçu le paiement en question. Nous allons donc devoir définir les règles de changement d’état. Notre workflow pourrait donc ressembler à ceci.

Maintenant imaginons ce workflow dans notre application. Pour chaque changement d’état, il va falloir vérifier si ce changement est possible ou non, cela risque de nous procurer des heures de développement à se tirer les cheveux. Si seulement il existait une solution pour nous simplifier la vie. Mais attendez ! Elle existe cette solution, c’est le composant Workflow de Symfony.

Le composant Workflow

Pour cet article, nous supposons que notre application Symfony est en version 4.3. Dans un premier temps, installons le composant avec composer.

$ composer install symfony/workflow 

Symfony vous crée un fichier de configuration de base qui ressemble à ceci :

# config/packages/workflow.yaml  framework :   workflows : null 

C’est dans ce fichier de configuration que nous allons définir tous nos workflows, leurs états possibles et comment passer d’un état à un autre. Ajoutons donc notre workflow concernant nos commandes.

# config/packages/workflow.yaml  framework :   workflows :     order :       type : 'state_machine'       marking_store :         type : 'method'         property : 'state'       supports :         - AppEntityOrder 

Arrêtons-nous sur cette configuration. Nous avons donc créé un workflow qui se nomme order et qui est de type state_machine. Il en existe deux types :

  • state_machine
  • workflow

En soi, un state_machine est un workflow avec quelques différences :

  • un objet dans un state_machine ne peut avoir qu’un seul état à la fois contrairement à un workflow.
  • le state_machine est dit cyclique, c’est-à-dire que notre objet peut revenir dans un état qu’il a déjà connu, ce que ne peut pas faire un workflow.

Cela sous-entend également qu’un objet dans un workflow doit avoir connu tous les états précédents avant de passer à un nouvel état alors que le state_machine doit être dans au moins un de ces états.

Ensuite, nous avons défini avec l’option marking_store la manière dont nous voulons stocker l’état actuel de notre objet. Ici, cela veut simplement dire que nous allons stocker l’état dans un attribut state de notre objet en utilisant une méthode setState.

Finalement, nous avons indiqué les objets qui suivent ce workflow avec l’option supports, ici il n’y a que notre entité AppEntityOrder.

Tout cela est bien beau, mais comment définir les états possibles ? C’est très simple, allons voir cela de ce pas.

# config/packages/workflow.yaml  framework :   workflows :     order :       type : 'state_machine'       marking_store :         type : 'method'         property : 'state'       supports :         - AppEntityOrder       initial_marking : created       places :         - created         - waiting_for_payment         - awaiting_delivery         - in_delivering         - delivered         - canceled 

Dans places, nous avons listé tous les états que peut prendre notre commande et nous avons spécifié dans initial_marking l’état de départ de notre objet.

Il ne nous reste plus qu’à préciser nos transitions, c’est-à-dire les règles de mouvement entre chaque état.

# config/packages/workflow.yaml  framework :   workflows :     order :       type : 'state_machine'       marking_store :         type : 'method'         property : 'state'       supports :         - AppEntityOrder       initial_marking : created       places :         - created         - waiting_for_payment         - awaiting_delivery         - in_delivering         - delivered         - canceled       transitions :         add_product_to_cart :           from : created           to : created         confirm_order :           from : created           to : waiting_for_payment         pay_order :           from : waiting_for_payment           to : awaiting_delivery         accept_delivery :           from : awaiting_delivery           to : in_delivering         delivery_done :           from : in_delivering           to : delivered         cancel_order :           from : [created, waiting_for_payment]           to : canceled 

Avec ces règles, il me sera désormais impossible de passer à un état in_delivering sans passer par la case paiement.

Vous pouvez désormais utiliser votre workflow dans votre application en injectant directement le Registry du composant Workflow dans votre constructeur et en récupérant votre workflow par son nom en lui passant l’objet sur lequel vous souhaitez l’appliquer.

<?php  // src/Controller/OrderController.php  namespace AppController ;  use AppEntityCommande ; use SymfonyBundleFrameworkBundleControllerAbstractController ; use SymfonyComponentRoutingAnnotationRoute ; use SymfonyComponentWorkflowRegistry ;  class OrderController extends AbstractController {     /**      * @var Registry      */     private $workflows ;      public function __construct(Registry $workflows)     {         $this->workflows = $workflows ;     }      /**      * @Route("/order", name="order")      */     public function order()     {         $order = new Order();         $workflow = $this->workflows->get($order, 'order');     } } 

Grâce à ce workflow, vous pouvez désormais vérifier simplement si votre commande peut passer à un état particulier et lui appliquer cet état en procédant comme ceci :

<?php      if($workflow->can($order, 'pay_order')) {         // votre code          $workflow->apply($order, 'pay_order');     } 

Vous pouvez également utiliser ces conditions dans vos templates twig.

{% if workflow_can(order, 'pay_order') %}     <a href="...">Payer la commande</a> {% endif %} 

Voilà, vous savez désormais comment vous faciliter la vie pour vos workflows.

Dans un prochain article, nous verrons comment aller plus loin en utilisant les événements liés aux workflows pour vraiment profiter de la puissance de ce composant.

Ressources

  • Site officiel de Symfony (en)
  • Documentation du composant Workflow (en)

À lire aussi

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique

Lire la suite

intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 

Lire la suite

Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 

Lire la suite

image miniature les nouveautés Atlassian
26 février 2025

Les nouveautés Atlassian en 2025

Lire la suite

Articles associés

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite
intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 


Lire la suite
Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter