Symfony 6 : Utiliser le composant Workflow

S

Si vous avez besoin de gérer des processus métier (tel qu’une gestion de commande, gestion de demande de congés ou encore des articles de publication) dans votre application Symfony, le composant Workflow pourrait bien vous être utile.

L’utilisation de ce composant est relativement simple, nous allons procéder par étapes :

  1. Création de votre entité (commande, congés, article, …)
  2. Configuration du Workflow
  3. Utilisation du Workflow

Pour utiliser notre workflow, on va déjà avoir besoin du composant workflow :

composer require symfony/workflow

Pour la création de l’entité on va faire simple, on va modéliser une commande (d’une boutique en ligne), elle n’aura que 2 propriétés : un numéro et un état, c’est cette dernière qui nous servira pour le workflow.

class Commande
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column]
    private ?int $numeroCommande = null;

    #[ORM\Column(length: 255)]
    private ?string $etatCommande = null;

Voici la configuration de notre workflow, je mettrai en dessous à quoi correspond chaque ligne :

# config/packages/workflow.yaml

framework:
    workflows:
        commande:
            type: state_machine
            marking_store:
                type: 'method'
                property: 'etatCommande'
            supports:
                - App\Entity\Commande
            initial_marking: brouillon
            places:
                - brouillon
                - finalisee
                - rejetee
                - payee
            transitions:
                creation:
                    from: brouillon
                    to: finalisee
                rejet:
                    from: finalisee
                    to: rejetee
                payee:
                    from: finalisee
                    to: payee

la ligne « commande » est importante car c’est le nom du workflow, et ce sera surtout utile lorsque l’on va injecter la dépendance, ça va donner dans notre cas : WorkflowInterface $commandeStateMachine
La ligne marking_store va faire référence à la propriété de notre entité qui stockera l’etat de la commande (ici « etatCommande »)
La ligne supports, facile, c’est notre entité.
initial_marking = l’état initial de notre entité.
places : liste des états dans lesquels pourra être l’entité.
transitions : liste de vos transitions, c’est-à-dire dans quel état est l’entité et dans quel état elle peut arriver.

Pour utiliser le workflow on va créer une commande qui ressemblera à ceci :

<?php

namespace App\Command;

use App\Entity\Commande;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Workflow\WorkflowInterface;

#[AsCommand(
    name: 'app:commande',
    description: 'test du workflow commande',
)]
class CommandeCommand extends Command
{
    public function __construct(readonly WorkflowInterface $commandeStateMachine)
    {
        parent::__construct();
    }

    protected function configure(): void
    {
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        //On créé une commande
        $comm = new Commande();
        $comm->setNumeroCommande(1);
        $comm->setEtatCommande('brouillon');
        
        //On affiche son état (ici "brouillon")
        $io->text($comm->getEtatCommande());

        //On teste si la commande peut effectuer la transition de brouillon à finalisee
        //Si vrai alors on pourra effectuer la transition
        $res = $this->commandeStateMachine->can($comm, 'creation');
        $io->text($res);

        //on effectue la transition
        $this->commandeStateMachine->apply($comm, 'creation');

        //On affiche son etat
        $io->text($comm->getEtatCommande());

        //On veut effectuer la transition creation
        //Ici ça ne fonctionnera pas car la commande est déjà en etat finalisée
        $this->commandeStateMachine->apply($comm, 'creation');
        
        return Command::SUCCESS;
    }
}

J’ai commenté la commande et comme vous pouvez le voir il n’y a rien de compliqué à utiliser le workflow et ça permet de bien cadrer les process métiers.

Petit bonus, vous pouvez exporter votre workflow vers une image :

bin/console workflow:dump commande | dot -Tpng -o workflow.png

pour pouvoir exécuter « dot » il faut installer Grapviz.

Et voici ce que ça nous donne :

A propos de l'auteur

Ajouter un commentaire

Guillaume

Get in touch

Je suis un développeur web passionné par les technologies Symfony et ChatGPT. J'aime partager mes connaissances et mon expérience à travers des articles que j'écris sur ces sujets. Avec une solide expertise en développement web, je m'efforce de fournir des contenus utiles et instructifs pour aider les développeurs à créer des applications web de qualité supérieure.