@@ -530,26 +530,31 @@ if you are using Doctrine, the matching column definition should use the type ``
530
530
Accessing the Workflow in a Class
531
531
---------------------------------
532
532
533
- You can use the workflow inside a class by using
534
- :doc: `service autowiring </service_container/autowiring >` and using
535
- ``camelCased workflow name + Workflow `` as parameter name. If it is a state
536
- machine type, use ``camelCased workflow name + StateMachine ``::
533
+ Symfony creates a service for each workflow you define. You have two ways of
534
+ injecting each workflow in any service or controller:
535
+
536
+ **(1) Use a specific argument name **
537
+
538
+ Type-hint your construtor/method argument with ``WorkflowInterface `` and name the
539
+ argument using this pattern: "workflow name in camelCase" + ``Workflow `` suffix.
540
+ If it is a state machine type, use the ``StateMachine `` suffix.
541
+
542
+ For example, to inject the ``blog_publishing `` workflow defined earlier::
537
543
538
544
use App\Entity\BlogPost;
539
545
use Symfony\Component\Workflow\WorkflowInterface;
540
546
541
547
class MyClass
542
548
{
543
549
public function __construct(
544
- // Symfony will inject the 'blog_publishing' workflow configured before
545
550
private WorkflowInterface $blogPublishingWorkflow,
546
551
) {
547
552
}
548
553
549
554
public function toReview(BlogPost $post): void
550
555
{
551
- // Update the currentState on the post
552
556
try {
557
+ // update the currentState on the post
553
558
$this->blogPublishingWorkflow->apply($post, 'to_review');
554
559
} catch (LogicException $exception) {
555
560
// ...
@@ -558,31 +563,30 @@ machine type, use ``camelCased workflow name + StateMachine``::
558
563
}
559
564
}
560
565
561
- To get the enabled transition of a Workflow, you can use
562
- :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
563
- method.
566
+ **(2) Use the ``#[Target]`` attribute **
564
567
565
- Workflows can also be injected thanks to their name and the
566
- :class: `Symfony\\ Component\\ DependencyInjection\\ Attribute\\ Target `
567
- attribute::
568
+ When :ref: `dealing with multiple implementations of the same type <autowiring-multiple-implementations-same-type >`
569
+ the ``#[Target] `` attribute helps you select which one to inject. Symfony creates
570
+ a target with the same name as each workflow.
571
+
572
+ For example, to select the ``blog_publishing `` lock defined earlier::
568
573
569
- use App\Entity\BlogPost;
570
574
use Symfony\Component\DependencyInjection\Attribute\Target;
571
575
use Symfony\Component\Workflow\WorkflowInterface;
572
576
573
577
class MyClass
574
578
{
575
579
public function __construct(
576
- #[Target('blog_publishing')]
577
- private WorkflowInterface $workflow
580
+ #[Target('blog_publishing')] private WorkflowInterface $workflow,
578
581
) {
579
582
}
580
583
581
584
// ...
582
585
}
583
586
584
- This allows you to decorrelate the argument name of any implementation
585
- name.
587
+ To get the enabled transition of a Workflow, you can use
588
+ :method: `Symfony\\ Component\\ Workflow\\ WorkflowInterface::getEnabledTransition `
589
+ method.
586
590
587
591
.. tip ::
588
592
@@ -604,6 +608,48 @@ name.
604
608
You can find the list of available workflow services with the
605
609
``php bin/console debug:autowiring workflow `` command.
606
610
611
+ Injecting Multiple Workflows
612
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
613
+
614
+ Use the :ref: `AutowireLocator <service-locator_autowire-locator >` attribute to
615
+ lazy-load all workflows and get the one you need::
616
+
617
+ use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
618
+ use Symfony\Component\DependencyInjection\ServiceLocator;
619
+
620
+ class MyClass
621
+ {
622
+ public function __construct(
623
+ // 'workflow' is the service tag name and injects both workflows and state machines;
624
+ // 'name' tells Symfony to index services using that tag property
625
+ #[AutowireLocator('workflow', 'name')]
626
+ private ServiceLocator $workflows,
627
+ ) {
628
+ }
629
+
630
+ public function someMethod(): void
631
+ {
632
+ // if you use the 'name' tag property to index services (see constructor above),
633
+ // you can get workflows by their name; otherwise, you must use the full
634
+ // service name with the 'workflow.' prefix (e.g. 'workflow.user_registration')
635
+ $workflow = $this->workflows->get('user_registration');
636
+
637
+ // ...
638
+ }
639
+ }
640
+
641
+ .. tip ::
642
+
643
+ You can also inject only workflows or only state machines::
644
+
645
+ public function __construct(
646
+ #[AutowireLocator('workflow.workflow', 'name')]
647
+ private ServiceLocator $workflows,
648
+ #[AutowireLocator('workflow.state_machine', 'name')]
649
+ private ServiceLocator $stateMachines,
650
+ ) {
651
+ }
652
+
607
653
.. _workflow_using-events :
608
654
609
655
Using Events
0 commit comments