feature #22587 [Workflow] Add transition completed event (izzyp)

This PR was merged into the 3.4 branch.

Discussion
----------

[Workflow] Add transition completed event

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR | https://github.com/symfony/symfony-docs/pull/8213

---

Because the "entered" event is the only event dispatched after the new marking is applied, and publish's an event upon entering into a "Place" (as opposed to completing a transition), it is not sufficient for a lot of use cases and is causing bugs.

Example:
Enabled Transitions:
1. A -> B
2. B -> C
3. C -> B

Transition 1 and transition 3, will dispatch an "entered" event on Place B, forcing post transition behaviour to be the same for both transition 1 and 3.

A user might need different behaviour depending on the transition, rather the the destination.
A concrete use case would be when applying an "undo" transition to a subject. One may or may not want to re-trigger all the events associated with the original transition to that Place.

I propose adding a "completed" event (ie. Transition completed) in addition to the entered event.

Commits
-------

c254cac [Workflow] Added an transition completed event
This commit is contained in:
Grégoire Pineau 2017-08-07 12:16:44 +02:00
commit 6c0e48d702
3 changed files with 19 additions and 0 deletions

View File

@ -5,6 +5,7 @@ CHANGELOG
-----
* Added support for `Event::getWorkflowName()` for "announce" events.
* Added `workflow.completed` events which are fired after a transition is completed.
3.3.0
-----

View File

@ -287,6 +287,9 @@ class WorkflowTest extends TestCase
'workflow.workflow_name.entered',
'workflow.workflow_name.entered.b',
'workflow.workflow_name.entered.c',
'workflow.completed',
'workflow.workflow_name.completed',
'workflow.workflow_name.completed.t1',
// Following events are fired because of announce() method
'workflow.announce',
'workflow.workflow_name.announce',

View File

@ -151,6 +151,8 @@ class Workflow
$this->entered($subject, $transition, $marking);
$this->completed($subject, $transition, $marking);
$this->announce($subject, $transition, $marking);
}
@ -309,6 +311,19 @@ class Workflow
}
}
private function completed($subject, Transition $transition, Marking $marking)
{
if (null === $this->dispatcher) {
return;
}
$event = new Event($subject, $marking, $transition, $this->name);
$this->dispatcher->dispatch('workflow.completed', $event);
$this->dispatcher->dispatch(sprintf('workflow.%s.completed', $this->name), $event);
$this->dispatcher->dispatch(sprintf('workflow.%s.completed.%s', $this->name, $transition->getName()), $event);
}
private function announce($subject, Transition $initialTransition, Marking $marking)
{
if (null === $this->dispatcher) {