Компонент Workflow
Дата оновлення перекладу 2024-05-07
Компонент 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 17 18
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
$definitionBuilder = new DefinitionBuilder();
$definition = $definitionBuilder->addPlaces(['draft', 'reviewed', 'rejected', 'published'])
// Переходи визначаються за допомогою унікального імені, початкового місця та місця призначення
->addTransition(new Transition('to_review', 'draft', 'reviewed'))
->addTransition(new Transition('publish', 'reviewed', 'published'))
->addTransition(new Transition('reject', 'reviewed', 'rejected'))
->build()
;
$singleState = true; // true якщо субʼєкт може бути тільки в одному стані в заданий час
$property = 'currentState'; // імʼя властивості субʼєкта, де зберігається стан
$marking = new MethodMarkingStore($singleState, $property);
$workflow = new Workflow($definition, $marking);
Workflow
тепер може допомогти вам вирішити, які дії дозволені у пості блогу,
в залежності від того, в якому місці він знаходиться. Він триматиме вашу логіку
в одному місці, а не розпорошуватиме її по всьому вашому додатку.
Використання
Ось приклад використання робочого процесу, визначеного вище:
1 2 3 4 5 6 7 8 9 10 11
// ...
// Вважайте, що $blogPost знаходиться у місці "draft" за замовчуванням
$blogPost = new BlogPost();
$workflow->can($blogPost, 'publish'); // False
$workflow->can($blogPost, 'to_review'); // True
$workflow->apply($blogPost, 'to_review'); // $blogPost is now in place "reviewed"
$workflow->can($blogPost, 'publish'); // True
$workflow->getEnabledTransitions($blogPost); // $blogPost can perform transition "publish" or "reject"
Ініціалізація
Якщо властивість вашого обʼєкта - null
і ви хочете встановити її з
initial_marking
з конфігурації, ви можете викликати метод getMarking()
,
щоб ініціалізувати властивість обʼєкта:
1 2 3 4 5 6
// ...
$blogPost = new BlogPost();
$workflow = $registry->get($blogPost);
// initiate workflow
$workflow->getMarking($blogPost);
Використання реєстру Workflow
Коли ви визначаєте декілька робочих процесів, ви можете розглянути можливість використання Реєстру
,
який є об'єктом, що зберігає та надає доступ до різних робочих процесів.
Реєстр також допоможе вам вирішити, чи підтримує робочий процес об'єкт, з яким ви
намагаєтеся його використовувати:
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));
Потім ви можете скористатися реєстром, щоб отримати робочий процес для конкретного об'єкта:
1 2 3 4 5
$blogPost = new BlogPost();
$workflow = $registry->get($blogPost);
// ініціювати робочий процес
$workflow->getMarking($blogPost);
Caution
Майте на увазі, що впровадження Registry
у ваші сервіси не
рекомендується. Більше того, це перешкоджає роботі деяких оптимізацій, таких як ліниве завантаження
і може призвести до зниження продуктивності. Замість цього, ви завжди повинні
впроваджувати робочий процес, який вам потрібен.
Дізнайтеся більше
Прочитайте більше про використання Компонента Workflow всередині додатку Symfony.