Skip to content

Commit ce0fda6

Browse files
committed
bug #21793 [Workflow] Fixed marking state on leave and enter events (HeahDude)
This PR was merged into the 3.2 branch. Discussion ---------- [Workflow] Fixed marking state on leave and enter events | Q | A | ------------- | --- | Branch? | 3.2 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | ~ | License | MIT | Doc PR | related to symfony/symfony-docs#7528 It seems weird to me to dispatch an event while the marking is not yet marked by the new places. The event is still "marked" by old places when leaving occurs, my guess is that the symmetry should be mirrored. Do you agree? Should I add a test? Commits ------- 175858a [Workflow] Fixed marking state on leave and enter events
2 parents 2ec78c2 + 175858a commit ce0fda6

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

src/Symfony/Component/Workflow/Tests/WorkflowTest.php

+36
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPUnit\Framework\TestCase;
66
use Symfony\Component\EventDispatcher\EventDispatcher;
77
use Symfony\Component\Workflow\Definition;
8+
use Symfony\Component\Workflow\Event\Event;
89
use Symfony\Component\Workflow\Event\GuardEvent;
910
use Symfony\Component\Workflow\Marking;
1011
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
@@ -252,6 +253,41 @@ public function testApplyWithEventDispatcher()
252253
$this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents);
253254
}
254255

256+
public function testMarkingStateOnApplyWithEventDispatcher()
257+
{
258+
$definition = new Definition(range('a', 'f'), array(new Transition('t', range('a', 'c'), range('d', 'f'))));
259+
260+
$subject = new \stdClass();
261+
$subject->marking = array('a' => 1, 'b' => 1, 'c' => 1);
262+
263+
$dispatcher = new EventDispatcher();
264+
265+
$workflow = new Workflow($definition, new MultipleStateMarkingStore(), $dispatcher, 'test');
266+
267+
$assertInitialState = function (Event $event) {
268+
$this->assertEquals(new Marking(array('a' => 1, 'b' => 1, 'c' => 1)), $event->getMarking());
269+
};
270+
$assertTransitionState = function (Event $event) {
271+
$this->assertEquals(new Marking(array()), $event->getMarking());
272+
};
273+
274+
$dispatcher->addListener('workflow.leave', $assertInitialState);
275+
$dispatcher->addListener('workflow.test.leave', $assertInitialState);
276+
$dispatcher->addListener('workflow.test.leave.a', $assertInitialState);
277+
$dispatcher->addListener('workflow.test.leave.b', $assertInitialState);
278+
$dispatcher->addListener('workflow.test.leave.c', $assertInitialState);
279+
$dispatcher->addListener('workflow.transition', $assertTransitionState);
280+
$dispatcher->addListener('workflow.test.transition', $assertTransitionState);
281+
$dispatcher->addListener('workflow.test.transition.t', $assertTransitionState);
282+
$dispatcher->addListener('workflow.enter', $assertTransitionState);
283+
$dispatcher->addListener('workflow.test.enter', $assertTransitionState);
284+
$dispatcher->addListener('workflow.test.enter.d', $assertTransitionState);
285+
$dispatcher->addListener('workflow.test.enter.e', $assertTransitionState);
286+
$dispatcher->addListener('workflow.test.enter.f', $assertTransitionState);
287+
288+
$workflow->apply($subject, 't');
289+
}
290+
255291
public function testGetEnabledTransitions()
256292
{
257293
$definition = $this->createComplexWorkflowDefinition();

src/Symfony/Component/Workflow/Workflow.php

+14-10
Original file line numberDiff line numberDiff line change
@@ -223,20 +223,22 @@ private function guardTransition($subject, Marking $marking, Transition $transit
223223

224224
private function leave($subject, Transition $transition, Marking $marking)
225225
{
226+
$places = $transition->getFroms();
227+
226228
if (null !== $this->dispatcher) {
227229
$event = new Event($subject, $marking, $transition);
228230

229231
$this->dispatcher->dispatch('workflow.leave', $event);
230232
$this->dispatcher->dispatch(sprintf('workflow.%s.leave', $this->name), $event);
231-
}
232-
233-
foreach ($transition->getFroms() as $place) {
234-
$marking->unmark($place);
235233

236-
if (null !== $this->dispatcher) {
234+
foreach ($places as $place) {
237235
$this->dispatcher->dispatch(sprintf('workflow.%s.leave.%s', $this->name, $place), $event);
238236
}
239237
}
238+
239+
foreach ($places as $place) {
240+
$marking->unmark($place);
241+
}
240242
}
241243

242244
private function transition($subject, Transition $transition, Marking $marking)
@@ -254,20 +256,22 @@ private function transition($subject, Transition $transition, Marking $marking)
254256

255257
private function enter($subject, Transition $transition, Marking $marking)
256258
{
259+
$places = $transition->getTos();
260+
257261
if (null !== $this->dispatcher) {
258262
$event = new Event($subject, $marking, $transition);
259263

260264
$this->dispatcher->dispatch('workflow.enter', $event);
261265
$this->dispatcher->dispatch(sprintf('workflow.%s.enter', $this->name), $event);
262-
}
263-
264-
foreach ($transition->getTos() as $place) {
265-
$marking->mark($place);
266266

267-
if (null !== $this->dispatcher) {
267+
foreach ($places as $place) {
268268
$this->dispatcher->dispatch(sprintf('workflow.%s.enter.%s', $this->name, $place), $event);
269269
}
270270
}
271+
272+
foreach ($places as $place) {
273+
$marking->mark($place);
274+
}
271275
}
272276

273277
private function announce($subject, Transition $initialTransition, Marking $marking)

0 commit comments

Comments
 (0)