8000 [FrameworkBundle] fixed guard event names for transitions · symfony/symfony@32b68cf · GitHub
[go: up one dir, main page]

Skip to content

Commit 32b68cf

Browse files
committed
[FrameworkBundle] fixed guard event names for transitions
1 parent fb88bfc commit 32b68cf

File tree

4 files changed

+54
-49
lines changed

4 files changed

+54
-49
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -602,15 +602,40 @@ 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();
607-
foreach ($workflow['transitions'] as $transition) {
609+
$guardsConfiguration = array();
610+
// Global transition counter per workflow
611+
$transitionCounter = 0;
612+
foreach (array_values($workflow['transitions']) as $number => $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+
$transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++);
616+
$container->setDefinition($transitionId, $transitionDefinition);
617+
$transitions[] = new Reference($transitionId);
618+
if (isset($transition['guard'])) {
619+
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
620+
$configuration->addArgument(new Reference($transitionId));
621+
$configuration->addArgument($transition['guard']);
622+
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
623+
$guardsConfiguration[$eventName][] = $configuration;
624+
}
610625
} elseif ('state_machine' === $type) {
611626
foreach ($transition['from'] as $from) {
612627
foreach ($transition['to'] as $to) {
613-
$transitions[] = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to));
628+
$transitionDefinition = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to));
629+
$transitionId = sprintf('%s.transition.%s', $workflowId, $transitionCounter++);
630+
$container->setDefinition($transitionId, $transitionDefinition);
631+
$transitions[] = new Reference($transitionId);
632+
if (isset($transition['guard'])) {
633+
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
634+
$configuration->addArgument(new Reference($transitionId));
635+
$configuration->addArgument($transition['guard']);
636+
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
637+
$guardsConfiguration[$eventName][] = $configuration;
638+
}
614639
}
615640
}
616641
}
@@ -641,7 +666,6 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
641666
}
642667

643668
// Create Workflow
644-
$workflowId = sprintf('%s.%s', $type, $name);
645669
$workflowDefinition = new ChildDefinition(sprintf('%s.abstract', $type));
646670
$workflowDefinition->replaceArgument(0, new Reference(sprintf('%s.definition', $workflowId)));
647671
if (isset($markingStoreDefinition)) {
@@ -677,16 +701,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
677701
}
678702

