diff --git a/workflow.rst b/workflow.rst index 8e4cba3b5a9..b25e62b8379 100644 --- a/workflow.rst +++ b/workflow.rst @@ -41,10 +41,14 @@ By defining a workflow like this, there is an overview how the process looks lik logic is not mixed with the controllers, models or view. The order of the steps can be changed by changing the configuration only. +Learn more +---------- + .. toctree:: :maxdepth: 1 - :glob: - workflow/* + workflow/usage + workflow/state-machines + workflow/dumping-workflows .. _Petri nets: https://en.wikipedia.org/wiki/Petri_net diff --git a/workflow/dumping-workflows.rst b/workflow/dumping-workflows.rst index 0e784062c41..f6ab01c4d0c 100644 --- a/workflow/dumping-workflows.rst +++ b/workflow/dumping-workflows.rst @@ -4,8 +4,8 @@ How to Dump Workflows ===================== -To help you debug your workflows, you can dump a representation of your workflow with -the use of a ``DumperInterface``. Use the ``GraphvizDumper`` to create a +To help you debug your workflows, you can dump a representation of your workflow +with the use of a ``DumperInterface``. Use the ``GraphvizDumper`` to create a PNG image of the workflow defined above:: // dump-graph.php @@ -20,8 +20,8 @@ The result will look like this: .. image:: /_images/components/workflow/blogpost.png -If you have configured your workflow with the Symfony framework, you may dump the dot file -with the ``WorkflowDumpCommand``: +Inside a Symfony application, you can dump the dot file with the +``workflow:dump`` command: .. code-block:: terminal diff --git a/workflow/state-machines.rst b/workflow/state-machines.rst index 25770be0314..a076dce55f0 100644 --- a/workflow/state-machines.rst +++ b/workflow/state-machines.rst @@ -28,7 +28,7 @@ Below is the configuration for the pull request state machine. .. code-block:: yaml - # app/config/config.yml + # config/packages/workflow.yaml framework: workflows: pull_request: @@ -67,7 +67,7 @@ Below is the configuration for the pull request state machine. .. code-block:: xml - + loadFromExtension('framework', array( // ... 'workflows' => array( @@ -190,8 +189,29 @@ Below is the configuration for the pull request state machine. ), )); -You can now use this state machine by getting the ``state_machine.pull_request`` service:: +In a Symfony application using the +:ref:`default services.yaml configuration `, +you can get this state machine by injecting the Workflow registry service:: + + // ... + use Symfony\Component\Workflow\Registry; + + class SomeService + { + private $workflows; + + public function __constructor(Registry $workflows) + { + $this->workflows = $workflows; + } + + public function someMethod() + { + $stateMachine = $this->workflows->get('pull_request'); + // ... + } - $stateMachine = $this->container->get('state_machine.pull_request'); + // ... + } .. _Petri net: https://en.wikipedia.org/wiki/Petri_net diff --git a/workflow/usage.rst b/workflow/usage.rst index 9e0124d904a..283b13df434 100644 --- a/workflow/usage.rst +++ b/workflow/usage.rst @@ -1,8 +1,15 @@ .. index:: single: Workflow; Usage -How to Use the Workflow -======================= +How to Create and Use Workflows +=============================== + +Before creating your first workflow, execute this command to install the +:doc:`Workflow component ` in your application: + +.. code-block:: terminal + + $ composer require workflow A workflow is a process or a lifecycle that your objects go through. Each step or stage in the process is called a *place*. You do also define *transitions* @@ -14,15 +21,15 @@ A set of places and transitions creates a **definition**. A workflow needs a ``Definition`` and a way to write the states to the objects (i.e. an instance of a :class:`Symfony\\Component\\Workflow\\MarkingStore\\MarkingStoreInterface`.) -Consider the following example for a blog post. A post can have places: -'draft', 'review', 'rejected', 'published'. You can define the workflow +Consider the following example for a blog post that can have these places: +``draft``, ``review``, ``rejected``, ``published``. You can define the workflow like this: .. configuration-block:: .. code-block:: yaml - # app/config/config.yml + # config/packages/workflow.yaml framework: workflows: blog_publishing: @@ -51,7 +58,7 @@ like this: .. code-block:: xml - + loadFromExtension('framework', array( // ... @@ -152,28 +159,46 @@ like this: .. tip:: - The ``type`` (default value ``single_state``) and ``arguments`` (default value ``marking``) - attributes of the ``marking_store`` option are optional. If omitted, their default values - will be used. + The ``type`` (default value ``single_state``) and ``arguments`` (default + value ``marking``) attributes of the ``marking_store`` option are optional. + If omitted, their default values will be used. -With this workflow named ``blog_publishing``, you can get help to decide -what actions are allowed on a blog post:: +With this workflow named ``blog_publishing``, you can now decide what actions +are allowed on a blog post. For example, inside a controller of an application +using the :ref:`default services.yaml configuration `, +you can get the workflow by injecting the Workflow registry service:: - $post = new \App\Entity\BlogPost(); + // ... + use Symfony\Component\Workflow\Registry; + use App\Entity\BlogPost; + use Symfony\Bundle\FrameworkBundle\Controller\Controller; + use Symfony\Component\Workflow\Exception\LogicException; - $workflow = $this->container->get('workflow.blog_publishing'); - $workflow->can($post, 'publish'); // False - $workflow->can($post, 'to_review'); // True + class BlogController extends Controller + { + public function edit(Registry $workflows) + { + $post = new BlogPost(); + $workflow = $workflows->get($post); - // Update the currentState on the post - try { - $workflow->apply($post, 'to_review'); - } catch (LogicException $e) { - // ... - } + // if there are multiple workflows for the same class, + // pass the workflow name as the second argument + // $workflow = $workflows->get($post, 'blog_publishing'); - // See all the available transition for the post in the current state - $transitions = $workflow->getEnabledTransitions($post); + $workflow->can($post, 'publish'); // False + $workflow->can($post, 'to_review'); // True + + // Update the currentState on the post + try { + $workflow->apply($post, 'to_review'); + } catch (LogicException $e) { + // ... if the transition is not allowed + } + + // See all the available transitions for the post in the current state + $transitions = $workflow->getEnabledTransitions($post); + } + } Using Events ------------ @@ -250,7 +275,8 @@ order: * ``workflow.[workflow name].announce`` * ``workflow.[workflow name].announce.[transition name]`` -Here is an example how to enable logging for every time a the "blog_publishing" workflow leaves a place:: +Here is an example of how to enable logging for every time the ``blog_publishing`` +workflow leaves a place:: use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;