Skip to content

Commit 3456cc0

Browse files
committed
minor #11209 Documented the workflow metadata [redux] (javiereguiluz, pbowyer, OskarStark)
This PR was merged into the 4.2 branch. Discussion ---------- Documented the workflow metadata [redux] With @javiereguiluz's permission I have taken #9476 and incorporated the comments and code examples into it. This is the start of a push to improve the Workflow documentation. The focus now is on expanding the documentation by merging pull requests; organizing it will come later. Commits ------- 7f3a0fd Oskar's feedback a4c23c1 Add blank line between code block and sentence above. Code block was not rendering. 6080aa8 Remove the word 'simple' 3765ddb Change code formatting of PHP snippet per https://github.com/symfony/symfony-docs/pull/11209/files/d57fa38d903175d58d9cfbf63f20e7ced8d2fd01#r268391655 55c9199 Indent PHP block by an additional 4 spaces 225c2fe Apply suggestions from code review f716e81 Incorporate @OskarStark's feedback 94d17de Simplify the English and turn it into a tip 40fbaf3 Update arrays to use short syntax ea64992 Incorporate further excellent feedback from @HeahDude af71c14 Add an introduction as suggested in #11209 (comment) ca66356 Document how to see all configuration options (see #11209 (comment)) c9ef262 Incorporate @OskarStark's feedback c595c47 First set of tidy-ups for @HeahDude's feedback. 663639b Incorporate the code examples in #9476 (comment) into the documentation 17eae8c Add missing metadata key, fixing comment by @noniagriconomie on #9476 d68cc99 Documented the workflow metadata
2 parents 96cb148 + 7f3a0fd commit 3456cc0

File tree

1 file changed

+230
-0
lines changed

1 file changed

+230
-0
lines changed

workflow/usage.rst

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ 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 Symfony project run this command:
21+
22+
.. code-block:: terminal
23+
24+
$ bin/console config:dump-reference framework workflows
25+
1726
Creating a Workflow
1827
-------------------
1928

@@ -552,3 +561,224 @@ Don't need a human-readable message? You can also block a transition via a guard
552561
event using::
553562

