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

Added a new workflow_has_marked_place() Twig function

Grégoire Pineau
Contributed by Grégoire Pineau in #21253

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

1
2
3
{% if workflow_has_marked_place(subject, 'ordered') %}
    ...
{% endif %}

Added a new SupportStrategyInterface

Contributed by 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 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

Grégoire Pineau
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

Grégoire Pineau
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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 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'))
    ->build()
;

Added a new workflow_marked_places() Twig function

Grégoire Pineau
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:

1
{{ workflow_marked_places(post)|join(',') }}
Published in #Living on the edge