feature #30902 [Workflow] The TransitionEvent is able to modify the context (lyrixx)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Workflow] The TransitionEvent is able to modify the context

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

EUFOSSA

ping @HeahDude

Commits
-------

62ab775154 [Workflow] The TransitionEvent is able to modify the context
This commit is contained in:
Fabien Potencier 2019-04-06 20:25:25 +02:00
commit e2e38dea9a
5 changed files with 43 additions and 4 deletions

View File

@ -6,6 +6,7 @@ CHANGELOG
* Trigger `entered` event for subject entering in the Workflow for the first time.
* Added a context to `Workflow::apply()`. The `MethodMarkingStore` could be used to leverage this feature.
* The `TransitionEvent` is able to modify the context.
* Add style to transitions by declaring metadata:
use Symfony\Component\Workflow\Definition;

View File

@ -13,4 +13,15 @@ namespace Symfony\Component\Workflow\Event;
class TransitionEvent extends Event
{
private $context;
public function setContext(array $context)
{
$this->context = $context;
}
public function getContext(): array
{
return $this->context;
}
}

View File

@ -5,10 +5,12 @@ namespace Symfony\Component\Workflow\Tests;
final class Subject
{
private $marking;
private $context;
public function __construct($marking = null)
{
$this->marking = $marking;
$this->context = [];
}
public function getMarking()
@ -16,8 +18,14 @@ final class Subject
return $this->marking;
}
public function setMarking($marking)
public function setMarking($marking, array $context = [])
{
$this->marking = $marking;
$this->context = $context;
}
public function getContext(): array
{
return $this->context;
}
}

View File

@ -7,6 +7,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\Event\Event;
use Symfony\Component\Workflow\Event\GuardEvent;
use Symfony\Component\Workflow\Event\TransitionEvent;
use Symfony\Component\Workflow\Exception\NotEnabledTransitionException;
use Symfony\Component\Workflow\Marking;
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
@ -418,6 +419,21 @@ class WorkflowTest extends TestCase
$this->assertSame($eventNameExpected, $eventDispatcher->dispatchedEvents);
}
public function testApplyWithContext()
{
$definition = $this->createComplexWorkflowDefinition();
$subject = new Subject();
$eventDispatcher = new EventDispatcher();
$eventDispatcher->addListener('workflow.transition', function (TransitionEvent $event) {
$event->setContext(array_merge($event->getContext(), ['user' => 'admin']));
});
$workflow = new Workflow($definition, new MethodMarkingStore(), $eventDispatcher);
$workflow->apply($subject, 't1', ['foo' => 'bar']);
$this->assertSame(['foo' => 'bar', 'user' => 'admin'], $subject->getContext());
}
public function testEventName()
{
$definition = $this->createComplexWorkflowDefinition();

View File

@ -176,7 +176,7 @@ class Workflow implements WorkflowInterface
$this->leave($subject, $transition, $marking);
$this->transition($subject, $transition, $marking);
$context = $this->transition($subject, $transition, $marking, $context);
$this->enter($subject, $transition, $marking);
@ -308,17 +308,20 @@ class Workflow implements WorkflowInterface
}
}
private function transition($subject, Transition $transition, Marking $marking): void
private function transition($subject, Transition $transition, Marking $marking, array $context): array
{
if (null === $this->dispatcher) {
return;
return $context;
}
$event = new TransitionEvent($subject, $marking, $transition, $this);
$event->setContext($context);
$this->dispatcher->dispatch($event, WorkflowEvents::TRANSITION);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.transition', $this->name));
$this->dispatcher->dispatch($event, sprintf('workflow.%s.transition.%s', $this->name, $transition->getName()));
return $event->getContext();
}
private function enter($subject, Transition $transition, Marking $marking): void