554563
$event->setBlocked('true');
564+
565+
Storing Metadata
566+
----------------
567+
568+
.. versionadded:: 4.1
569+
570+
The feature to store metadata in workflows was introduced in Symfony 4.1.
571+
572+
In case you need it, you can store arbitrary metadata in workflows, their
573+
places, and their transitions using the ``metadata`` option. This metadata can
574+
be as simple as the title of the workflow or as complex as your own application
575+
requires:
576+
577+
.. configuration-block::
578+
579+
.. code-block:: yaml
580+
581+
# config/packages/workflow.yaml
582+
framework:
583+
workflows:
584+
blog_publishing:
585+
metadata:
586+
title: 'Blog Publishing Workflow'
587+
# ...
588+
places:
589+
draft:
590+
metadata:
591+
max_num_of_words: 500
592+
# ...
593+
transitions:
594+
to_review:
595+
from: draft
596+
to: review
597+
metadata:
598+
priority: 0.5
599+
# ...
600+
601+
.. code-block:: xml
602+
603+
<!-- config/packages/workflow.xml -->
604+
<?xml version="1.0" encoding="UTF-8" ?>
605+
<container xmlns="http://symfony.com/schema/dic/services"
606+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
607+
xmlns:framework="http://symfony.com/schema/dic/symfony"
608+
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
609+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
610+
>
611+
612+
<framework:config>
613+
<framework:workflow name="blog_publishing">
614+
<framework:metadata>
615+
<framework:title>Blog Publishing Workflow</framework:title>
616+
</framework:metadata>
617+
<!-- ... -->
618+
619+
<framework:place name="draft">
620+
<framework:metadata>
621+
<framework:max-num-of-words>500</framework:max-num-of-words>
622+
</framework:metadata>
623+
</framework:place>
624+
<!-- ... -->
625+
626+
<framework:transition name="to_review">
627+
<framework:from>draft</framework:from>
628+
<framework:to>review</framework:to>
629+
<framework:metadata>
630+
<framework:priority>0.5</framework:priority>
631+
</framework:metadata>
632+
</framework:transition>
633+
<!-- ... -->
634+
</framework:workflow>
635+
</framework:config>
636+
</container>
637+
638+
.. code-block:: php
639+
640+
// config/packages/workflow.php
641+
642+
$container->loadFromExtension('framework', [
643+
// ...
644+
'workflows' => [
645+
'blog_publishing' => [
646+
'metadata' => [
647+
'title' => 'Blog Publishing Workflow',
648+
],
649+
// ...
650+
'places' => [
651+
'draft' => [
652+
'metadata' => [
653+
'max_num_of_words' => 500,
654+
],
655+
],
656+
// ...
657+
],
658+
'transitions' => [
659+
'to_review' => [
660+
'from' => 'draft',
661+
'to' => 'review',
662+
'metadata' => [
663+
'priority' => 0.5,
664+
],
665+
],
666+
],
667+
],
668+
],
669+
]);
670+
671+
Then you can access this metadata in your controller as follows::
672+
673+
public function myControllerAction(Registry $registry, Article $article)
674+
{
675+
$workflow = $registry->get($article);
676+
677+
$workflow
678+
->getMetadataStore()
679+
->getWorkflowMetadata()['title'] ?? false
680+
;
681+
682+
// or
683+
$workflow->getMetadataStore()
684+
->getWorkflowMetadata()['title'] ?? false
685+
;
686+
687+
// or
688+
$aTransition = $workflow->getDefinition()->getTransitions()[0];
689+
$workflow
690+
->getMetadataStore()
691+
->getTransitionMetadata($aTransition)['title'] ?? false
692+
;
693+
}
694+
695+
There is a shortcut that works with everything::
696+
697+
$workflow
698+
->getMetadataStore()
699+
->getMetadata('title')
700+
;
701+
702+
In a Flash message in your Controller::
703+
704+
// $transition = ...; (an instance of Transition)
705+
706+
// $workflow is a Workflow instance retrieved from the Registry (see above)
707+
$title = $workflow->getMetadataStore()->getMetadata('title', $transition);
708+
$this->addFlash('info', "You have successfully applied the transition with title: '$title'");
709+
710+
Metadata can also be accessed in a Listener, from the Event object.
711+
712+
Using transition blockers you can
713+
return a user-friendly error message when you stop a transition from happening. In the example we
714+
get this message from the :class:`Symfony\\Component\\Workflow\\Event\\Event`'s metadata, giving
715+
you a central place to manage the text.
716+
717+
.. tip::
718+
719+
This example has been simplified; in production you may prefer to use the :doc:`Translation </components/translation>`
720+
component to manage messages in one place::
721+
722+
namespace App\Listener\Workflow\Task;
723+
724+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
725+
use Symfony\Component\Workflow\Event\GuardEvent;
726+
use Symfony\Component\Workflow\TransitionBlocker;
727+
728+
class OverdueGuard implements EventSubscriberInterface
729+
{
730+
public function guardPublish(GuardEvent $event)
731+
{
732+
$timeLimit = $event->getMetadata('time_limit', $event->getTransition());
733+
734+
if (date('Hi') <= $timeLimit) {
735+
return;
736+
}
737+
738+
$explanation = $event->getMetadata('explanation', $event->getTransition());
739+
$event->addTransitionBlocker(new TransitionBlocker($explanation , 0));
740+
}
741+
742+
public static function getSubscribedEvents()
743+
{
744+
return [
745+
'workflow.task.guard.done' => 'guardPublish',
746+
];
747+
}
748+
}
749+
750+
.. versionadded:: 4.1
751+
752+
The transition blockers were introduced in Symfony 4.1.
753+
754+
In Twig templates, metadata is available via the ``workflow_metadata()`` function:
755+
756+
.. code-block:: html+twig
757+
758+
<h2>Metadata</h2>
759+
<p>
760+
<strong>Workflow</strong>:<br >
761+
<code>{{ workflow_metadata(article, 'title') }}</code>
762+
</p>
763+
<p>
764+
<strong>Current place(s)</strong>
765+
<ul>
766+
{% for place in workflow_marked_places(article) %}
767+
<li>
768+
{{ place }}:
769+
<code>{{ workflow_metadata(article, 'max_num_of_words', place) ?: 'Unlimited'}}</code>
770+
</li>
771+
{% endfor %}
772+
</ul>
773+
</p>
774+
<p>
775+
<strong>Enabled transition(s)</strong>
776+
<ul>
777+
{% for transition in workflow_transitions(article) %}
778+
<li>
779+
{{ transition.name }}:
780+
<code>{{ workflow_metadata(article, 'priority', transition) ?: '0' }}</code>
781+
</li>
782+
{% endfor %}
783+
</ul>
784+
</p>

0 commit comments

Comments
 (0)