Workflows工作流是许多公司在结构化时的一个基本元素。它们描述了一种操作序列,可以被反复执行,用来提供某些服务(如,在程序中买一件商品),处理某些信息(如,通过CMS系统发布内容),等等。

在Symfony 3.2中,我们添加了一个全新的组件Workflow component,来帮你定义那些在程序中出现的工作流。技术角度讲,本组件实现了一个“workflow net”,它是Petri net的一个子类。

实践中,要创建一个工作流,你要定义“状态(states)”和“转变(transitions)”(transitions是指,可以在两个状态间发生的events,即事件)。下例展示了一个迷你工作流,用于发布一些内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
framework:
    workflows:
        article_publishing:
            supports:
                - AppBundle\Entity\Article
            places:
                - draft
                - spellchecked
                - published
            transitions:
                spellcheck:
                    from: draft
                    to:   spellchecked
                publish:
                    from: spellchecked
                    to:   published

现在你可以在模板和控制器中使用工作流了。比如在模板中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{# the workflow name is optional when there is just one workflow for the class #}
{# 当类只有一个工作流时,工作流的名称是可选的 #}
{% if workflow_can(article, 'publish') %}
    <a href="...">Publish article(发布文章)</a>
{% endif %}
 
{# if more than one workflow is defined for the 'Article' class #}
{# 当类有一个以上的工作流被定义时 #}
{% if workflow_can(article, 'publish', 'article_publishing') %}
    <a href="...">Publish article(发布文章)</a>
{% endif %}
 
{# ... #}
 
{% for transition in workflow_transitions(article) %}
    <a href="...">{{ transition.name }}</a>
{% else %}
    No actions available for this article.(该文章无可用操作)
{% endfor %}

在控制器中,通过工作流名称你可以得到任何已定义的工作流,这是因为Symfony创建了工作流登记(workflow registry),之后,把任何给定的“转变”应用给它:

1
2
3
4
5
6
7
8
9
10
11
12
use Symfony\Component\Workflow\Exception\LogicException;
 
public function reviewAction(Article $article)
{
    // the try/catch is needed because this transition could already have been applied
    // try/catch很有必要,因为这个转变可能已经被应用过了
    try {
        $this->get('worflow.article_publishing')->apply($article, 'spellcheck');
    } catch (LogicException $e) {
        // ...
    }
}

如果你需要在转变发生时,执行自定义逻辑,你可以针对本组件触发的事件注册一个监听。

通过这个演示程序来查看workflow组件在完整样例中的实际运行情况,同时把这个GitHub项目作为Symfony2.3以上版本的一个非官方的组件入口(来加以掌握)。