Skip to content

Commit 60b7fcb

Browse files
committed
[FrameworkBundle] fixed guard event names for transitions
1 parent 8888e40 commit 60b7fcb

File tree

2 files changed

+45
-25
lines changed

2 files changed

+45
-25
lines changed

DependencyInjection/FrameworkExtension.php

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -602,15 +602,44 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
602602
@trigger_error(sprintf('The "type" option of the "framework.workflows.%s" configuration entry must be defined since Symfony 3.3. The default value will be "state_machine" in Symfony 4.0.', $name), E_USER_DEPRECATED);
603603
}
604604
$type = $workflow['type'];
605+
$workflowId = sprintf('%s.%s', $type, $name);
605606

607+
// Create transitions
606608
$transitions = array();
609+
$guardsConfiguration = array();
610+
// Global transition counter per workflow
611+
$transitionCounter = 0;
607612
foreach ($workflow['transitions'] as $transition) {
608613
if ('workflow' === $type) {
609-
$transitions[] = new Definition(Workflow\Transition::class, array($transition['name'], $transition['from'], $transition['to']));
614+
$transitionDefinition = new Definition(Workflow\Transition::class, array($transition['name'], $transition['from'], $transition['to']));
615+
$transitionDefinition->setPublic(false);
616+
$transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++);
617+
$container->setDefinition($transitionId, $transitionDefinition);
618+
$transitions[] = new Reference($transitionId);
619+
if (isset($transition['guard'])) {
620+
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
621+
$configuration->addArgument(new Reference($transitionId));
622+
$configuration->addArgument($transition['guard']);
623+
$configuration->setPublic(false);
624+
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
625+
$guardsConfiguration[$eventName][] = $configuration;
626+
}
610627
} elseif ('state_machine' === $type) {
611628
foreach ($transition['from'] as $from) {
612629
foreach ($transition['to'] as $to) {
613-
$transitions[] = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to));
630+
$transitionDefinition = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to));
631+
$transitionDefinition->setPublic(false);
632+
$transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++);
633+
$container->setDefinition($transitionId, $transitionDefinition);
634+
$transitions[] = new Reference($transitionId);
635+
if (isset($transition['guard'])) {
636+
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
637+
$configuration->addArgument(new Reference($transitionId));
638+
$configuration->addArgument($transition['guard']);
639+
$configuration->setPublic(false);
640+
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
641+
$guardsConfiguration[$eventName][] = $configuration;
642+
}
614643
}
615644
}
616645
}
@@ -641,7 +670,6 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
641670
}
642671

643672
// Create Workflow
644-
$workflowId = sprintf('%s.%s', $type, $name);
645673
$workflowDefinition = new ChildDefinition(sprintf('%s.abstract', $type));
646674
$workflowDefinition->replaceArgument(0, new Reference(sprintf('%s.definition', $workflowId)));
647675
if (isset($markingStoreDefinition)) {
@@ -677,16 +705,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
677705
}
678706

679707
// Add Guard Listener
680-
$guard = new Definition(Workflow\EventListener\GuardListener::class);
681-
$guard->setPrivate(true);
682-
$configuration = array();
683-
foreach ($workflow['transitions'] as $config) {
684-
$transitionName = $config['name'];
685-
686-
if (!isset($config['guard'])) {
687-
continue;
688-
}
689-
708+
if ($guardsConfiguration) {
690709
if (!class_exists(ExpressionLanguage::class)) {
691710
throw new LogicException('Cannot guard workflows as the ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
692711
}
@@ -695,20 +714,21 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
695714
throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security".');
696715
}
697716

698-
$eventName = sprintf('workflow.%s.guard.%s', $name, $transitionName);
699-
$guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition'));
700-
$configuration[$eventName] = $config['guard'];
701-
}
702-
if ($configuration) {
717+
$guard = new Definition(Workflow\EventListener\GuardListener::class);
718+
$guard->setPrivate(true);
719+
703720
$guard->setArguments(array(
704-
$configuration,
721+
$guardsConfiguration,
705722
new Reference('workflow.security.expression_language'),
706723
new Reference('security.token_storage'),
707724
new Reference('security.authorization_checker'),
708725
new Reference('security.authentication.trust_resolver'),
709726
new Reference('security.role_hierarchy'),
710727
new Reference('validator', ContainerInterface::NULL_ON_INVALID_REFERENCE),
711728
));
729+
foreach ($guardsConfiguration as $eventName => $config) {
730+
$guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition'));
731+
}
712732

713733
$container->setDefinition(sprintf('%s.listener.guard', $workflowId), $guard);
714734
$container->setParameter('workflow.has_guard_listeners', true);

Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
<framework:argument>a</framework:argument>
1414
</framework:marking-store>
1515
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
16-
<framework:place name="draft" />
17-
<framework:place name="wait_for_journalist" />
18-
<framework:place name="approved_by_journalist" />
19-
<framework:place name="wait_for_spellchecker" />
20-
<framework:place name="approved_by_spellchecker" />
21-
<framework:place name="published" />
16+
<framework:place>draft</framework:place>
17+
<framework:place>wait_for_journalist</framework:place>
18+
<framework:place>approved_by_journalist</framework:place>
19+
<framework:place>wait_for_spellchecker</framework:place>
20+
<framework:place>approved_by_spellchecker</framework:place>
21+
<framework:place>published</framework:place>
2222
<framework:transition name="request_review">
2323
<framework:from>draft</framework:from>
2424
<framework:to>wait_for_journalist</framework:to>

0 commit comments

Comments
 (0)