Компонент Workflow

Компонент Workflow

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

Установка

1
$ composer require 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 Acme\Entity\BlogPost;
use Acme\Entity\Newsletter;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy;

$blogPostWorkflow = ...;
$newsletterWorkflow = ...;

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

Використання

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

1
2
3
4
5
6
7
8
9
10
11
12
// ...
// Вважайте, що $blogPost знаходиться у місці "draft" за замовчуванням
$blogPost = new BlogPost();
$workflow = $registry->get($blogPost);

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

$workflow->apply($blogPost, 'to_review'); // $blogPost тепер у місці "reviewed"

$workflow->can($blogPost, 'publish'); // True
$workflow->getEnabledTransitions($blogPost); // $blogPost може виконати перехід "publish" або "reject"

Ініціалізація

Якщо властивість вашого обʼєкта - null і ви хочете встановити її з initial_marking з конфігурації, ви можете викликати метод getMarking(), щоб ініціалізувати властивість обʼєкта:

1
2
3
4
5
6
// ...
$blogPost = new BlogPost();
$workflow = $registry->get($blogPost);

// initiate workflow
$workflow->getMarking($blogPost);