April 15, 2019 Grégoire Pineau

In Symfony 4.3 we improved the Workflow component with lots of major and minor features. This blog post summarizes the most important ones.

Added a context to Workflow::apply() ¶ Contributed by

Grégoire Pineau

in #29146. When applying a transition, now it's possible to pass a custom $context (e.g. the user who performed the transition or the current date): 1 2 3 $workflow -> apply ( $article , $request -> request -> get ( 'transition' ), [ 'time' => date ( 'y-m-d H:i:s' ), ]); Before using this feature, update your entity or any other object supported by the workflow as follows: 1 2 3 4 class Article { - public function setMarking($marking) + public function setMarking($marking, $context = []) Then, update the configuration of the workflow to use the MethodMarkingStore : 1 2 3 4 5 6 7 framework: workflows: article: type: workflow marking_store: - type: multiple_state + type: method

Allow to modify the context in a listener¶ Contributed by

Grégoire Pineau

in #30902. Passing the context on every call to ->apply() could be annoying and will lead to duplicated code. Now you can create a listener that does that for you: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 class TransitionEventSubscriber implements EventSubscriberInterface { private $tokenStorage ; public function __construct ( TokenStorageInterface $tokenStorage ) { $this -> tokenStorage = $tokenStorage ; } public function onWorkflowArticleTransition ( TransitionEvent $event ) { $context = $event -> getContext (); $token = $this -> tokenStorage -> getToken (); if ( $token instanceof TokenInterface ) { $user = $token -> getUser (); if ( $user instanceof UserInterface ) { $context [ 'user' ] = $user -> getUsername (); } } $event -> setContext ( $context ); } public static function getSubscribedEvents () { return [ TransitionEvent :: class => 'onWorkflowArticleTransition' , ]; } }

Added color to dumped workflow¶ Contributed by

Alexis Lefebvre

in #29538. It's now possible to configure how a workflow will be rendered thanks to the dump_style metadata config option: 1 2 3 4 5 6 7 8 9 10 transitions : submit : from : start to : travis metadata : title : transition submit title dump_style : label : 'My custom label' arrow_color : '#0088FF' label_color : 'Red' And this is how the custom style would look like:

Allow to configure many initial places¶ Contributed by

Grégoire Pineau

in #30468 and #30890. Unlike state machines, when using a workflow it's possible to have a subject in many places. That's why the component now allows to configure multiple initial places: 1 2 3 4 5 workflows : article : type : workflow initial_marking : [ foo , bar ] places : [ foo , bar , a , b , c , d ]

Simpler configuration¶ Contributed by

Grégoire Pineau

in #30551 and #30890. As mentioned above, subjects can only be in one place in state machines but they can be in one or more states when using a workflow. However, the initial design of the Workflow component allowed to use a workflow with a Single State Marking Store. This wasn't the best decision and it added some unnecessary complexity. Starting from Symfony 4.3, if your subject can be only in one state, use a state machine. In that case, the property (called marking by default) will be a string. If the subject can be in many places, use a workflow. In that case, the property will be an array. Thanks to this simplification, we've improved the DX (developer experience): 1 2 3 4 5 6 7 8 9 10 11 12 framework : workflows : article : type : workflow marking_store : type : method # This will be the default value in Symfony 5.0 property : marking # This is the default value, it could be omitted task : type : state_machine marking_store : type : method # This will be the default value in Symfony 5.0 property : state