minor #23781 [Workflow] do not emit not needed guard events (xabbuh)

This PR was merged into the 3.4 branch.

Discussion
----------

[Workflow] do not emit not needed guard events

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #23677
| License       | MIT
| Doc PR        |

Commits
-------

47c68e12ea [Workflow] do not emit not needed guard events
This commit is contained in:
Fabien Potencier 2017-08-05 19:44:04 +02:00
commit 457d57b767
2 changed files with 36 additions and 2 deletions

View File

@ -137,6 +137,31 @@ class WorkflowTest extends TestCase
$this->assertFalse($workflow->can($subject, 't1'));
}
public function testCanDoesNotTriggerGuardEventsForNotEnabledTransitions()
{
$definition = $this->createComplexWorkflowDefinition();
$subject = new \stdClass();
$subject->marking = null;
$dispatchedEvents = array();
$eventDispatcher = new EventDispatcher();
$workflow = new Workflow($definition, new MultipleStateMarkingStore(), $eventDispatcher, 'workflow_name');
$workflow->apply($subject, 't1');
$workflow->apply($subject, 't2');
$eventDispatcher->addListener('workflow.workflow_name.guard.t3', function () use (&$dispatchedEvents) {
$dispatchedEvents[] = 'workflow_name.guard.t3';
});
$eventDispatcher->addListener('workflow.workflow_name.guard.t4', function () use (&$dispatchedEvents) {
$dispatchedEvents[] = 'workflow_name.guard.t4';
});
$workflow->can($subject, 't3');
$this->assertSame(array('workflow_name.guard.t3'), $dispatchedEvents);
}
/**
* @expectedException \Symfony\Component\Workflow\Exception\LogicException
* @expectedExceptionMessage Unable to apply transition "t2" for workflow "unnamed".

View File

@ -92,10 +92,19 @@ class Workflow
*/
public function can($subject, $transitionName)
{
$transitions = $this->getEnabledTransitions($subject);
$transitions = $this->definition->getTransitions();
$marking = $this->getMarking($subject);
foreach ($transitions as $transition) {
if ($transitionName === $transition->getName()) {
foreach ($transition->getFroms() as $place) {
if (!$marking->has($place)) {
// do not emit guard events for transitions where the marking does not contain
// all "from places" (thus the transition couldn't be applied anyway)
continue 2;
}
}
if ($transitionName === $transition->getName() && $this->doCan($subject, $marking, $transition)) {
return true;
}
}