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 :
- Création de votre entité (commande, congés, article, …)
- Configuration du Workflow
- 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 :