Skip to content

Added docs for Workflow component #6871

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 38 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d0701f0
Added docs for Workflow component
Nyholm Aug 12, 2016
91867c2
Moved images
Nyholm Aug 12, 2016
69bca59
Fixes
Nyholm Aug 12, 2016
f99fbb2
Fixes
Nyholm Aug 12, 2016
e797f0c
Syntax error
Nyholm Aug 12, 2016
5b2a029
Cleanup and minor fixes
Nyholm Aug 16, 2016
196baf9
Separated docs for component
Nyholm Aug 16, 2016
763950d
Updating docs to using symfony services
Nyholm Aug 16, 2016
cead2f7
Added docs about registry
Nyholm Aug 16, 2016
e0089c5
Added placeholders
Nyholm Aug 16, 2016
48de43d
Added note about state machines
Nyholm Aug 16, 2016
805b237
Added example with twig
Nyholm Aug 16, 2016
f57ec14
Show Twig function workflow_transitions
Nyholm Aug 16, 2016
03925ff
syntax fix
Nyholm Aug 16, 2016
e6bdee6
Some syntax fixes and a better "why do we need this"
Nyholm Nov 7, 2016
c7464c7
typos
Nyholm Nov 7, 2016
83d26c1
toctree fix
Nyholm Nov 7, 2016
6e7a35f
Fixed typos and comments
Nyholm Nov 8, 2016
4415466
Added usage example on the component
Nyholm Nov 8, 2016
866b25a
Added example how to dump with Symfony
Nyholm Nov 8, 2016
dceebec
Added examples of workflows
Nyholm Nov 8, 2016
b959f8a
Updated state machine with an example
Nyholm Nov 8, 2016
b45edf2
simplify job_application
Nyholm Nov 8, 2016
fefdb5f
syntax
Nyholm Nov 9, 2016
7f0f5b0
Added comment about the service name
Nyholm Nov 9, 2016
c681283
Updated accoding to feedback
Nyholm Nov 9, 2016
86ecf0a
Added PHP config
Nyholm Nov 9, 2016
d002a8b
Added xml and PHP config
Nyholm Nov 9, 2016
b0a8855
Added workflow under guides
Nyholm Nov 9, 2016
4e7cf11
Removed the *why workflows* from the usage page.
Nyholm Nov 9, 2016
3aa433d
Documented support for DefinitionBuilder
Nyholm Nov 9, 2016
4f277dc
fixed typo
Nyholm Nov 9, 2016
2511c21
Merge pull request #1 from Nyholm/workflow-definition-builder
Nyholm Nov 9, 2016
c9b1656
Updated to support changes in https://github.com/symfony/symfony/pull…
Nyholm Nov 9, 2016
2cc2934
Updated twig example
Nyholm Nov 9, 2016
47dc11d
show how to configure the DI extension config
Nyholm Nov 11, 2016
3250621
Fixed typos
Nyholm Nov 11, 2016
c0bd6da
Use imperative instead of past tense.
Nyholm Nov 11, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Updated accoding to feedback
  • Loading branch information
Nyholm committed Nov 9, 2016
commit c681283feb0af4fc0726c41beb64af4da7f86908
5 changes: 2 additions & 3 deletions components/workflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ are trying to use it with::
Usage
-----

When you have configured a ``Registry`` with your workflows you may use it as follows::
When you have configured a ``Registry`` with your workflows, you may use it as follows::

// ...
$post = new BlogPost();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please prefix the example with // ... to indicate things are left out (but shown above).

// ...
$post = new BlogPost();

$workflow = $registry->get($post);

Expand All @@ -92,15 +93,13 @@ When you have configured a ``Registry`` with your workflows you may use it as fo
$workflow->can($post, 'publish'); // True
$workflow->getEnabledTransitions($post); // ['publish', 'reject']


Learn more
----------

.. toctree::
:maxdepth: 1
:glob:

