Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork5.3k
[Workflow] doc improvements#11578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -76,16 +76,19 @@ are trying to use it with:: | ||
| Usage | ||
| ----- | ||
| When you have configured a ``Registry`` with your workflows, | ||
| you can retreive a workflow from it and use it as follows:: | ||
| // ... | ||
| // Consider that $post is in state "draft" by default | ||
| $post = new BlogPost(); | ||
| $workflow = $registry->get($post); | ||
noniagriconomie marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| $workflow->can($post, 'publish'); // False | ||
| $workflow->can($post, 'to_review'); // True | ||
| $workflow->apply($post, 'to_review'); // $post is now in state "review" | ||
| $workflow->can($post, 'publish'); // True | ||
| $workflow->getEnabledTransitions($post); // ['publish', 'reject'] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -197,7 +197,10 @@ As configured, the following property is used by the marking store:: | ||
| With this workflow named ``blog_publishing``, you can get help to decide | ||
| what actions are allowed on a blog post:: | ||
| use Symfony\Component\Workflow\Exception\LogicException; | ||
| use App\Entity\BlogPost; | ||
OskarStark marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| $post = BlogPost(); | ||
| $workflow = $this->container->get('workflow.blog_publishing'); | ||
| $workflow->can($post, 'publish'); // False | ||
| @@ -401,6 +404,9 @@ This means that each event has access to the following information: | ||
| :method:`Symfony\\Component\\Workflow\\Event\\Event::getWorkflowName` | ||
| Returns a string with the name of the workflow that triggered the event. | ||
| :method:`Symfony\\Component\\Workflow\\Event\\Event::getMetadata` | ||
| Returns a metadata. | ||
| For Guard Events, there is an extended class :class:`Symfony\\Component\\Workflow\\Event\\GuardEvent`. | ||
| This class has two more methods: | ||
| @@ -410,6 +416,13 @@ This class has two more methods: | ||
| :method:`Symfony\\Component\\Workflow\\Event\\GuardEvent::setBlocked` | ||
| Sets the blocked value. | ||
| :method:`Symfony\\Component\\Workflow\\Event\\GuardEvent::getTransitionBlockerList` | ||
| Returns the event :class:`Symfony\\Component\\Workflow\\TransitionBlockerList`. | ||
| See :ref:`blocking transitions <workflow-blocking-transitions>`. | ||
| :method:`Symfony\\Component\\Workflow\\Event\\GuardEvent::addTransitionBlocker` | ||
| Add a :class:`Symfony\\Component\\Workflow\\TransitionBlocker` instance. | ||
| .. _workflow-blocking-transitions: | ||
| Blocking Transitions | ||
| @@ -438,16 +451,61 @@ transition. The value of this option is any valid expression created with the | ||
| from: draft | ||
| to: reviewed | ||
| publish: | ||
| # or "is_anonymous", "is_remember_me", "is_fully_authenticated", "is_granted", "is_valid" | ||
OskarStark marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| guard: "is_authenticated" | ||
| from: reviewed | ||
| to: published | ||
| reject: | ||
| # or any valid expression language with "subject" referring to thesupported object | ||
| guard: "has_role('ROLE_ADMIN') and subject.isRejectable()" | ||
| from: reviewed | ||
| to: rejected | ||
| You can also use transition blockers to block and return a user-friendly error | ||
| message when you stop a transition from happening. | ||
| In the example we get this message from the | ||
| :class:`Symfony\\Component\\Workflow\\Event\\Event`'s metadata, giving you a | ||
| central place to manage the text. | ||
| This example has been simplified; in production you may prefer to use the | ||
| :doc:`Translation </components/translation>` component to manage messages in one | ||
| place:: | ||
| namespace App\Listener\Workflow\Task; | ||
| use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
| use Symfony\Component\Workflow\Event\GuardEvent; | ||
| use Symfony\Component\Workflow\TransitionBlocker; | ||
| class BlogPostPublishListener implements EventSubscriberInterface | ||
| { | ||
| public function guardPublish(GuardEvent $event) | ||
| { | ||
| $eventTransition = $event->getTransition(); | ||
| $hourLimit = $event->getMetadata('hour_limit', $eventTransition); | ||
| if (date('H') <= $hourLimit) { | ||
| return; | ||
| } | ||
| // Block the transition "publish" if it is more than 8 PM | ||
| // with the message for end user | ||
| $explanation = $event->getMetadata('explanation', $eventTransition); | ||
| $event->addTransitionBlocker(new TransitionBlocker($explanation , 0)); | ||
| } | ||
| public static function getSubscribedEvents() | ||
| { | ||
| return [ | ||
| 'workflow.blog_publishing.guard.publish' => ['guardPublish'], | ||
| ]; | ||
| } | ||
| } | ||
| .. versionadded:: 4.1 | ||
| The transition blockers were introduced in Symfony 4.1. | ||
| Usage in Twig | ||
| ------------- | ||
| @@ -470,15 +528,15 @@ The following example shows these functions in action: | ||
| .. code-block:: html+twig | ||
| <h3>Actions on Blog Post</h3> | ||
| {% if workflow_can(post, 'publish') %} | ||
| <a href="...">Publish</a> | ||
| {% endif %} | ||
| {% if workflow_can(post, 'to_review') %} | ||
| <a href="...">Submit to review</a> | ||
| {% endif %} | ||
| {% if workflow_can(post, 'reject') %} | ||
| <a href="...">Reject</a> | ||
| {% endif %} | ||
| {# Or loop through the enabled transitions #} | ||
| @@ -494,8 +552,8 @@ The following example shows these functions in action: | ||
| {% endif %} | ||
| {# Check if some place has been marked on the object #} | ||
| {% if 'reviewed' in workflow_marked_places(post) %} | ||
| <span class="label">Reviewed</span> | ||
| {% endif %} | ||
| Storing Metadata | ||
| @@ -532,7 +590,12 @@ requires: | ||
| to: review | ||
| metadata: | ||
| priority: 0.5 | ||
| publish: | ||
| from: reviewed | ||
| to: published | ||
| metadata: | ||
| hour_limit: 20 | ||
| explanation: 'You can not publish after 8 PM.' | ||
| .. code-block:: xml | ||
| @@ -563,7 +626,14 @@ requires: | ||
| <framework:priority>0.5</framework:priority> | ||
| </framework:metadata> | ||
| </framework:transition> | ||
| <framework:transition name="publish"> | ||
| <framework:from>reviewed</framework:from> | ||
| <framework:to>published</framework:to> | ||
| <framework:metadata> | ||
| <framework:hour_limit>20</framework:priority> | ||
| <framework:explanation>You can not publish after 8 PM.</framework:priority> | ||
| </framework:metadata> | ||
| </framework:transition> | ||
| </framework:workflow> | ||
| </framework:config> | ||
| </container> | ||
| @@ -595,6 +665,14 @@ requires: | ||
| 'priority' => 0.5, | ||
| ], | ||
| ], | ||
| 'publish' => [ | ||
| 'from' => 'reviewed', | ||
| 'to' => 'published', | ||
| 'metadata' => [ | ||
| 'hour_limit' => 20, | ||
| 'explanation' => 'You can not publish after 8 PM.', | ||
| ], | ||
| ], | ||
| ], | ||
| ], | ||
| ], | ||
| @@ -603,27 +681,29 @@ requires: | ||
| Then you can access this metadata in your controller as follows:: | ||
| use Symfony\Component\Workflow\Registry; | ||
| use App\Entity\BlogPost; | ||
| public function myController(Registry $registry,BlogPost $post) | ||
| { | ||
| $workflow = $registry->get($post); | ||
| $title = $workflow | ||
| ->getMetadataStore() | ||
| ->getWorkflowMetadata()['title'] ??'Default title' | ||
OskarStark marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| ; | ||
| // or | ||
| $aTransition = $workflow->getDefinition()->getTransitions()[0]; | ||
| $transitionTitle = $workflow | ||
| ->getMetadataStore() | ||
| ->getTransitionMetadata($aTransition)['priority'] ??0 | ||
| ; | ||
| } | ||
| There is a shortcut that works withevery metadata level:: | ||
| $title = $workflow->getMetadataStore()->getMetadata('title'); | ||
noniagriconomie marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| $priority = $workflow->getMetadataStore()->getMetadata('priority'); | ||
| In a :ref:`flash message <flash-messages>` in your controller:: | ||
| @@ -633,76 +713,35 @@ In a :ref:`flash message <flash-messages>` in your controller:: | ||
| $title = $workflow->getMetadataStore()->getMetadata('title', $transition); | ||
| $this->addFlash('info', "You have successfully applied the transition with title: '$title'"); | ||
| Metadata can also be accessed in a Listener, from the :class:`Symfony\\Component\\Workflow\\Event\\Event` object. | ||
| In Twig templates, metadata is available via the ``workflow_metadata()`` function: | ||
| .. code-block:: html+twig | ||
| <h2>Metadata of Blog Post</h2> | ||
| <p> | ||
| <strong>Workflow</strong>:<br> | ||
| <code>{{ workflow_metadata(blog_post, 'title') }}</code> | ||
| </p> | ||
| <p> | ||
| <strong>Current place(s)</strong> | ||
| <ul> | ||
| {% for place in workflow_marked_places(blog_post) %} | ||
| <li> | ||
| {{ place }}: | ||
| <code>{{ workflow_metadata(blog_post, 'max_num_of_words', place) ?: 'Unlimited'}}</code> | ||
| </li> | ||
| {% endfor %} | ||
| </ul> | ||
| </p> | ||
| <p> | ||
| <strong>Enabled transition(s)</strong> | ||
| <ul> | ||
| {% for transition in workflow_transitions(blog_post) %} | ||
| <li> | ||
| {{ transition.name }}: | ||
| <code>{{ workflow_metadata(blog_post, 'priority', transition) ?: '0' }}</code> | ||
| </li> | ||
| {% endfor %} | ||
| </ul> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,8 +5,8 @@ How to Dump Workflows | ||
| ===================== | ||
| To help you debug your workflows, you can dump a representation of your workflow | ||
| or state machine with the use of a ``DumperInterface``. Symfony providestwo | ||
| different dumpers, both based on Dot (see below). | ||
| Use the ``GraphvizDumper`` or ``StateMachineGraphvizDumper`` to create DOT | ||
| files, or use ``PlantUmlDumper`` for PlantUML files. Both types can be converted | ||
| @@ -24,17 +24,20 @@ Images of the workflow defined above:: | ||
| .. code-block:: terminal | ||
| # dump DOT file in PNG image: | ||
| $ php dump-graph-dot.php | dot -Tpng -o dot_graph.png | ||
| #dump DOT file inSVGimage: | ||
| # $ php dump-graph-dot.php | dot -Tsvg -o dot_graph.svg | ||
| # dump PlantUML in PNG image: | ||
| $ php dump-graph-puml.php | java -jar plantuml.jar -p > puml_graph.png | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. this grouping is a bit confusing now, because it generates a ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. wanted to "group" | ||
| The DOT result will look like this: | ||
| .. image:: /_images/components/workflow/blogpost.png | ||
| ThePlantUML result: | ||
| .. image:: /_images/components/workflow/blogpost_puml.png | ||
| @@ -43,8 +46,9 @@ Inside a Symfony application, you can dump the files with those commands using | ||
| .. code-block:: terminal | ||
| $ php bin/console workflow:dump workflow_name | dot -Tpng -o workflow_name.png | ||
| $ php bin/console workflow:dump workflow_name | dot -Tsvg -o workflow_name.svg | ||
| $ php bin/console workflow:dump workflow_name --dump-format=puml | java -jar plantuml.jar -p > workflow_name.png | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. same as above | ||
| .. note:: | ||
Uh oh!
There was an error while loading.Please reload this page.