@@ -485,6 +485,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
485485
486486 foreach ($ config ['workflows ' ] as $ name => $ workflow ) {
487487 $ type = $ workflow ['type ' ];
488+ $ workflowId = sprintf ('%s.%s ' , $ type , $ name );
488489
489490 // Process Metadata (workflow + places (transition is done in the "create transition" block))
490491 $ metadataStoreDefinition = new Definition (Workflow \Metadata \InMemoryMetadataStore::class, array (array (), array (), null ));
@@ -503,11 +504,25 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
503504
504505 // Create transitions
505506 $ transitions = array ();
507+ $ guardsConfiguration = array ();
506508 $ transitionsMetadataDefinition = new Definition (\SplObjectStorage::class);
509+ // Global transition counter per workflow
510+ $ transitionCounter = 0 ;
507511 foreach ($ workflow ['transitions ' ] as $ transition ) {
508512 if ('workflow ' === $ type ) {
509513 $ transitionDefinition = new Definition (Workflow \Transition::class, array ($ transition ['name ' ], $ transition ['from ' ], $ transition ['to ' ]));
510- $ transitions [] = $ transitionDefinition ;
514+ $ transitionDefinition ->setPublic (false );
515+ $ transitionId = sprintf ('%s.transition.%s ' , $ workflowId , $ transitionCounter ++);
516+ $ container ->setDefinition ($ transitionId , $ transitionDefinition );
517+ $ transitions [] = new Reference ($ transitionId );
518+ if (isset ($ transition ['guard ' ])) {
519+ $ configuration = new Definition (Workflow \EventListener \GuardExpression::class);
520+ $ configuration ->addArgument (new Reference ($ transitionId ));
521+ $ configuration ->addArgument ($ transition ['guard ' ]);
522+ $ configuration ->setPublic (false );
523+ $ eventName = sprintf ('workflow.%s.guard.%s ' , $ name , $ transition ['name ' ]);
524+ $ guardsConfiguration [$ eventName ][] = $ configuration ;
525+ }
511526 if ($ transition ['metadata ' ]) {
512527 $ transitionsMetadataDefinition ->addMethodCall ('attach ' , array (
513528 $ transitionDefinition ,
@@ -518,7 +533,18 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
518533 foreach ($ transition ['from ' ] as $ from ) {
519534 foreach ($ transition ['to ' ] as $ to ) {
520535 $ transitionDefinition = new Definition (Workflow \Transition::class, array ($ transition ['name ' ], $ from , $ to ));
521- $ transitions [] = $ transitionDefinition ;
536+ $ transitionDefinition ->setPublic (false );
537+ $ transitionId = sprintf ('%s.transition.%s ' , $ workflowId , $ transitionCounter ++);
538+ $ container ->setDefinition ($ transitionId , $ transitionDefinition );
539+ $ transitions [] = new Reference ($ transitionId );
540+ if (isset ($ transition ['guard ' ])) {
541+ $ configuration = new Definition (Workflow \EventListener \GuardExpression::class);
542+ $ configuration ->addArgument (new Reference ($ transitionId ));
543+ $ configuration ->addArgument ($ transition ['guard ' ]);
544+ $ configuration ->setPublic (false );
545+ $ eventName = sprintf ('workflow.%s.guard.%s ' , $ name , $ transition ['name ' ]);
546+ $ guardsConfiguration [$ eventName ][] = $ configuration ;
547+ }
522548 if ($ transition ['metadata ' ]) {
523549 $ transitionsMetadataDefinition ->addMethodCall ('attach ' , array (
524550 $ transitionDefinition ,
@@ -560,7 +586,6 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
560586 }
561587
562588 // Create Workflow
563- $ workflowId = sprintf ('%s.%s ' , $ type , $ name );
564589 $ workflowDefinition = new ChildDefinition (sprintf ('%s.abstract ' , $ type ));
565590 $ workflowDefinition ->replaceArgument (0 , new Reference (sprintf ('%s.definition ' , $ workflowId )));
566591 if (isset ($ markingStoreDefinition )) {
@@ -596,16 +621,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
596621 }
597622
598623 // Add Guard Listener
599- $ guard = new Definition (Workflow \EventListener \GuardListener::class);
600- $ guard ->setPrivate (true );
601- $ configuration = array ();
602- foreach ($ workflow ['transitions ' ] as $ config ) {
603- $ transitionName = $ config ['name ' ];
604-
605- if (!isset ($ config ['guard ' ])) {
606- continue ;
607- }
608-
624+ if ($ guardsConfiguration ) {
609625 if (!class_exists (ExpressionLanguage::class)) {
610626 throw new LogicException ('Cannot guard workflows as the ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language". ' );
611627 }
@@ -614,20 +630,21 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
614630 throw new LogicException ('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security". ' );
615631 }
616632
617- $ eventName = sprintf ('workflow.%s.guard.%s ' , $ name , $ transitionName );
618- $ guard ->addTag ('kernel.event_listener ' , array ('event ' => $ eventName , 'method ' => 'onTransition ' ));
619- $ configuration [$ eventName ] = $ config ['guard ' ];
620- }
621- if ($ configuration ) {
633+ $ guard = new Definition (Workflow \EventListener \GuardListener::class);
634+ $ guard ->setPrivate (true );
635+
622636 $ guard ->setArguments (array (
623- $ configuration ,
637+ $ guardsConfiguration ,
624638 new Reference ('workflow.security.expression_language ' ),
625639 new Reference ('security.token_storage ' ),
626640 new Reference ('security.authorization_checker ' ),
627641 new Reference ('security.authentication.trust_resolver ' ),
628642 new Reference ('security.role_hierarchy ' ),
629643 new Reference ('validator ' , ContainerInterface::NULL_ON_INVALID_REFERENCE ),
630644 ));
645+ foreach ($ guardsConfiguration as $ eventName => $ config ) {
646+ $ guard ->addTag ('kernel.event_listener ' , array ('event ' => $ eventName , 'method ' => 'onTransition ' ));
647+ }
631648
632649 $ container ->setDefinition (sprintf ('%s.listener.guard ' , $ workflowId ), $ guard );
633650 $ container ->setParameter ('workflow.has_guard_listeners ' , true );
0 commit comments