New in Symfony 3.3: Workflow improvements

In Symfony 3.3, the Workflow component will include lots of useful new features.

Added a new workflow_has_marked_place() Twig function

Contributed by Adam Prager and Grégoire Pineau in #21253.

This Twig helper function checks if the marking of the given object has the given state:

{% if workflow_has_marked_place(subject, 'ordered') %}
{% endif %}

Added a new SupportStrategyInterface

Contributed by
Andreas Kleemann
in #21334.

The Workflow component's Registry class checks on a subject's class instance to decide if it is supported or not. However, some projects use a generic class to hold content of any content type. In those cases, it's useful to be able to use the registry to identify the supported workflow for a content by checking the class content type.

In Symfony 3.3 we made some changes to make that possible. First, we deprecated passing the class name as the second argument of WorkflowRegistry::add(). Then we added a SupportStrategyInterface and a ClassInstanceSupportStrategy to wrap the class names. Finally, we added a related support_strategy configuration option (which is mutually exclusive with supports option).

Added a new entered event

Contributed by
Adam Prager
in #20787.

After a long discussion about the necessity of this event, it was decided to add in Symfony 3.3 a new entered event that is triggered just after a transition. The existing enter event is not enough because it's called before the new markings are set, so you can't for example flush an entity inside a listener.

Added the workflow name to all the events

Contributed by
Grégoire Pineau
in #21925.

The Event class now includes a getWorkflowName() method to get the name of the workflow.

Added a fluent interface to DefinitionBuilder

Contributed by
Grégoire Pineau
in #21950.

Fluent interfaces are controversial in software engineering, but for object builders they make sense because they simplify the code. In Symfony 3.3, the DefinitionBuilder provides a fluent interface for all its methods:

// Before
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;

$builder = new DefinitionBuilder();
$builder->addPlaces(['draft', 'review', 'rejected', 'published']);

$builder->addTransition(new Transition('to_review', 'draft', 'review'));
$builder->addTransition(new Transition('publish', 'review', 'published'));
$builder->addTransition(new Transition('reject', 'review', 'rejected'));

$definition = $builder->build();

// After
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;

$definition = (new DefinitionBuilder())
    ->addPlaces(['draft', 'review', 'rejected', 'published'])
    ->addTransition(new Transition('to_review', 'draft', 'review'))
    ->addTransition(new Transition('publish', 'review', 'published'))
    ->addTransition(new Transition('reject', 'review', 'rejected'))

Added a new workflow_marked_places() Twig function

Contributed by
Grégoire Pineau
in #22180.

When using a custom MarkingStore, the value in the $subject::marking can vary from the value inside Marking::getPlaces(). This occurs, for example, when the value stored in the subject is a bitmask.

Therefore, it's always safer to get the places names from the marking, which is the purpose of this new function:

{{ workflow_marked_places(post)|join(',') }}


This reminds me something I'm working on for quite some time — Smalldb framework ( It is designed to join formal state machines, SQL databases, and REST principles into a compact package and ease implementation of the model layer in an MVC application. It makes use of UML notation to visualize state diagrams (using Graphviz too) and can load GraphML into state machine definition so you can draw the machine. Integration with Symfony is a bit young, but the Smalldb is framework agnostic and meant to be integrated into other frameworks.
Shouldn't it be "$definition = " in line 18? Cause ->build() is called like in line 12.
@Robert good catch! It's fixed now. Thanks.
Always wanted to ask: why was the decision to include workflows into the framework bundle instead of creating a new workflow bundle? Doesn't make sense really to put that into the framework bundle, doesn't?
I'm wondering if it's possible to change the place inside an event by verify attributes of the subject.

For example:
Subject has a boolean flag
Place A -> transition -> Place B or Place C (if the boolean flag of the subject is true)

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.