679703
// 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-
704+
if ($guardsConfiguration) {
690705
if (!class_exists(ExpressionLanguage::class)) {
691706
throw new LogicException('Cannot guard workflows as the ExpressionLanguage component is not installed. Try running "composer require symfony/expression-language".');
692707
}
@@ -695,20 +710,21 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
695710
throw new LogicException('Cannot guard workflows as the Security component is not installed. Try running "composer require symfony/security".');
696711
}
697712

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) {
713+
$guard = new Definition(Workflow\EventListener\GuardListener::class);
714+
$guard->setPrivate(true);
715+
703716
$guard->setArguments(array(
704-
$configuration,
717+
$guardsConfiguration,
705718
new Reference('workflow.security.expression_language'),
706719
new Reference('security.token_storage'),
707720
new Reference('security.authorization_checker'),
708721
new Reference('security.authentication.trust_resolver'),
709722
new Reference('security.role_hierarchy'),
710723
new Reference('validator', ContainerInterface::NULL_ON_INVALID_REFERENCE),
711724
));
725+
foreach ($guardsConfiguration as $eventName => $config) {
726+
$guard->addTag('kernel.event_listener', array('event' => $eventName, 'method' => 'onTransition'));
727+
}
712728

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

src/Symfony/Bundle/FrameworkBundle/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>

src/Symfony/Component/Workflow/EventListener/GuardListener.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Symfony\Component\Validator\Validator\ValidatorInterface;
1919
use Symfony\Component\Workflow\Event\GuardEvent;
2020
use Symfony\Component\Workflow\Exception\InvalidTokenConfigurationException;
21-
use Symfony\Component\Workflow\TransitionBlocker;
2221

2322
/**
2423
* @author Grégoire Pineau <lyrixx@lyrixx.info>
@@ -66,8 +65,7 @@ public function onTransition(GuardEvent $event, $eventName)
6665
private function validateGuardExpression(GuardEvent $event, string $expression)
6766
{
6867
if (!$this->expressionLanguage->evaluate($expression, $this->getVariables($event))) {
69-
$blocker = TransitionBlocker::createBlockedByExpressionGuardListener($expression);
70-
$event->addTransitionBlocker($blocker);
68+
$event->setBlocked(true);
7169
}
7270
}
7371

src/Symfony/Component/Workflow/Tests/EventListener/GuardListenerTest.php

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ class GuardListenerTest extends TestCase
2121
private $authenticationChecker;
2222
private $validator;
2323
private $listener;
24-
private $transition;
24+
private $configuration;
2525

2626
protected function setUp()
2727
{
28-
$configuration = array(
28+
$this->configuration = array(
2929
'test_is_granted' => 'is_granted("something")',
3030
'test_is_valid' => 'is_valid(subject)',
3131
'test_expression' => array(
32-
new GuardExpression($this->getTransition(true), '!is_valid(subject)'),
33-
new GuardExpression($this->getTransition(true), 'is_valid(subject)'),
32+
new GuardExpression(new Transition('name', 'from', 'to'), '!is_valid(subject)'),
33+
new GuardExpression(new Transition('name', 'from', 'to'), 'is_valid(subject)'),
3434
),
3535
);
3636
$expressionLanguage = new ExpressionLanguage();
@@ -41,7 +41,7 @@ protected function setUp()
4141
$this->authenticationChecker = $this->getMockBuilder(AuthorizationCheckerInterface::class)->getMock();
4242
$trustResolver = $this->getMockBuilder(AuthenticationTrustResolverInterface::class)->getMock();
4343
$this->validator = $this->getMockBuilder(ValidatorInterface::class)->getMock();
44-
$this->listener = new GuardListener($configuration, $expressionLanguage, $tokenStorage, $this->authenticationChecker, $trustResolver, null, $this->validator);
44+
$this->listener = new GuardListener($this->configuration, $expressionLanguage, $tokenStorage, $this->authenticationChecker, $trustResolver, null, $this->validator);
4545
}
4646

4747
protected function tearDown()
@@ -104,16 +104,16 @@ public function testWithValidatorSupportedEventAndAccept()
104104

105105
public function testWithGuardExpressionWithNotSupportedTransition()
106106
{
107-
$event = $this->createEvent(true);
108-
$this->configureValidator(false, false);
107+
$event = $this->createEvent();
108+
$this->configureValidator(false);
109109
$this->listener->onTransition($event, 'test_expression');
110110

111111
$this->assertFalse($event->isBlocked());
112112
}
113113

114114
public function testWithGuardExpressionWithSupportedTransition()
115115
{
116-
$event = $this->createEvent();
116+
$event = $this->createEvent($this->configuration['test_expression'][1]->getTransition());
117117
$this->configureValidator(true, true);
118118
$this->listener->onTransition($event, 'test_expression');
119119

@@ -122,18 +122,18 @@ public function testWithGuardExpressionWithSupportedTransition()
122122

123123
public function testGuardExpressionBlocks()
124124
{
125-
$event = $this->createEvent();
125+
$event = $this->createEvent($this->configuration['test_expression'][1]->getTransition());
126126
$this->configureValidator(true, false);
127127
$this->listener->onTransition($event, 'test_expression');
128128

129129
$this->assertTrue($event->isBlocked());
130130
}
131131

132-
private function createEvent($newTransition = false)
132+
private function createEvent(Transition $transition = null)
133133
{
134134
$subject = new \stdClass();
135135
$subject->marking = new Marking();
136-
$transition = $this->getTransition($newTransition);
136+
$transition = $transition ?: new Transition('name', 'from', 'to');
137137

138138
return new GuardEvent($subject, $subject->marking, $transition);
139139
}
@@ -173,13 +173,4 @@ private function configureValidator($isUsed, $valid = true)
173173
->willReturn($valid ? array() : array('a violation'))
174174
;
175175
}
176-
177-
private function getTransition($new = false)
178-
{
179-
if ($new || !$this->transition) {
180-
$this->transition = new Transition('name', 'from', 'to');
181-
}
182-
183-
return $this->transition;
184-
}
185176
}

0 commit comments

Comments
 (0)
0