Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 025c2bb

Browse filesBrowse files
committed
Merge branch '4.2'
* 4.2: Documented the workflow metadata
2 parents 8a6b025 + ad961c7 commit 025c2bb
Copy full SHA for 025c2bb

File tree

Expand file treeCollapse file tree

1 file changed

+229
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+229
-0
lines changed

‎workflow/usage.rst

Copy file name to clipboardExpand all lines: workflow/usage.rst
+229Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ install the workflow feature before using it:
1414
1515
$ composer require symfony/workflow
1616
17+
Configuration
18+
-------------
19+
20+
To see all configuration options, if you are using the component inside a
21+
Symfony project run this command:
22+
23+
.. code-block:: terminal
24+
25+
$ php bin/console config:dump-reference framework workflows
26+
1727
Creating a Workflow
1828
-------------------
1929

@@ -665,3 +675,222 @@ Don't need a human-readable message? You can also block a transition via a guard
665675
event using::
666676

667677
$event->setBlocked('true');
678+
679+
Storing Metadata
680+
----------------
681+
682+
.. versionadded:: 4.1
683+
684+
The feature to store metadata in workflows was introduced in Symfony 4.1.
685+
686+
In case you need it, you can store arbitrary metadata in workflows, their
687+
places, and their transitions using the ``metadata`` option. This metadata can
688+
be as simple as the title of the workflow or as complex as your own application
689+
requires:
690+
691+
.. configuration-block::
692+
693+
.. code-block:: yaml
694+
695+
# config/packages/workflow.yaml
696+
framework:
697+
workflows:
698+
blog_publishing:
699+
metadata:
700+
title: 'Blog Publishing Workflow'
701+
# ...
702+
places:
703+
draft:
704+
metadata:
705+
max_num_of_words: 500
706+
# ...
707+
transitions:
708+
to_review:
709+
from: draft
710+
to: review
711+
metadata:
712+
priority: 0.5
713+
# ...
714+
715+
.. code-block:: xml
716+
717+
<!-- config/packages/workflow.xml -->
718+
<?xml version="1.0" encoding="UTF-8" ?>
719+
<container xmlns="http://symfony.com/schema/dic/services"
720+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
721+
xmlns:framework="http://symfony.com/schema/dic/symfony"
722+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
723+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
724+
>
725+
726+
<framework:config>
727+
<framework:workflow name="blog_publishing">
728+
<framework:metadata>
729+
<framework:title>Blog Publishing Workflow</framework:title>
730+
</framework:metadata>
731+
<!-- ... -->
732+
733+
<framework:place name="draft">
734+
<framework:metadata>
735+
<framework:max-num-of-words>500</framework:max-num-of-words>
736+
</framework:metadata>
737+
</framework:place>
738+
<!-- ... -->
739+
740+
<framework:transition name="to_review">
741+
<framework:from>draft</framework:from>
742+
<framework:to>review</framework:to>
743+
<framework:metadata>
744+
<framework:priority>0.5</framework:priority>
745+
</framework:metadata>
746+
</framework:transition>
747+
<!-- ... -->
748+
</framework:workflow>
749+
</framework:config>
750+
</container>
751+
752+
.. code-block:: php
753+
754+
// config/packages/workflow.php
755+
756+
$container->loadFromExtension('framework', [
757+
// ...
758+
'workflows' => [
759+
'blog_publishing' => [
760+
'metadata' => [
761+
'title' => 'Blog Publishing Workflow',
762+
],
763+
// ...
764+
'places' => [
765+
'draft' => [
766+
'metadata' => [
767+
'max_num_of_words' => 500,
768+
],
769+
],
770+
// ...
771+
],
772+
'transitions' => [
773+
'to_review' => [
774+
'from' => 'draft',
775+
'to' => 'review',
776+
'metadata' => [
777+
'priority' => 0.5,
778+
],
779+
],
780+
],
781+
],
782+
],
783+
]);
784+
785+
Then you can access this metadata in your controller as follows::
786+
787+
public function myController(Registry $registry, Article $article)
788+
{
789+
$workflow = $registry->get($article);
790+
791+
$title = $workflow
792+
->getMetadataStore()
793+
->getWorkflowMetadata()['title'] ?? false
794+
;
795+
796+
// or
797+
$title = $workflow->getMetadataStore()
798+
->getWorkflowMetadata()['title'] ?? false
799+
;
800+
801+
// or
802+
$aTransition = $workflow->getDefinition()->getTransitions()[0];
803+
$transitionTitle = $workflow
804+
->getMetadataStore()
805+
->getTransitionMetadata($aTransition)['title'] ?? false
806+
;
807+
}
808+
809+
There is a shortcut that works with everything::
810+
811+
$title = $workflow->getMetadataStore()->getMetadata('title');
812+
813+
In a :ref:`flash message <flash-messages>` in your controller::
814+
815+
// $transition = ...; (an instance of Transition)
816+
817+
// $workflow is a Workflow instance retrieved from the Registry (see above)
818+
$title = $workflow->getMetadataStore()->getMetadata('title', $transition);
819+
$this->addFlash('info', "You have successfully applied the transition with title: '$title'");
820+
821+
Metadata can also be accessed in a Listener, from the Event object.
822+
823+
Using transition blockers you can return a user-friendly error message when you
824+
stop a transition from happening. The example gets this message from the
825+
:class:`Symfony\\Component\\Workflow\\Event\\Event`'s metadata, giving you a
826+
central place to manage the text.
827+
828+
.. tip::
829+
830+
This example has been simplified; in production you may prefer to use the
831+
:doc:`Translation </components/translation>` component to manage messages in
832+
one place::
833+
834+
namespace App\Listener\Workflow\Task;
835+
836+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
837+
use Symfony\Component\Workflow\Event\GuardEvent;
838+
use Symfony\Component\Workflow\TransitionBlocker;
839+
840+
class OverdueGuard implements EventSubscriberInterface
841+
{
842+
public function guardPublish(GuardEvent $event)
843+
{
844+
$timeLimit = $event->getMetadata('time_limit', $event->getTransition());
845+
846+
if (date('Hi') <= $timeLimit) {
847+
return;
848+
}
849+
850+
$explanation = $event->getMetadata('explanation', $event->getTransition());
851+
$event->addTransitionBlocker(new TransitionBlocker($explanation , 0));
852+
}
853+
854+
public static function getSubscribedEvents()
855+
{
856+
return [
857+
'workflow.task.guard.done' => 'guardPublish',
858+
];
859+
}
860+
}
861+
862+
.. versionadded:: 4.1
863+
864+
The transition blockers were introduced in Symfony 4.1.
865+
866+
In Twig templates, metadata is available via the ``workflow_metadata()`` function:
867+
868+
.. code-block:: html+twig
869+
870+
<h2>Metadata</h2>
871+
<p>
872+
<strong>Workflow</strong>:<br >
873+
<code>{{ workflow_metadata(article, 'title') }}</code>
874+
</p>
875+
<p>
876+
<strong>Current place(s)</strong>
877+
<ul>
878+
{% for place in workflow_marked_places(article) %}
879+
<li>
880+
{{ place }}:
881+
<code>{{ workflow_metadata(article, 'max_num_of_words', place) ?: 'Unlimited'}}</code>
882+
</li>
883+
{% endfor %}
884+
</ul>
885+
</p>
886+
<p>
887+
<strong>Enabled transition(s)</strong>
888+
<ul>
889+
{% for transition in workflow_transitions(article) %}
890+
<li>
891+
{{ transition.name }}:
892+
<code>{{ workflow_metadata(article, 'priority', transition) ?: '0' }}</code>
893+
</li>
894+
{% endfor %}
895+
</ul>
896+
</p>

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.