diff --git a/workflow/usage.rst b/workflow/usage.rst index 57fc4eb79dc..532837fe4bd 100644 --- a/workflow/usage.rst +++ b/workflow/usage.rst @@ -14,6 +14,15 @@ install the workflow feature before using it: $ composer require symfony/workflow +Configuration +------------- + +To see all configuration options, if you are using the component inside a Symfony project run this command: + +.. code-block:: terminal + + $ bin/console config:dump-reference framework workflows + Creating a Workflow ------------------- @@ -533,3 +542,224 @@ You can access the message from a Twig template as follows: Don't need a human-readable message? You can still use:: $event->setBlocked('true'); + +Storing Metadata +---------------- + +.. versionadded:: 4.1 + + The feature to store metadata in workflows was introduced in Symfony 4.1. + +In case you need it, you can store arbitrary metadata in workflows, their +places, and their transitions using the ``metadata`` option. This metadata can +be as simple as the title of the workflow or as complex as your own application +requires: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/workflow.yaml + framework: + workflows: + blog_publishing: + metadata: + title: 'Blog Publishing Workflow' + # ... + places: + draft: + metadata: + max_num_of_words: 500 + # ... + transitions: + to_review: + from: draft + to: review + metadata: + priority: 0.5 + # ... + + .. code-block:: xml + + + + + + + + + Blog Publishing Workflow + + + + + + 500 + + + + + + draft + review + + 0.5 + + + + + + + + .. code-block:: php + + // config/packages/workflow.php + + $container->loadFromExtension('framework', [ + // ... + 'workflows' => [ + 'blog_publishing' => [ + 'metadata' => [ + 'title' => 'Blog Publishing Workflow', + ], + // ... + 'places' => [ + 'draft' => [ + 'metadata' => [ + 'max_num_of_words' => 500, + ], + ], + // ... + ], + 'transitions' => [ + 'to_review' => [ + 'from' => 'draft', + 'to' => 'review', + 'metadata' => [ + 'priority' => 0.5, + ], + ], + ], + ], + ], + ]); + +Then you can access this metadata in your controller as follows:: + + public function myControllerAction(Registry $registry, Article $article) + { + $workflow = $registry->get($article); + + $workflow + ->getMetadataStore() + ->getWorkflowMetadata()['title'] ?? false + ; + + // or + $workflow->getMetadataStore() + ->getWorkflowMetadata()['title'] ?? false + ; + + // or + $aTransition = $workflow->getDefinition()->getTransitions()[0]; + $workflow + ->getMetadataStore() + ->getTransitionMetadata($aTransition)['title'] ?? false + ; + } + +There is a shortcut that works with everything:: + + $workflow + ->getMetadataStore() + ->getMetadata('title') + ; + +In a Flash message in your Controller:: + + // $transition = ...; (an instance of Transition) + + // $workflow is a Workflow instance retrieved from the Registry (see above) + $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 Event object. + +Using transition blockers you can +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. + +.. tip:: + + This example has been simplified; in production you may prefer to use the :doc:`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 OverdueGuard implements EventSubscriberInterface + { + public function guardPublish(GuardEvent $event) + { + $timeLimit = $event->getMetadata('time_limit', $event->getTransition()); + + if (date('Hi') <= $timeLimit) { + return; + } + + $explanation = $event->getMetadata('explanation', $event->getTransition()); + $event->addTransitionBlocker(new TransitionBlocker($explanation , 0)); + } + + public static function getSubscribedEvents() + { + return [ + 'workflow.task.guard.done' => 'guardPublish', + ]; + } + } + +.. versionadded:: 4.1 + + The transition blockers were introduced in Symfony 4.1. + +In Twig templates, metadata is available via the ``workflow_metadata()`` function: + +.. code-block:: html+twig + +

Metadata

+

+ Workflow:
+ {{ workflow_metadata(article, 'title') }} +

+

+ Current place(s) +

+

+

+ Enabled transition(s) +

+