@@ -14,8 +14,8 @@ A set of places and transitions creates a **definition**. A workflow needs
14
14
a ``Definition `` and a way to write the states to the objects (i.e. an
15
15
instance of a :class: `Symfony\\ Component\\ Workflow\\ MarkingStore\\ MarkingStoreInterface `.)
16
16
17
- Consider the following example for a blog post. A post can have places:
18
- ' draft', 'review', ' rejected', ' published' . You can define the workflow
17
+ Consider the following example for a blog post. A post can have these places:
18
+ `` draft ``, `` reviewed ``, `` rejected ``, `` published `` . You can define the workflow
19
19
like this:
20
20
21
21
.. configuration-block ::
@@ -38,18 +38,18 @@ like this:
38
38
initial_place : draft
39
39
places :
40
40
- draft
41
- - review
41
+ - reviewed
42
42
- rejected
43
43
- published
44
44
transitions :
45
45
to_review :
46
46
from : draft
47
- to : review
47
+ to : reviewed
48
48
publish :
49
- from : review
49
+ from : reviewed
50
50
to : published
51
51
reject :
52
- from : review
52
+ from : reviewed
53
53
to : rejected
54
54
55
55
.. code-block :: xml
@@ -74,24 +74,24 @@ like this:
74
74
<framework : support >AppBundle\Entity\BlogPost</framework : support >
75
75
76
76
<framework : place >draft</framework : place >
77
- <framework : place >review </framework : place >
77
+ <framework : place >reviewed </framework : place >
78
78
<framework : place >rejected</framework : place >
79
79
<framework : place >published</framework : place >
80
80
81
81
<framework : transition name =" to_review" >
82
82
<framework : from >draft</framework : from >
83
83
84
- <framework : to >review </framework : to >
84
+ <framework : to >reviewed </framework : to >
85
85
</framework : transition >
86
86
87
87
<framework : transition name =" publish" >
88
- <framework : from >review </framework : from >
88
+ <framework : from >reviewed </framework : from >
89
89
90
90
<framework : to >published</framework : to >
91
91
</framework : transition >
92
92
93
93
<framework : transition name =" reject" >
94
- <framework : from >review </framework : from >
94
+ <framework : from >reviewed </framework : from >
95
95
96
96
<framework : to >rejected</framework : to >
97
97
</framework : transition >
@@ -119,21 +119,21 @@ like this:
119
119
'supports' => ['AppBundle\Entity\BlogPost'],
120
120
'places' => [
121
121
'draft',
122
- 'review ',
122
+ 'reviewed ',
123
123
'rejected',
124
124
'published',
125
125
],
126
126
'transitions' => [
127
127
'to_review' => [
128
128
'from' => 'draft',
129
- 'to' => 'review ',
129
+ 'to' => 'reviewed ',
130
130
],
131
131
'publish' => [
132
- 'from' => 'review ',
132
+ 'from' => 'reviewed ',
133
133
'to' => 'published',
134
134
],
135
135
'reject' => [
136
- 'from' => 'review ',
136
+ 'from' => 'reviewed ',
137
137
'to' => 'rejected',
138
138
],
139
139
],
@@ -210,7 +210,7 @@ When a state transition is initiated, the events are dispatched in the following
210
210
order:
211
211
212
212
``workflow.guard ``
213
- Validate whether the transition is allowed at all (:ref: `see below <workflow-usage-guard-events >`).
213
+ Validate whether the transition is blocked or not (:ref: `see below <workflow-usage-guard-events >` and :ref: ` using guards < workflow-usage-using-guards >`).
214
214
215
215
The three events being dispatched are:
216
216
@@ -322,14 +322,14 @@ Guard Events
322
322
There are a special kind of events called "Guard events". Their event listeners
323
323
are invoked every time a call to ``Workflow::can ``, ``Workflow::apply `` or
324
324
``Workflow::getEnabledTransitions `` is executed. With the guard events you may
325
- add custom logic to decide what transitions are valid or not. Here is a list
325
+ add custom logic to decide which transitions should be blocked or not. Here is a list
326
326
of the guard event names.
327
327
328
328
* ``workflow.guard ``
329
329
* ``workflow.[workflow name].guard ``
330
330
* ``workflow.[workflow name].guard.[transition name] ``
331
331
332
- See example to make sure no blog post without title is moved to "review" ::
332
+ This example stops any blog post being transitioned to "reviewed" if it is missing a title ::
333
333
334
334
use Symfony\Component\Workflow\Event\GuardEvent;
335
335
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -343,8 +343,8 @@ See example to make sure no blog post without title is moved to "review"::
343
343
$title = $post->title;
344
344
345
345
if (empty($title)) {
346
- // Posts without title are not allowed
347
- // to perform the transition "to_review"
346
+ // Block the transition "to_review"
347
+ // if the post has no title
348
348
$event->setBlocked(true);
349
349
}
350
350
}
@@ -388,6 +388,51 @@ This class has two more methods:
388
388
:method: `Symfony\\ Component\\ Workflow\\ Event\\ GuardEvent::setBlocked `
389
389
Sets the blocked value.
390
390
391
+ .. _workflow-usage-using-guards :
392
+
393
+ Using Guards
394
+ ------------
395
+
396
+ The component has a guard logic to control the execution of your workflow on top of your configuration.
397
+
398
+ It allows you to execute your custom logic to decide if the transition is blocked or not, before actually
399
+ applying this transition.
400
+
401
+ You have multiple optional ways to use guards in your workflow.
402
+
403
+ The first way is :ref: `with the guard event <workflow-usage-guard-events >`, which allows you to implement
404
+ any desired feature.
405
+
406
+ Another one is via the configuration and its specific entry ``guard `` on a transition.
407
+
408
+ This ``guard `` entry allows any expression that is valid for the Expression Language component:
409
+
410
+ .. configuration-block ::
411
+
412
+ .. code-block :: yaml
413
+
414
+ # config/packages/workflow.yaml
415
+ framework :
416
+ workflows :
417
+ blog_publishing :
418
+ # previous configuration
419
+ transitions :
420
+ to_review :
421
+ # the transition is allowed only if the current user has the ROLE_REVIEWER role.
422
+ guard : " is_granted('ROLE_REVIEWER')"
423
+ from : draft
424
+ to : reviewed
425
+ publish :
426
+ # or "is_anonymous", "is_remember_me", "is_fully_authenticated", "is_granted"
427
+ guard : " is_authenticated"
428
+ from : reviewed
429
+ to : published
430
+ reject :
431
+ # or any valid expression language with "subject" refering to the post
432
+ guard : " has_role(" ROLE_ADMIN") and subject.isStatusReviewed()"
433
+ from : reviewed
434
+ to : rejected
435
+
391
436
Usage in Twig
392
437
-------------
393
438
@@ -434,7 +479,7 @@ The following example shows these functions in action:
434
479
{% endfor %}
435
480
436
481
{# Check if the object is in some specific place #}
437
- {% if workflow_has_marked_place(post, 'review ') %}
482
+ {% if workflow_has_marked_place(post, 'reviewed ') %}
438
483
<p>This post is ready for review.</p>
439
484
{% endif %}
440
485
0 commit comments