Компонент Workflow

Компонент Workflow

Компонент Workflow предоставляет инструменты для управления рабочим процессом или конечной машиной.

Установка

1
$ composer require symfony/workflow

Также вы можете клонировать репозиторий https://github.com/symfony/workflow.

Note

Если вы устанавливаете этот компонент вне приложения Symfony, вам нужно подключить файл vendor/autoload.php в вашем коде для включения механизма автозагрузки классов, предоставляемых Composer. Детальнее читайте в этой статье.

Создание рабочего процесса

Компонент Workflow предоставляет вам объектно-ориентированный способ для определения процесса или жизненного цикла, через который проходит ваш объект. Каждый шаг или этап в процессе называется местом. Вы также определяете переходы, которые описывают действие для перемещения из одного места в другое.

Набор мест и переходов создаёт определение. Рабочему процессу нужно Definition и способ написания состояний в объекты (т.е. экземпляр MarkingStoreInterface).

Рассмотрите следующий пример для поста блога. Пост может иметь один из множества предопределённых статусов (`draft`, `review`, `rejected`, `published`). В рабочем процессе эти статусы называются местами. Вы можете определять рабочий процесс так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;

$definitionBuilder = new DefinitionBuilder();
$definition = $definitionBuilder->addPlaces(['draft', 'review', 'rejected', 'published'])
    // Переходы определяются с помощью уникального имени, исходного места и места назначения
    ->addTransition(new Transition('to_review', 'draft', 'review'))
    ->addTransition(new Transition('publish', 'review', 'published'))
    ->addTransition(new Transition('reject', 'review', 'rejected'))
    ->build()
;

$marking = new SingleStateMarkingStore('currentState');
$workflow = new Workflow($definition, $marking);

Workflow теперь может помочь вам решить, какие действия разрешены в посте блога, в зависимости от того, в каком месте он находится. Он будет держать вашу логику домена в одном месте, а не распораживать её по всему вашему приложению.

Когда вы определяете несколько рабочих процессов, вам стоит рассмотреть использование Registry, который является объектом, хранящим и предоставляющим доступ к разным рабочим процессам. Регистр также поможет вам решить, поддерживает ли рабочий процесс объект, который вы пытаетесь использовать с ним:

1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\WorkflowInterface\InstanceOfSupportStrategy;
use Acme\Entity\BlogPost;
use Acme\Entity\Newsletter;

$blogWorkflow = ...
$newsletterWorkflow = ...

$registry = new Registry();
$registry->addWorkflow($blogWorkflow, new InstanceOfSupportStrategy(BlogPost::class));
$registry->addWorkflow($newsletterWorkflow, new InstanceOfSupportStrategy(Newsletter::class));

4.1

Метод addWorkflow() был представлен в Symfony 4.1. В предыдущих версиях Symfony это называлось add().

Использование

Когда вы сконфигурировали Registry с помощью вашего рабочего процесса, вы можете использовать его таким образом:

1
2
3
4
5
6
7
8
9
10
// ...
$post = new BlogPost();
$workflow = $registry->get($post);

$workflow->can($post, 'publish'); // False
$workflow->can($post, 'to_review'); // True

$workflow->apply($post, 'to_review');
$workflow->can($post, 'publish'); // True
$workflow->getEnabledTransitions($post); // ['publish', 'reject']