Skip to content

Commit 7756024

Browse files
committed
Added Context to Workflow Event
There's also a default context for the initial marking event.
1 parent 812a4d5 commit 7756024

File tree

6 files changed

+102
-35
lines changed

6 files changed

+102
-35
lines changed

src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* WorkflowExtension.
2222
*
2323
* @author Grégoire Pineau <lyrixx@lyrixx.info>
24+
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
2425
*/
2526
final class WorkflowExtension extends AbstractExtension
2627
{

src/Symfony/Component/Workflow/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
-----
66

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

911
5.1.0
1012
-----

src/Symfony/Component/Workflow/Event/Event.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,23 @@
1919
/**
2020
* @author Fabien Potencier <fabien@symfony.com>
2121
* @author Grégoire Pineau <lyrixx@lyrixx.info>
22+
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
2223
*/
2324
class Event extends BaseEvent
2425
{
2526
private $subject;
2627
private $marking;
2728
private $transition;
2829
private $workflow;
30+
protected $context;
2931

30-
public function __construct(object $subject, Marking $marking, Transition $transition = null, WorkflowInterface $workflow = null)
32+
public function __construct(object $subject, Marking $marking, Transition $transition = null, WorkflowInterface $workflow = null, array $context = [])
3133
{
3234
$this->subject = $subject;
3335
$this->marking = $marking;
3436
$this->transition = $transition;
3537
$this->workflow = $workflow;
38+
$this->context = $context;
3639
}
3740

3841
public function getMarking()
@@ -64,4 +67,9 @@ public function getMetadata(string $key, $subject)
6467
{
6568
return $this->workflow->getMetadataStore()->getMetadata($key, $subject);
6669
}
70+
71+
public function getContext(): array
72+
{
73+
return $this->context;
74+
}
6775
}

src/Symfony/Component/Workflow/Event/TransitionEvent.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,8 @@
1313

1414
final class TransitionEvent extends Event
1515
{
16-
private $context;
17-
1816
public function setContext(array $context): void
1917
{
2018
$this->context = $context;
2119
}
22-
23-
public function getContext(): array
24-
{
25-
return $this->context;
26-
}
2720
}

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ public function testApplyWithEventDispatcher()
392392
$eventNameExpected = [
393393
'workflow.entered',
394394
'workflow.workflow_name.entered',
395+
'workflow.workflow_name.entered.a',
395396
'workflow.guard',
396397
'workflow.workflow_name.guard',
397398
'workflow.workflow_name.guard.t1',
@@ -463,6 +464,7 @@ public function testApplyDoesNotTriggerExtraGuardWithEventDispatcher()
463464
$eventNameExpected = [
464465
'workflow.entered',
465466
'workflow.workflow_name.entered',
467+
'workflow.workflow_name.entered.a',
466468
'workflow.guard',
467469
'workflow.workflow_name.guard',
468470
'workflow.workflow_name.guard.a-b',
@@ -533,6 +535,58 @@ public function testEventName()
533535
$workflow->apply($subject, 't1');
534536
}
535537

538+
public function testEventContext()
539+
{
540+
$definition = $this->createComplexWorkflowDefinition();
541+
$subject = new Subject();
542+
$dispatcher = new EventDispatcher();
543+
$name = 'workflow_name';
544+
$context = ['context'];
545+
$workflow = new Workflow($definition, new MethodMarkingStore(), $dispatcher, $name);
546+
547+
$assertWorkflowContext = function (Event $event) use ($context) {
548+
$this->assertEquals($context, $event->getContext());
549+
};
550+
551+
$eventNames = [
552+
'workflow.leave',
553+
'workflow.transition',
554+
'workflow.enter',
555+
'workflow.entered',
556+
'workflow.announce',
557+
];
558+
559+
foreach ($eventNames as $eventName) {
560+
$dispatcher->addListener($eventName, $assertWorkflowContext);
561+
}
562+
563+
$workflow->apply($subject, 't1', $context);
564+
}
565+
566+
public function testEventDefaultInitialContext()
567+
{
568+
$definition = $this->createComplexWorkflowDefinition();
569+
$subject = new Subject();
570+
$dispatcher = new EventDispatcher();
571+
$name = 'workflow_name';
572+
$context = Workflow::DEFAULT_INITIAL_CONTEXT;
573+
$workflow = new Workflow($definition, new MethodMarkingStore(), $dispatcher, $name);
574+
575+
$assertWorkflowContext = function (Event $event) use ($context) {
576+
$this->assertEquals($context, $event->getContext());
577+
};
578+
579+
$eventNames = [
580+
'workflow.workflow_name.entered.a',
581+
];
582+
583+
foreach ($eventNames as $eventName) {
584+
$dispatcher->addListener($eventName, $assertWorkflowContext);
585+
}
586+
587+
$workflow->apply($subject, 't1');
588+
}
589+
536590
public function testMarkingStateOnApplyWithEventDispatcher()
537591
{
538592
$definition = new Definition(range('a', 'f'), [new Transition('t', range('a', 'c'), range('d', 'f'))]);

src/Symfony/Component/Workflow/Workflow.php

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@
3030
* @author Fabien Potencier <fabien@symfony.com>
3131
* @author Grégoire Pineau <lyrixx@lyrixx.info>
3232
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
33+
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
3334
*/
3435
class Workflow implements WorkflowInterface
3536
{
3637
public const DISABLE_ANNOUNCE_EVENT = 'workflow_disable_announce_event';
38+
public const DEFAULT_INITIAL_CONTEXT = ['initial' => true];
3739

3840
private $definition;
3941
private $markingStore;
@@ -51,7 +53,7 @@ public function __construct(Definition $definition, MarkingStoreInterface $marki
5153
/**
5254
* {@inheritdoc}
5355
*/
54-
public function getMarking(object $subject)
56+
public function getMarking(object $subject, array $context = [])
5557
{
5658
$marking = $this->markingStore->getMarking($subject);
5759

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

74-
$this->entered($subject, null, $marking);
76+
if (!$context) {
77+
$context = self::DEFAULT_INITIAL_CONTEXT;
78+
}
79+
80+
$this->entered($subject, null, $marking, $context);
7581
}
7682

7783
// check that the subject has a known place
@@ -154,7 +160,7 @@ public function buildTransitionBlockerList(object $subject, string $transitionNa
154160
*/
155161
public function apply(object $subject, string $transitionName, array $context = [])
156162
{
157-
$marking = $this->getMarking($subject);
163+
$marking = $this->getMarking($subject, $context);
158164

159165
$transitionExist = false;
160166
$approvedTransitions = [];
@@ -167,7 +173,7 @@ public function apply(object $subject, string $transitionName, array $context =
167173

168174
$transitionExist = true;
169175

170-
$tmpTransitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
176+
$tmpTransitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition, $context);
171177

172178
if ($tmpTransitionBlockerList->isEmpty()) {
173179
$approvedTransitions[] = $transition;
@@ -197,20 +203,20 @@ public function apply(object $subject, string $transitionName, array $context =
197203
}
198204

199205
foreach ($approvedTransitions as $transition) {
200-
$this->leave($subject, $transition, $marking);
206+
$this->leave($subject, $transition, $marking, $context);
201207

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

204-
$this->enter($subject, $transition, $marking);
210+
$this->enter($subject, $transition, $marking, $context);
205211

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

208-
$this->entered($subject, $transition, $marking);
214+
$this->entered($subject, $transition, $marking, $context);
209215

210-
$this->completed($subject, $transition, $marking);
216+
$this->completed($subject, $transition, $marking, $context);
211217

212218
if (!($context[self::DISABLE_ANNOUNCE_EVENT] ?? false)) {
213-
$this->announce($subject, $transition, $marking);
219+
$this->announce($subject, $transition, $marking, $context);
214220
}
215221
}
216222

@@ -220,13 +226,13 @@ public function apply(object $subject, string $transitionName, array $context =
220226
/**
221227
* {@inheritdoc}
222228
*/
223-
public function getEnabledTransitions(object $subject)
229+
public function getEnabledTransitions(object $subject, array $context = [])
224230
{
225231
$enabledTransitions = [];
226232
$marking = $this->getMarking($subject);
227233

228234
foreach ($this->definition->getTransitions() as $transition) {
229-
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition);
235+
$transitionBlockerList = $this->buildTransitionBlockerListForTransition($subject, $marking, $transition, $context);
230236
if ($transitionBlockerList->isEmpty()) {
231237
$enabledTransitions[] = $transition;
232238
}
@@ -286,7 +292,7 @@ public function getMetadataStore(): MetadataStoreInterface
286292
return $this->definition->getMetadataStore();
287293
}
288294

289-
private function buildTransitionBlockerListForTransition(object $subject, Marking $marking, Transition $transition): TransitionBlockerList
295+
private function buildTransitionBlockerListForTransition(object $subject, Marking $marking, Transition $transition, array $context = []): TransitionBlockerList
290296
{
291297
foreach ($transition->getFroms() as $place) {
292298
if (!$marking->has($place)) {
@@ -300,7 +306,7 @@ private function buildTransitionBlockerListForTransition(object $subject, Markin
300306
return new TransitionBlockerList();
301307
}
302308

303-
$event = $this->guardTransition($subject, $marking, $transition);
309+
$event = $this->guardTransition($subject, $marking, $transition, $context);
304310

305311
if ($event->isBlocked()) {
306312
return $event->getTransitionBlockerList();
@@ -309,7 +315,7 @@ private function buildTransitionBlockerListForTransition(object $subject, Markin
309315
return new TransitionBlockerList();
310316
}
311317

312-
private function guardTransition(object $subject, Marking $marking, Transition $transition): ?GuardEvent
318+
private function guardTransition(object $subject, Marking $marking, Transition $transition, array $context = []): ?GuardEvent
313319
{
314320
if (null === $this->dispatcher) {
315321
return null;
@@ -324,12 +330,12 @@ private function guardTransition(object $subject, Marking $marking, Transition $
324330
return $event;
325331
}
326332

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

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

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

353-
$event = new TransitionEvent($subject, $marking, $transition, $this);
354-
$event->setContext($context);
359+
$event = new TransitionEvent($subject, $marking, $transition, $this, $context);
355360

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

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

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

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

383-
private function entered(object $subject, ?Transition $transition, Marking $marking): void
388+
private function entered(object $subject, ?Transition $transition, Marking $marking, array $context = []): void
384389
{
385390
if (null === $this->dispatcher) {
386391
return;
387392
}
388393

389-
$event = new EnteredEvent($subject, $marking, $transition, $this);
394+
$event = new EnteredEvent($subject, $marking, $transition, $this, $context);
390395

391396
$this->dispatcher->dispatch($event, WorkflowEvents::ENTERED);
392397
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered', $this->name));
@@ -395,34 +400,38 @@ private function entered(object $subject, ?Transition $transition, Marking $mark
395400
foreach ($transition->getTos() as $place) {
396401
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered.%s', $this->name, $place));
397402
}
403+
} elseif (!empty($this->definition->getInitialPlaces())) {
404+
foreach ($this->definition->getInitialPlaces() as $place) {
405+
$this->dispatcher->dispatch($event, sprintf('workflow.%s.entered.%s', $this->name, $place));
406+
}
398407
}
399408
}
400409

401-
private function completed(object $subject, Transition $transition, Marking $marking): void
410+
private function completed(object $subject, Transition $transition, Marking $marking, array $context): void
402411
{
403412
if (null === $this->dispatcher) {
404413
return;
405414
}
406415

407-
$event = new CompletedEvent($subject, $marking, $transition, $this);
416+
$event = new CompletedEvent($subject, $marking, $transition, $this, $context);
408417

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

414-
private function announce(object $subject, Transition $initialTransition, Marking $marking): void
423+
private function announce(object $subject, Transition $initialTransition, Marking $marking, array $context): void
415424
{
416425
if (null === $this->dispatcher) {
417426
return;
418427
}
419428

420-
$event = new AnnounceEvent($subject, $marking, $initialTransition, $this);
429+
$event = new AnnounceEvent($subject, $marking, $initialTransition, $this, $context);
421430

422431
$this->dispatcher->dispatch($event, WorkflowEvents::ANNOUNCE);
423432
$this->dispatcher->dispatch($event, sprintf('workflow.%s.announce', $this->name));
424433

425-
foreach ($this->getEnabledTransitions($subject) as $transition) {
434+
foreach ($this->getEnabledTransitions($subject, $context) as $transition) {
426435
$this->dispatcher->dispatch($event, sprintf('workflow.%s.announce.%s', $this->name, $transition->getName()));
427436
}
428437
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy