diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php index 68ebaafcd9aa..d6f6bae45cbf 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php @@ -304,6 +304,45 @@ public function testApplyWithEventDispatcher() $this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents); } + public function testApplyDoesNotTriggerExtraGuardWithEventDispatcher() + { + $transitions[] = new Transition('a-b', 'a', 'b'); + $transitions[] = new Transition('a-c', 'a', 'c'); + $definition = new Definition(['a', 'b', 'c'], $transitions); + + $subject = new \stdClass(); + $subject->marking = null; + $eventDispatcher = new EventDispatcherMock(); + $workflow = new Workflow($definition, new MultipleStateMarkingStore(), $eventDispatcher, 'workflow_name'); + + $eventNameExpected = [ + 'workflow.guard', + 'workflow.workflow_name.guard', + 'workflow.workflow_name.guard.a-b', + 'workflow.leave', + 'workflow.workflow_name.leave', + 'workflow.workflow_name.leave.a', + 'workflow.transition', + 'workflow.workflow_name.transition', + 'workflow.workflow_name.transition.a-b', + 'workflow.enter', + 'workflow.workflow_name.enter', + 'workflow.workflow_name.enter.b', + 'workflow.entered', + 'workflow.workflow_name.entered', + 'workflow.workflow_name.entered.b', + 'workflow.completed', + 'workflow.workflow_name.completed', + 'workflow.workflow_name.completed.a-b', + 'workflow.announce', + 'workflow.workflow_name.announce', + ]; + + $marking = $workflow->apply($subject, 'a-b'); + + $this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents); + } + public function testEventName() { $definition = $this->createComplexWorkflowDefinition(); diff --git a/src/Symfony/Component/Workflow/Workflow.php b/src/Symfony/Component/Workflow/Workflow.php index a0500b3796bf..18ca7f796902 100644 --- a/src/Symfony/Component/Workflow/Workflow.php +++ b/src/Symfony/Component/Workflow/Workflow.php @@ -125,22 +125,20 @@ public function can($subject, $transitionName) */ public function apply($subject, $transitionName) { - $transitions = $this->getEnabledTransitions($subject); - - // We can shortcut the getMarking method in order to boost performance, - // since the "getEnabledTransitions" method already checks the Marking - // state - $marking = $this->markingStore->getMarking($subject); - - $applied = false; + $marking = $this->getMarking($subject); + $transitions = []; - foreach ($transitions as $transition) { - if ($transitionName !== $transition->getName()) { - continue; + foreach ($this->definition->getTransitions() as $transition) { + if ($transitionName === $transition->getName() && $this->doCan($subject, $marking, $transition)) { + $transitions[] = $transition; } + } - $applied = true; + if (!$transitions) { + throw new LogicException(sprintf('Unable to apply transition "%s" for workflow "%s".', $transitionName, $this->name)); + } + foreach ($transitions as $transition) { $this->leave($subject, $transition, $marking); $this->transition($subject, $transition, $marking); @@ -156,10 +154,6 @@ public function apply($subject, $transitionName) $this->announce($subject, $transition, $marking); } - if (!$applied) { - throw new LogicException(sprintf('Unable to apply transition "%s" for workflow "%s".', $transitionName, $this->name)); - } - return $marking; }