Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Workflow] Added Context to Workflow Event #37539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions 1 src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* WorkflowExtension.
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
lyrixx marked this conversation as resolved.
Show resolved Hide resolved
*/
final class WorkflowExtension extends AbstractExtension
{
Expand Down
2 changes: 2 additions & 0 deletions 2 src/Symfony/Component/Workflow/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ CHANGELOG
-----

* Added `Workflow::getEnabledTransition()` to easily retrieve a specific transition object
* Added context to the event dispatched
* Added default context to the Initial Marking

5.1.0
-----
Expand Down
10 changes: 9 additions & 1 deletion 10 src/Symfony/Component/Workflow/Event/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@
/**
* @author Fabien Potencier <fabien@symfony.com>
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
*/
class Event extends BaseEvent
{
protected $context;
private $subject;
private $marking;
private $transition;
private $workflow;

public function __construct(object $subject, Marking $marking, Transition $transition = null, WorkflowInterface $workflow = null)
public function __construct(object $subject, Marking $marking, Transition $transition = null, WorkflowInterface $workflow = null, array $context = [])
{
$this->subject = $subject;
$this->marking = $marking;
$this->transition = $transition;
$this->workflow = $workflow;
$this->context = $context;
}

public function getMarking()
Expand Down Expand Up @@ -64,4 +67,9 @@ public function getMetadata(string $key, $subject)
{
return $this->workflow->getMetadataStore()->getMetadata($key, $subject);
}

public function getContext(): array
{
return $this->context;
}
}
7 changes: 0 additions & 7 deletions 7 src/Symfony/Component/Workflow/Event/TransitionEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,8 @@

final class TransitionEvent extends Event
{
private $context;

public function setContext(array $context): void
{
$this->context = $context;
}

public function getContext(): array
{
return $this->context;
}
}
54 changes: 54 additions & 0 deletions 54 src/Symfony/Component/Workflow/Tests/WorkflowTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ public function testApplyWithEventDispatcher()
$eventNameExpected = [
'workflow.entered',
'workflow.workflow_name.entered',
'workflow.workflow_name.entered.a',
'workflow.guard',
'workflow.workflow_name.guard',
'workflow.workflow_name.guard.t1',
Expand Down Expand Up @@ -463,6 +464,7 @@ public function testApplyDoesNotTriggerExtraGuardWithEventDispatcher()
$eventNameExpected = [
'workflow.entered',
'workflow.workflow_name.entered',
'workflow.workflow_name.entered.a',
'workflow.guard',
'workflow.workflow_name.guard',
'workflow.workflow_name.guard.a-b',
Expand Down Expand Up @@ -533,6 +535,58 @@ public function testEventName()
$workflow->apply($subject, 't1');
}

public function testEventContext()
{
$definition = $this->createComplexWorkflowDefinition();
$subject = new Subject();
$dispatcher = new EventDispatcher();
$name = 'workflow_name';
$context = ['context'];
$workflow = new Workflow($definition, new MethodMarkingStore(), $dispatcher, $name);

$assertWorkflowContext = function (Event $event) use ($context) {
$this->assertEquals($context, $event->getContext());
};

$eventNames = [
'workflow.leave',
'workflow.transition',
'workflow.enter',
'workflow.entered',
'workflow.announce',
];

foreach ($eventNames as $eventName) {
$dispatcher->addListener($eventName, $assertWorkflowContext);
}

$workflow->apply($subject, 't1', $context);
}

public function testEventDefaultInitialContext()
{
$definition = $this->createComplexWorkflowDefinition();
$subject = new Subject();
$dispatcher = new EventDispatcher();
$name = 'workflow_name';
$context = Workflow::DEFAULT_INITIAL_CONTEXT;
$workflow = new Workflow($definition, new MethodMarkingStore(), $dispatcher, $name);

$assertWorkflowContext = function (Event $event) use ($context) {
$this->assertEquals($context, $event->getContext());
};

$eventNames = [
'workflow.workflow_name.entered.a',
];

foreach ($eventNames as $eventName) {
$dispatcher->addListener($eventName, $assertWorkflowContext);
}

$workflow->apply($subject, 't1');
}

public function testMarkingStateOnApplyWithEventDispatcher()
{
$definition = new Definition(range('a', 'f'), [new Transition('t', range('a', 'c'), range('d', 'f'))]);
Expand Down
49 changes: 29 additions & 20 deletions 49 src/Symfony/Component/Workflow/Workflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
* @author Fabien Potencier <fabien@symfony.com>
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
*/
class Workflow implements WorkflowInterface
{
public const DISABLE_ANNOUNCE_EVENT = 'workflow_disable_announce_event';
public const DEFAULT_INITIAL_CONTEXT = ['initial' => true];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you made this an associative array and not an indexed one?
public const DEFAULT_INITIAL_CONTEXT = ['initial'];

I see in one of your tests you did use an indexed array as $context.

Are yuo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this way, you can do :
if ($context['initial']??false)


private $definition;
private $markingStore;
Expand All @@ -51,7 +53,7 @@ public function __construct(Definition $definition, MarkingStoreInterface $marki
/**
* {@inheritdoc}
*/
public function getMarking(object $subject)
public function getMarking(object $subject, array $context = [])
{
$marking = $this->markingStore->getMarking($subject);

Expand All @@ -71,7 +73,11 @@ public function getMarking(object $subject)
// update the subject with the new marking
$this->markingStore->setMarking($subject, $marking);

$this->entered($subject, null, $marking);
if (!$context) {
$context = self::DEFAULT_INITIAL_CONTEXT;
}

$this->entered($subject, null, $marking, $context);
}

// check that the subject has a known place
Expand Down Expand Up @@ -154,7 +160,7 @@ public function buildTransitionBlockerList(object $subject, string $transitionNa
*/
public function apply(object $subject, string $transitionName, array $context = [])
{
$marking = $this->getMarking($subject);
$marking = $this->getMarking($subject, $context);

$transitionExist = false;
$approvedTransitions = [];
Expand Down Expand Up @@ -197,20 +203,20 @@ public function apply(object $subject, string $transitionName, array $context =
}

foreach ($approvedTransitions as $transition) {
$this->leave($subject, $transition, $marking);
$this->leave($subject, $transition, $marking, $context);

$context = $this->transition($subject, $transition, $marking, $context);

$this->enter($subject, $transition, $marking);
$this->enter($subject, $transition, $marking, $context);

$this->markingStore->setMarking($subject, $marking, $context);

$this->entered($subject, $transition, $marking);
$this->entered($subject, $transition, $marking, $context);

$this->completed($subject, $transition, $marking);
$this->completed($subject, $transition, $marking, $context);

if (!($context[self::DISABLE_ANNOUNCE_EVENT] ?? false)) {
$this->announce($subject, $transition, $marking);
$this->announce($subject, $transition, $marking, $context);
}
}

Expand Down Expand Up @@ -324,12 +330,12 @@ private function guardTransition(object $subject, Marking $marking, Transition $
return $event;
}

private function leave(object $subject, Transition $transition, Marking $marking): void
private function leave(object $subject, Transition $transition, Marking $marking, array $context = []): void
{
$places = $transition->getFroms();

if (null !== $this->dispatcher) {
$event = new LeaveEvent($subject, $marking, $transition, $this);
$event = new LeaveEvent($subject, $marking, $transition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::LEAVE);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.leave', $this->name));
Expand All @@ -350,8 +356,7 @@ private function transition(object $subject, Transition $transition, Marking $ma
return $context;
}

$event = new TransitionEvent($subject, $marking, $transition, $this);
$event->setContext($context);
$event = new TransitionEvent($subject, $marking, $transition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::TRANSITION);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.transition', $this->name));
Expand All @@ -360,12 +365,12 @@ private function transition(object $subject, Transition $transition, Marking $ma
return $event->getContext();
}

private function enter(object $subject, Transition $transition, Marking $marking): void
private function enter(object $subject, Transition $transition, Marking $marking, array $context): void
{
$places = $transition->getTos();

if (null !== $this->dispatcher) {
$event = new EnterEvent($subject, $marking, $transition, $this);
$event = new EnterEvent($subject, $marking, $transition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::ENTER);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.enter', $this->name));
Expand All @@ -380,13 +385,13 @@ private function enter(object $subject, Transition $transition, Marking $marking
}
}

private function entered(object $subject, ?Transition $transition, Marking $marking): void
private function entered(object $subject, ?Transition $transition, Marking $marking, array $context): void
{
if (null === $this->dispatcher) {
return;
}

$event = new EnteredEvent($subject, $marking, $transition, $this);
$event = new EnteredEvent($subject, $marking, $transition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::ENTERED);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered', $this->name));
Expand All @@ -395,29 +400,33 @@ private function entered(object $subject, ?Transition $transition, Marking $mark
foreach ($transition->getTos() as $place) {
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered.%s', $this->name, $place));
}
} elseif (!empty($this->definition->getInitialPlaces())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not related to the current PR. Could you revert it? thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without that, the DEFAULT_INITIAL_CONTEXT makes no sense.

it's a little far fetched, but I believe adding this context enhancement is a good moment to add this default context

Unless you don't want a DEFAULT_INITIAL_CONTEXT ?

foreach ($this->definition->getInitialPlaces() as $place) {
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered.%s', $this->name, $place));
}
}
}

private function completed(object $subject, Transition $transition, Marking $marking): void
private function completed(object $subject, Transition $transition, Marking $marking, array $context): void
{
if (null === $this->dispatcher) {
return;
}

$event = new CompletedEvent($subject, $marking, $transition, $this);
$event = new CompletedEvent($subject, $marking, $transition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::COMPLETED);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.completed', $this->name));
$this->dispatcher->dispatch($event, sprintf('workflow.%s.completed.%s', $this->name, $transition->getName()));
}

private function announce(object $subject, Transition $initialTransition, Marking $marking): void
private function announce(object $subject, Transition $initialTransition, Marking $marking, array $context): void
{
if (null === $this->dispatcher) {
return;
}

$event = new AnnounceEvent($subject, $marking, $initialTransition, $this);
$event = new AnnounceEvent($subject, $marking, $initialTransition, $this, $context);

$this->dispatcher->dispatch($event, WorkflowEvents::ANNOUNCE);
$this->dispatcher->dispatch($event, sprintf('workflow.%s.announce', $this->name));
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.