@@ -28,7 +28,7 @@ a ``Definition`` and a way to write the states to the objects (i.e. an
2828instance of a:class: `Symfony\\ Component\\ Workflow\\ MarkingStore\\ MarkingStoreInterface `.)
2929
3030Consider the following example for a blog post that can have these places:
31- ``draft ``, ``review ``, ``rejected ``, ``published ``. You can define the workflow
31+ ``draft ``, ``reviewed ``, ``rejected ``, ``published ``. You can define the workflow
3232like this:
3333
3434..configuration-block ::
@@ -51,18 +51,18 @@ like this:
5151initial_place :draft
5252places :
5353 -draft
54- -review
54+ -reviewed
5555 -rejected
5656 -published
5757transitions :
5858to_review :
5959from :draft
60- to :review
60+ to :reviewed
6161publish :
62- from :review
62+ from :reviewed
6363to :published
6464reject :
65- from :review
65+ from :reviewed
6666to :rejected
6767
6868 ..code-block ::xml
@@ -87,24 +87,24 @@ like this:
8787 <framework : support >App\Entity\BlogPost</framework : support >
8888
8989 <framework : place >draft</framework : place >
90- <framework : place >review </framework : place >
90+ <framework : place >reviewed </framework : place >
9191 <framework : place >rejected</framework : place >
9292 <framework : place >published</framework : place >
9393
9494 <framework : transition name =" to_review" >
9595 <framework : from >draft</framework : from >
9696
97- <framework : to >review </framework : to >
97+ <framework : to >reviewed </framework : to >
9898 </framework : transition >
9999
100100 <framework : transition name =" publish" >
101- <framework : from >review </framework : from >
101+ <framework : from >reviewed </framework : from >
102102
103103 <framework : to >published</framework : to >
104104 </framework : transition >
105105
106106 <framework : transition name =" reject" >
107- <framework : from >review </framework : from >
107+ <framework : from >reviewed </framework : from >
108108
109109 <framework : to >rejected</framework : to >
110110 </framework : transition >
@@ -132,21 +132,21 @@ like this:
132132 'supports' => ['App\Entity\BlogPost'],
133133 'places' => [
134134 'draft',
135- 'review ',
135+ 'reviewed ',
136136 'rejected',
137137 'published',
138138 ],
139139 'transitions' => [
140140 'to_review' => [
141141 'from' => 'draft',
142- 'to' => 'review ',
142+ 'to' => 'reviewed ',
143143 ],
144144 'publish' => [
145- 'from' => 'review ',
145+ 'from' => 'reviewed ',
146146 'to' => 'published',
147147 ],
148148 'reject' => [
149- 'from' => 'review ',
149+ 'from' => 'reviewed ',
150150 'to' => 'rejected',
151151 ],
152152 ],
@@ -327,7 +327,7 @@ When a state transition is initiated, the events are dispatched in the following
327327order:
328328
329329``workflow.guard ``
330- Validate whether the transition isallowed at all (:ref: `see below <workflow-usage-guard-events >`).
330+ Validate whether the transition isblocked or not (:ref: `see below <workflow-usage-guard-events >` and :ref: ` using guards < workflow-usage-using-guards >`).
331331
332332 The three events being dispatched are:
333333
@@ -439,14 +439,14 @@ Guard Events
439439There are a special kind of events called "Guard events". Their event listeners
440440are invoked every time a call to ``Workflow::can ``, ``Workflow::apply `` or
441441``Workflow::getEnabledTransitions `` is executed. With the guard events you may
442- add custom logic to decide what transitionsare valid or not. Here is a list
442+ add custom logic to decide what transitionsshould be blocked or not. Here is a list
443443of the guard event names.
444444
445445* ``workflow.guard ``
446446* ``workflow.[workflow name].guard ``
447447* ``workflow.[workflow name].guard.[transition name] ``
448448
449- See example to make sure no blog post without title is moved to "review "::
449+ See example to make sure no blog post without title is moved to "reviewed "::
450450
451451 use Symfony\Component\Workflow\Event\GuardEvent;
452452 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -460,8 +460,8 @@ See example to make sure no blog post without title is moved to "review"::
460460 $title = $post->title;
461461
462462 if (empty($title)) {
463- //Posts without title are not allowed
464- //to perform thetransition "to_review"
463+ //Block the transition "to_review"
464+ //if thepost has no title defined
465465 $event->setBlocked(true);
466466 }
467467 }
@@ -501,6 +501,48 @@ This class has two more methods:
501501:method: `Symfony\\ Component\\ Workflow\\ Event\\ GuardEvent::setBlocked `
502502 Sets the blocked value.
503503
504+ .. _workflow-usage-using-guards :
505+
506+ Using Guards
507+ ------------
508+
509+ The component has a guard logic to control the execution of your workflow on top of your configuration.
510+
511+ It allows you to execute your custom logic to decide if the transition is blocked or not, before actually
512+ applying this transition.
513+
514+ You have multiple optional ways to use guards in your workflow.
515+
516+ The first way is:ref: `with the guard event <workflow-usage-guard-events >`, which allows you to implement
517+ any desired feature.
518+
519+ Another one is via the configuration and its specific entry `guard ` on a transition.
520+
521+ This `guard ` entry allows any expression that is valid for the Expression Language component:
522+
523+ ..configuration-block ::
524+
525+ ..code-block ::yaml
526+
527+ # config/packages/workflow.yaml
528+ framework :
529+ workflows :
530+ blog_publishing :
531+ # previous configuration
532+ transitions :
533+ to_review :
534+ guard :" is_granted('ROLE_REVIEWER')" # the transition is allowed only if the current user has the ROLE_REVIEWER role.
535+ from :draft
536+ to :reviewed
537+ publish :
538+ guard :" is_authenticated" # or "is_anonymous", "is_remember_me", "is_fully_authenticated", "is_granted"
539+ from :reviewed
540+ to :published
541+ reject :
542+ guard :" has_role(" ROLE_ADMIN") and subject.isStatusReviewed()" # or any valid expression language with "subject" refering to the post
543+ from :reviewed
544+ to :rejected
545+
504546 Usage in Twig
505547-------------
506548
@@ -542,7 +584,7 @@ The following example shows these functions in action:
542584 {% endfor %}
543585
544586 {# Check if the object is in some specific place #}
545- {% if workflow_has_marked_place(post, 'review ') %}
587+ {% if workflow_has_marked_place(post, 'reviewed ') %}
546588 <p>This post is ready for review.</p>
547589 {% endif %}
548590