/workflow
/workflow/*

.. _Packagist: https://packagist.org/packages/symfony/workflow
18 changes: 9 additions & 9 deletions workflow.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ of how a blog post goes from draft, review and publish. Another example is when
a user submits a series of different forms to complete a task. Such processes are
best kept away from your models and should be defined in configuration.

A **definition** of a workflow consist of places and actions how to get from one
A **definition** of a workflow consist of places and actions to get from one
place to another. The actions are called **transistions**. A workflow does also
need to know each object's position in the workflow. That **marking store** writes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"That marking score [...]" -> "The marking store [...]"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see where I've written "score". It supposed to be "store" everywhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, typo from my side. I meant "That" should become "The".

to a property of object to remember the current place.
to a property of the object to remember the current place.

.. note::

The terminology above is commonly used when discussing workflows and
`Petri nets`_

The workflow component does also support state machines. A state machine is a subset
The Workflow component does also support state machines. A state machine is a subset
of a workflow and its purpose is to hold a state of your model. Read more about the
differences and specific features of state machine in :doc:`/workflow/state-machines`
differences and specific features of state machine in :doc:`/workflow/state-machines`.

Examples
--------
Expand All @@ -34,12 +34,12 @@ workflow below descirbes the process to fill in a job application.

When you fill in a job application in this examplethere are 4 to 7 steps depending

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space missing in examplethere

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you

on the what job you are applying for. Some jobs requires personality test, logic tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require personality tests

and/or formal requirements to be answered by the user. Some jobs don't. We use the
``GuardEvent`` to decide what next steps that are allowed for a specific application.
and/or formal requirements to be answered by the user. Some jobs don't. The
``GuardEvent`` is used to decide what next steps are allowed for a specific application.

By defining a workflow like this we have an over view how the process looks like. We
do not have any of the process logic in our controllers, models or view. We can change
the order of the steps by changing configuration only.
By defining a workflow like this, there is an overview how the process looks like. The process
logic is not mixed with the controllers, models or view. The order of the steps can be changed
by changing the configuration only.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two blank lines

.. toctree::
Expand Down
9 changes: 4 additions & 5 deletions workflow/dumping-workflows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ PNG image of the workflow defined above::
$dumper = new GraphvizDumper();
echo $dumper->dump($definition);

.. code-block:: bash
.. code-block:: terminal

$ php dump-graph.php > out.dot
$ dot -Tpng out.dot -o graph.png
Expand All @@ -21,10 +21,10 @@ The result will look like this:

.. image:: /_images/components/workflow/blogpost.png

If you have configured your workflow with the Symfony framwork you may dump the dot file
with the ``WorkflowDumpCommand``.
If you have configured your workflow with the Symfony framework, you may dump the dot file
with the ``WorkflowDumpCommand``:

.. code-block:: bash
.. code-block:: terminal

$ php bin/console workflow:dump name > out.dot
$ dot -Tpng out.dot -o graph.png
Expand All @@ -34,5 +34,4 @@ with the ``WorkflowDumpCommand``.
The ``dot`` command is a part of Graphviz. You can download it and read
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is part of

more about it on `Graphviz.org`_.


.. _Graphviz.org: http://www.graphviz.org
86 changes: 80 additions & 6 deletions workflow/state-machines.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ The workflow component is modelled after a *Workflow net* which is a subclass
of a `Petri net`_. By adding further restrictions you can get a state machine.
The most important one being that a state machine cannot be in more than
one place simultaneously. It is also worth noting that a workflow does not
commonly have cyclic path in the definition graph but it is common for a state
commonly have cyclic path in the definition graph, but it is common for a state
machine.

Example of state machine
Example of State Machine
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of a

------------------------

Consider the states a GitHub pull request may have. We have an initial "start"
state, a state for running tests on "travis", then we have the "review" state
where we can require changes, reject or accept the pull request. At anytime we
could also "update" the pull request which will result in another "travis" run.
A pull request starts in an intial "start" state, a state for e.g. running
tests on Travis. When this is finished, the pull request is in the "review"
state, where contributors can require changes, reject or accept the
pull request. At any time, you can also "update" the pull request, which
will result in another Travis run.

.. image:: /_images/components/workflow/pull_request.png

Expand All @@ -27,6 +28,7 @@ Below is the configuration for the pull request state machine.

.. code-block:: yaml

# app/config/config.yml
framework:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add # app/config/config.yml

workflows:
pull_request:
Expand Down Expand Up @@ -65,6 +67,78 @@ Below is the configuration for the pull request state machine.
from: closed
to: review
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add XML and PHP formats.

<!-- app/config/config.xml -->
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
>

    <framework:config>
        <framework:workflow name="pull_request" type="state_machine">
            <framework:marking-store type="scalar"/>

            <framework:support>AppBundle\Entity\PullRequest</framework:support>

            <framework:place>start</framework:place>
            <framework:place>coding</framework:place>
            <framework:place>travis</framework:place>
            <framework:place>review</framework:place>
            <framework:place>merged</framework:place>
            <framework:place>closed</framework:place>

            <framework:transition name="submit">
                <framework:from>start</framework:from>

                <framework:to>travis</framework:to>
            </framework:transition>

            <framework:transition name="update">
                <framework:from>coding</framework:from>
                <framework:from>travis</framework:from>
                <framework:from>review</framework:from>

                <framework:to>travis</framework:to>
            </framework:transition>

            <framework:transition name="wait_for_review">
                <framework:from>travis</framework:from>

                <framework:to>review</framework:to>
            </framework:transition>

            <framework:transition name="change_needed">
                <framework:from>review</framework:from>

                <framework:to>coding</framework:to>
            </framework:transition>

            <framework:transition name="accepted">
                <framework:from>review</framework:from>

                <framework:to>merged</framework:to>
            </framework:transition>

            <framework:transition name="rejected">
                <framework:from>review</framework:from>

                <framework:to>closed</framework:to>
            </framework:transition>

            <framework:transition name="reopened">
                <framework:from>closed</framework:from>

                <framework:to>review</framework:to>
            </framework:transition>

        </framework:workflow>

    </framework:config>
</container>

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Im embarrassingly bad at the XML syntax for the config.


.. code-block:: xml

<!-- app/config/config.xml -->
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd"
>

<framework:config>
<framework:workflow name="pull_request" type="state_machine">
<framework:marking-store type="scalar"/>

<framework:support>AppBundle\Entity\PullRequest</framework:support>

<framework:place>start</framework:place>
<framework:place>coding</framework:place>
<framework:place>travis</framework:place>
<framework:place>review</framework:place>
<framework:place>merged</framework:place>
<framework:place>closed</framework:place>

<framework:transition name="submit">
<framework:from>start</framework:from>

<framework:to>travis</framework:to>
</framework:transition>

<framework:transition name="update">
<framework:from>coding</framework:from>
<framework:from>travis</framework:from>
<framework:from>review</framework:from>

<framework:to>travis</framework:to>
</framework:transition>

<framework:transition name="wait_for_review">
<framework:from>travis</framework:from>

<framework:to>review</framework:to>
</framework:transition>

<framework:transition name="change_needed">
<framework:from>review</framework:from>

<framework:to>coding</framework:to>
</framework:transition>

<framework:transition name="accepted">
<framework:from>review</framework:from>

<framework:to>merged</framework:to>
</framework:transition>

<framework:transition name="rejected">
<framework:from>review</framework:from>

<framework:to>closed</framework:to>
</framework:transition>

<framework:transition name="reopened">
<framework:from>closed</framework:from>

<framework:to>review</framework:to>
</framework:transition>

</framework:workflow>

</framework:config>
</container>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These extra blank lines can be removed

You can now use this state machine by getting the ``state_machine.pull_request`` service::

Expand Down
23 changes: 14 additions & 9 deletions workflow/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
How to Use the Workflow
=======================

Using the workflow component will help you to keep your domain logic as
Using the Workflow component will help you to keep your domain logic as
configuration. Having domain logic in one place gives you a better overview
and it is easier to maintain whenever the domain requirement changes since
you do not have to edit all your controllers, twig templates and services.
Expand Down Expand Up @@ -32,7 +32,7 @@ like this:
blog_publishing:
type: 'workflow' # or 'state_machine'
marking_store:
type: 'property_accessor' # or 'scalar' or 'state_machine'
type: 'property_accessor' # or 'scalar'
arguments:
- 'currentPlace'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about

arguments:
    - 'status' # The name of property that holds the marking in the object

supports:
Expand All @@ -54,7 +54,7 @@ like this:
to: rejected


.. code-block: php
.. code-block:: php

class BlogPost
{
Expand All @@ -69,10 +69,10 @@ like this:
The marking store type could be "property_accessor" or "scalar".
A scalar marking type does not support a model being on multiple places.

With this workflow named ``blog_publishing`` you can get help to decide
With this workflow named ``blog_publishing``, you can get help to decide
what actions that are allowed on a blog post. ::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use either [...] a blog post:: or [...] a blog post. + .. code-block:: php on the next line

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this was preferred. I thought you said that: #6871 (comment)

Copy link
Member

@wouterj wouterj Nov 9, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I tried to say was that :: is preferred when the sentence ends with a colon already. If that's not the case, we still prefer the verbose syntax. Sorry for the confusion.


$post = new \BlogPost();
$post = new \AppBundle\Entity\BlogPost();

$workflow = $this->container->get('workflow.blog_publishing');
$workflow->can($post, 'publish'); // False
Expand All @@ -93,7 +93,7 @@ Using Events

To make your workflows even more powerful you could construct the ``Workflow``
object with an ``EventDispatcher``. You can now create event listeners to
block transitions ie depending on the data in the blog post. The following
block transitions (i.e. depending on the data in the blog post). The following
events are dispatched:

* ``workflow.guard``
Expand All @@ -102,6 +102,9 @@ events are dispatched:

See example to make sure no blog post without title is moved to "review"::

use Symfony\Component\Workflow\Event\GuardEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class BlogPostReviewListener implements EventSubscriberInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing use statements (for the GuardEvent, EventSubscriberInterface

{
public function guardReview(GuardEvent $event)
Expand All @@ -127,16 +130,18 @@ See example to make sure no blog post without title is moved to "review"::
With help from the ``EventDispatcher`` and the ``AuditTrailListener`` you
could easily enable logging::

$logger = new PSR3Logger();
use Symfony\Component\Workflow\EventListener\AuditTrailListener;

$logger = new AnyPsr3Logger();
$subscriber = new AuditTrailListener($logger);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing use statements

$dispatcher->addSubscriber($subscriber);

Usage in Twig
-------------

Using your workflow in your Twig templates reduces the need of domain logic
in the view layer. Consider this example of the control panel for our blog's
edit page. The links below will only be displayed when the action is allowed:
in the view layer. Consider this example of the control panel of the blog.
The links below will only be displayed when the action is allowed:

.. code-block:: twig

Expand Down