在 Symfony 4.1 我们对 Workflow 组件 进行了大大小小的功能改进。 本文总结了最重要的几点。

New PlantUML dumper

Contributed by
Sébastien Morel
in #24705.

工作流已经可以被导出为 DOT 格式,然后转换成图片文件。在 Symfony 4.1 we 中添加了对另一种被称为 PlantUML 的流行格式的支持。现在你可以选择哪种格式最适合你:

1
2
3
4
5
# traditional DOT-based dumping / 传统的基于 DOT 的 dumping
$  bin/console workflow:dump my_workflow | dot -Tpng > my_workflow.png
 
# new PlantUML-based dumping / 新式的基于 UML 的 dumping
$  bin/console workflow:dump my_workflow --dump-format=puml | java -jar plantuml.jar -p > my_workflow.png

transition/place 名称中被删除了的约束

Contributed by
Grégoire Pineau
in #26079.

以前,工作流 transitions 和 places 的名字只能包含匹配到这个正则的字符: [\w_-]。现在你可以在那些名字中使用任意字符。

New WorkflowInterface 和 WorkflowSupportStrategyInterface 接口

Contributed by
Hamza Amrouche
in #24751.

Workflow 现在实现是一个新的 WorkflowInterface 接口。该接口包含了与现有类相同的方法 (getMarking() 类相同的方法 can(), apply(), getEnabledTransitions(), getName(), getDefinition()getMarkingStore()),因此你毋须在程序中做任何改变。

此外,全新的 WorkflowSupportStrategyInterface 也被创建,为的是替换被降格的 SupportStrategyInterface。这个新接口只包含 supports() 方法,因此你不必在接口类以外的地方做任何修改。

新增了 transition blockers

Contributed by
Grégoire Pineau
in #26076.

新的 transition blockers 定义了 TransitionBlocker 类,让你能够得到“为可transition不能在工作流内发生”的更多信息:

1
2
3
$event->addTransitionBlocker(
    new TransitionBlocker('You can not publish this article because it\'s too late. Try again tomorrow morning.')
);

然后你可以在 PHP 代码和 Twig 模板中访问到它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<h2>Why you can't transition?</h2>
<ul>
    {% for transition in workflow_all_transitions(article) %}
        {% if not workflow_can(article, transition.name) %}
            <li>
                <strong>{{ transition.name }}</strong>:
                <ul>
                {% for blocker in workflow_build_transition_blocker_list(article, transition.name) %}
                    <li>
                        {{ blocker.message }}
                        {% if blocker.parameters.expression is defined %}
                            <code>{{ blocker.parameters.expression }}</code>
                        {% endif %}
                    </li>
                {% endfor %}
                </ul>
            </li>
        {% endif %}
    {% endfor %}
</ul>

允许存储metadata元数据

Contributed by
Grégoire Pineau
in #26092.

现在你可以在 places 中存储任意的元数据,transitions 和 workflows 使用的是 metadata 选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# config/packages/workflow.yaml
framework:
    workflows:
        my_workflow:
            supports:
                - App\Entity\BlogPost
            metadata:
                some_key: 'some_value'
                other_key: 'other_value'
            # ...
            places:
                some_place:
                    metadata:
                        some_key: 'some_value'
            # ...
            transitions:
                some_transition:
                    metadata:
                        some_key: 'some_value'

Metadata 通过使用实现了 MetadataStoreInterface 接口的对象来进行存储,而它可以通过使用 getMetadata() 方法来获取到:

1
2
3
4
5
6
public function onReview(Event $event) {
    $metadataStore = $event->getWorkflow()->getMetadataStore();
    foreach ($event->getTransition()->getTos() as $place) {
        $this->flashbag->add('info', $metadataStore->getPlaceMetadata($place)->get('some_key'));
    }
}

在 Twig 模板中你可以使用全新的 workflow_metadata() 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<strong>Current place(s)</strong>
<ul>
{% for place in workflow_marked_places(article) %}
    <li>
        {{ place }}:
        <code>{{ workflow_metadata(article, 'title', place) ?: 'n-a'}}</code>
    </li>
{% endfor %}
</ul>
 
<strong>Enabled transition(s)</strong>
<ul>
{% for transition in workflow_transitions(article) %}
    <li>
        {{ transition.name }}:
        <code>{{ workflow_metadata(article, 'title', transition) ?: 'n-a'}}</code>
    </li>
{% endfor %}
</ul>

添加了全新的 TransitionException 类

Contributed by
Andrew Tchircoff
in #26587.

当一个 transition 无法被应用到 workflow 时,一个新的 Symfony\Component\Workflow\Exception\TransitionException 异常会被抛出,而不是之前通用的 LogicException异常。