You work with Symfony, but the concept of dependency injection is a little blurry for you? Find out how to take advantage of the component reading this article.
Use the Symfony Workflow component
Since Symfony 3.2, a new useful component was born: the Workflow component. It is indeed really convenient and can simplify greatly your developments when you have to manage status workflows in your application, that occurs a lot.
In all cases, you have to install the following dependency:
If you use an earlier version of Symfony but >=2.3 you are also able to use this component, but you have to install the following non-official bundle, which loads the component itself and add the required configuration under the bundle's namespace:
Do not forget to enable the bundle in your kernel class.
Time has come to write our workflow configuration. We will have to define all our places (statuses / states) and available transitions.
In this blog post, we will take a pull request status example. A pull request can have one of the following status:
However, it cannot be, for instance, moved from the
merged status without having the
reviewed status before. The workflow component makes sense here.
Here is our full workflow configuration:
Here, we specify we want to use a
multiple_state workflow. Please not that if you want to use a simple transition from one state to another, you can use a
For this example, we also have defined a
AppBundle\Entity\PullRequest class which has a
state property and associated setter and getter methods (component will use these methods to manage transitions):
Everything is now ready, we can start to use the Workflow component!
First useful thing to do after you have written your workflow configuration is to generate a graph using the Symfony command. The command will generate one graph using the Graphviz format.
Here is the Symfony command you have to run:
The generated Graphviz will give you the following diagram:
This one gives you a really clear vision of your workflow and allows everyone at every level (developers, product owners, customers, ...) to understand the business logic. The Workflow component implements methods that allow you to verify if a transition is applicable and to later apply it depending on the current status and to also list all enabled transitions.
In order to check if you can apply a specific transition and apply it, simply use the following code:
In the case you do not want to use the
can() method, the
one will throw an exception if the transition cannot be effectively done, so you will be able to catch exceptions on the
To list all enabled transitions:
Overall, the component usage is just as simple as these 3 methods. As you can see, complex workflows are now easier to manage!
Tune in for events!
The component also dispatches multiple events, chronologically sorted as:
workflow.leave: when our pull request will leave its current state,
workflow.transition: when the transition to the new state is launched,
workflow.enter: when the new state is just defined on our pull request,
workflow.guard: this one allows you to prevent the asked transition from occurring, you can do that by calling the following method:
Finally, you have to know that these events also exist in a unique way for each workflow in order to allow you to tune in your workflow events only.
If you want to do that, you have to listen to the following name:
Let's do better than that: you are also able to listen to a specific transition or a state for a specific workflow:
workflow.pull_request.enter.needs_review: is only dispatched when a
needs_reviewstate is defined on our pull request. We could for instance send an email to the author with the changes the reviewer has suggested,
workflow.pull_request.transition.merge: will occur when the merge transition will be dispatched on our pull request.
The Workflow component is a really useful component to manage state or status on most of web applications. Do not hesitate to use it because its simplicity of configuration and use will probably help you a lot on your projects. Also, this component helps me a lot to give people I was working with a clear vision on a complex workflow we have to manage. The graph generation allows to clarify all of that for everyone!