2. Hamza Amrouche
Lead Dev Symfony chez Les-Tilleuls.coop
Core Team Api-Platform
Contributeur à Symfony
@cDaed
@Simperfit
Bureau étendu AFUP
3. Les-Tilleuls.coop
Une coopérative depuis 2011
Appartient à 100% à ses employés
22 coopérateurs, 97% de croissance en 2016
On recrute à Amiens, Lille, Paris et Londres:
jobs@les-tilleuls.coop
13. Contexte Quotatis
Quotatis permet aux personnes qui souhaitent faire des
travaux de créer des projets, ceux-ci ont plusieurs états.
Pour atteindre ces états il y a des conditions, qui ne sont
remplies que si le projet est prêt.
14. Merci au Workflow !
Le composant nous permet de garantir que les projets
qui sont dans certains états ont bien passé toutes les
règles de validation.
19. Les events !
public static function getSubscribedEvents(): array
{
return [
'workflow.project.enter.to_validate'=> ['assignUser'],
'workflow.project.entered.validated' => ['sendToLegacy'],
];
}
20. Le guard Event
use SymfonyComponentWorkflowEventGuardEvent;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
class BlogPostReviewListener implements EventSubscriberInterface
{
public function guardReview(GuardEvent $event)
{
$post = $event->getSubject();
$title = $post->title;
if (empty($title)) {
// Posts with no title should not be allowed
$event->setBlocked(true);
}
}
public static function getSubscribedEvents()
{
return ['workflow.blogpost.guard.to_review' => ['guardReview']];
}
}
22. La vue
{# Or loop through the enabled transitions #}
{% for transition in workflow_transitions(post) %}
<a href="...">{{ transition.name }}</a>
{% endfor %}
24. En mode API
On a plusieurs services qui mettent à jour le statut :
L’utilisateur à travers l’appli :
Scenario: As authenticated user, I can set the project's status to "to_validate"
Given I am authenticated as user
And there is a newly created project
When I set the project's status to "to_validate"
Then I should get a project
And the status should be "to_validate"
And I should be assigned to the project
La « Legacy » qui transforme le projet en « found » lorsque le projet a
trouvé son artisan.
L’API elle-même qui transforme le projet en « pending_search » lorsque
qu’un appel à l’api « Legacy » est fait.
25. En mode API
private function checkStatusWorkflow(Project $data)
{
$content = json_decode($request->getContent(), true);
if (null === $status = $content['status'] ?? null
|| $userProject->getStatus() === $status) {
return;
}
if (true === $this->projectWorkflow->can($data, $status)) {
$this->projectWorkflow->apply($data, $status);
return;
}
throw new BadRequestHttpException('status.not_in_workflow');
}
32. <?php
interface WorkflowInterface
{
public function getMarking($subject);
public function can($subject, $transitionName);
public function apply($subject, $transitionName);
public function getEnabledTransitions($subject);
public function getName();
public function getDefinition();
public function getMarkingStore();
}
35. Merci à vous !
🍺🍺🍺🍺
Twitter : @cDaed
Les slides :
Notes de l'éditeur
——-
Le composant workflow est un composant qui a été introduit dans symfony en version 3.2 par Grégoire Pineau et Fabien Potencier. Il est donc déjà bien présent dans la version de 3 de symfony et va évolué avec les version 4.1 de symfony.
Il va permettre par exemple de gérer des cas d’utilisations comme la publication d’articles sur un blog. L’article crée va avoir comme status « brouillon », lorsqu’il sera prêt l’article va passer en status « en attente d’approbation » afin que le relecteur relise l’article, une fois que cela est fait, l’article passera dans un status publié. Et derrière, tout cela on peut avoir une machine à états qui va faire la transitions et nous permettre de vérifié que lorsque l’article doit passer du status en attente d’approbation au status publié, via des règles de validation, qu’il y ai bien le bon nombre de relecteur, ici 1.
Voici donc un workflow classique
Dans ce cas, on est obliger de passer par t0 pour aller A ou B vers C tout en gardant la même transitions. même choses de B vers C ou D.
La machine à états permet de transitionné aussi mais avec des transitions bien précise pour chaque états.
On peut aussi représenté la machine a état comme ceci, cela va nous permettre ensuite de comprendre comment cela fonctionne avec le composant workflow.
On a deux façon de définir notre configuration pour notre workflow, la première est vraiment en créeant les objets en PHP, donc notre objet Definition à 3 arguments, le premier étant les places possible, le second va contenir nos transitions, dans le cas présent, il s’agit de notre première transition de l’états complétion_in_progress à l’état to_validate, cette transition se nomme donc comme l’états d’arrivée, et on va voir plus tard pourquoi. Le 3éme arguments est l’états de base.
Voici la configuration en YAML qui permet via Symfony de directement déclarer notre workflow. Ceci est un exemple qui rentre un peu plus dans les détails, avec le support de l’object et la declaration du marking_store, je ne reviens pas sur chaqu’une des clés on peut en discuté après, tout est dans la documentation de Symfony.
Voici comment on va débug notre graph, via une commande qui est directement dans symfony va nous permettre de dumpé notre graph. On a avoir besoin de dot qui est inclue dans Graphviz
Maintenant que vous savez comment déclarer votre workflow et comment le débugger, passons à sont utilisation réel dans un context projet qui est le context de Quotatis.
Voici notre workflow en production chez quotatis, notre projet pourra toujours atteindre le status aborted car à tous moment du flow, il peut être annulé.
Le can va nous permettre de savoir si on a le droit de passer d’un statut a un autre, dans le cas de notre status de base qui est completion_in_progress, on aura le droit d’effectuer une transition (donc can va retourner vrai) pour aller aux statues to_validate et aborted.
Avant de faire un apply, normalement on fait un can(), donc dans ce cas comme dit juste avant, on peut effectuer la transition
Bon, après avoir vue qu’est-ce qu’un workflow, à quoi ça sert, différent types de workflow et de machine à états, comment est-ce qu’on le définie, comment est-ce qu’on le dump en quelquechose de visuelle et comment on l’utilise, maintenant on va parler des événements !
Quand on transitionne ça déclenche des événements au moment de la transitions,
On a plusieurs types d’événements, ces événements, on va pouvoir les écouté grâce a la gestions d’événements de symfony.
L’utilisation au quotidien de notre Workflow avec Api-Platform et chez Quotatis, comme j’en ai parler tout à l’heure on a besoin du composant pour gérer l’états de nos projets.
On as dans la 3.4 un nouvelle événement lorsque les transitions ont été effectué
Vous vous souvenez de mon exemples sur les articles, et beh maintenant on a moins besoin des events, la logique peut être directement écrite dans votre propre implémentation de can().
Et ça à été merger aujourd’hui !!! :p
Donc comme je viens de le dire, cela va servir à gérer votre propre implémentation du can ou du apply.
Si vous avez besoin de juste réimplement le can, l’idée ici et d’utiliser l’héritage, en implémentant l’interface et en héritant du composant.