In Symfony 3.3, the Workflow component will include lots of useful new features.
Added a new workflow_has_marked_place()
Twig function
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
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
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
The Event
class now includes a getWorkflowName()
method to get the name
of the workflow.
Added a fluent interface to DefinitionBuilder
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
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(',') }}
This reminds me something I'm working on for quite some time — Smalldb framework (https://smalldb.org/). 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)