Skip to content

Commit 458d12e

Browse files
committed
[Workflow] Choose which Workflow events should be dispatched (fix previous commit)
1 parent 5b5a3e7 commit 458d12e

20 files changed

+182
-279
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

+36-12
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Symfony\Component\Translation\Translator;
3535
use Symfony\Component\Validator\Validation;
3636
use Symfony\Component\WebLink\HttpHeaderSerializer;
37+
use Symfony\Component\Workflow\WorkflowEvents;
3738

3839
/**
3940
* FrameworkExtension configuration structure.
@@ -382,21 +383,32 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
382383
->defaultValue([])
383384
->prototype('scalar')->end()
384385
->end()
385-
->arrayNode('dispatched_events')
386-
->beforeNormalization()
387-
->ifString()
388-
->then(function ($v) {
389-
return [$v];
386+
->variableNode('dispatched_events')
387+
->defaultValue(null)
388+
->validate()
389+
->ifTrue(function ($v) {
390+
if (null === $v) {
391+
return false;
392+
}
393+
if (!\is_array($v)) {
394+
return true;
395+
}
396+
397+
foreach ($v as $value) {
398+
if (!\is_string($value)) {
399+
return true;
400+
}
401+
if (class_exists(WorkflowEvents::class) && !\in_array($value, WorkflowEvents::ALIASES)) {
402+
return true;
403+
}
404+
}
405+
406+
return false;
390407
})
408+
->thenInvalid('The value must be "null" or an array of workflow events (like ["workflow.enter"]).')
391409
->end()
392-
// We have to specify a default here as when this config option
393-
// isn't set the default behaviour of `arrayNode()` is to return an empty
394-
// array which conflicts with our Definition, and we cannot set a default
395-
// of `null` for arrayNode()'s
396-
->defaultValue(['all'])
397-
->prototype('scalar')->end()
398410
->info('Select which Transition events should be dispatched for this Workflow')
399-
->example(['leave', 'completed'])
411+
->example(['workflow.enter', 'workflow.transition'])
400412
->end()
401413
->arrayNode('places')
402414
->beforeNormalization()
@@ -526,6 +538,18 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
526538
})
527539
->thenInvalid('"supports" or "support_strategy" should be configured.')
528540
->end()
541+
->beforeNormalization()
542+
->always()
543+
->then(function ($values) {
544+
// Special case to deal with XML when the user wants an empty array
545+
if (\array_key_exists('dispatched_event', $values) && null === $values['dispatched_event']) {
546+
$values['dispatched_events'] = [];
547+
unset($values['dispatched_event']);
548+
}
549+
550+
return $values;
551+
})
552+
->end()
529553
->end()
530554
->end()
531555
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

+1-12
Original file line numberDiff line numberDiff line change
@@ -741,25 +741,13 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
741741
$places = array_column($workflow['places'], 'name');
742742
$initialMarking = $workflow['initial_marking'] ?? [];
743743

744-
// Record which events should be dispatched
745-
if ($workflow['dispatched_events'] === ['all']) {
746-
$dispatchedEvents = null;
747-
} elseif ($workflow['dispatched_events'] === ['none']) {
748-
$dispatchedEvents = [];
749-
} else {
750-
$dispatchedEvents = array_map(function (string $event) {
751-
return 'workflow.'.$event;
752-
}, $workflow['dispatched_events']);
753-
}
754-
755744
// Create a Definition
756745
$definitionDefinition = new Definition(Workflow\Definition::class);
757746
$definitionDefinition->setPublic(false);
758747
$definitionDefinition->addArgument($places);
759748
$definitionDefinition->addArgument($transitions);
760749
$definitionDefinition->addArgument($initialMarking);
761750
$definitionDefinition->addArgument($metadataStoreDefinition);
762-
$definitionDefinition->addArgument($dispatchedEvents);
763751
$definitionDefinition->addTag('workflow.definition', [
764752
'name' => $name,
765753
'type' => $type,
@@ -783,6 +771,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
783771
$workflowDefinition->replaceArgument(1, $markingStoreDefinition);
784772
}
785773
$workflowDefinition->replaceArgument(3, $name);
774+
$workflowDefinition->replaceArgument(4, $workflow['dispatched_events']);
786775

787776
// Store to container
788777
$container->setDefinition($workflowId, $workflowDefinition);

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

+8-8
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,14 @@
348348

349349
<xsd:simpleType name="dispatched_event">
350350
<xsd:restriction base="xsd:string">
351-
<xsd:enumeration value="all" />
352-
<xsd:enumeration value="none" />
353-
<xsd:enumeration value="leave" />
354-
<xsd:enumeration value="transition" />
355-
<xsd:enumeration value="enter" />
356-
<xsd:enumeration value="entered" />
357-
<xsd:enumeration value="completed" />
358-
<xsd:enumeration value="announce" />
351+
<xsd:enumeration value="" />
352+
<xsd:enumeration value="workflow.leave" />
353+
<xsd:enumeration value="workflow.leave" />
354+
<xsd:enumeration value="workflow.transition" />
355+
<xsd:enumeration value="workflow.enter" />
356+
<xsd:enumeration value="workflow.entered" />
357+
<xsd:enumeration value="workflow.completed" />
358+
<xsd:enumeration value="workflow.announce" />
359359
</xsd:restriction>
360360
</xsd:simpleType>
361361

src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.php

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
abstract_arg('marking store'),
2626
service('event_dispatcher')->ignoreOnInvalid(),
2727
abstract_arg('workflow name'),
28+
abstract_arg('dispatched events'),
2829
])
2930
->abstract()
3031
->public()
@@ -34,6 +35,7 @@
3435
abstract_arg('marking store'),
3536
service('event_dispatcher')->ignoreOnInvalid(),
3637
abstract_arg('workflow name'),
38+
abstract_arg('dispatched events'),
3739
])
3840
->abstract()
3941
->public()

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_all_dispatched_events.php

-41
This file was deleted.

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_specified_dispatched_events.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
FrameworkExtensionTest::class,
1515
],
1616
'dispatched_events' => [
17-
'leave',
18-
'completed'
17+
'workflow.leave',
18+
'workflow.completed',
1919
],
2020
'places' => [
2121
'one',

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_all_dispatched_events.xml

-27
This file was deleted.

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_no_dispatched_events.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<framework:initial-marking>one</framework:initial-marking>
1212
<framework:marking-store type="method" property="state" />
1313
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
14-
<framework:dispatched-event>none</framework:dispatched-event>
14+
<framework:dispatched-event></framework:dispatched-event>
1515
<framework:place name="one" />
1616
<framework:place name="two" />
1717
<framework:place name="three" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_specified_dispatched_events.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<framework:initial-marking>one</framework:initial-marking>
1212
<framework:marking-store type="method" property="state" />
1313
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
14-
<framework:dispatched-event>leave</framework:dispatched-event>
15-
<framework:dispatched-event>completed</framework:dispatched-event>
14+
<framework:dispatched-event>workflow.leave</framework:dispatched-event>
15+
<framework:dispatched-event>workflow.completed</framework:dispatched-event>
1616
<framework:place name="one" />
1717
<framework:place name="two" />
1818
<framework:place name="three" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_all_dispatched_events.yml

-21
This file was deleted.

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_specified_dispatched_events.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ framework:
33
my_workflow:
44
type: state_machine
55
initial_marking: one
6-
dispatched_events: ['leave', 'completed']
6+
dispatched_events: ['workflow.leave', 'workflow.completed']
77
marking_store:
88
type: method
99
property: state

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

+4-14
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ public function testWorkflows()
217217

218218
$this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service');
219219
$this->assertSame('workflow.abstract', $container->getDefinition('workflow.article')->getParent());
220+
$this->assertNull($container->getDefinition('workflow.article')->getArgument('index_4'), 'Workflows has eventToBeDispatched=null');
221+
220222
$this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service');
221223

222224
$workflowDefinition = $container->getDefinition('workflow.article.definition');
@@ -424,22 +426,11 @@ public function testWorkflowsNamedExplicitlyEnabled()
424426
$this->assertTrue($container->hasDefinition('workflow.workflows.definition'));
425427
}
426428

427-
public function testWorkflowsWithAllDispatchedEvents()
428-
{
429-
$container = $this->createContainerFromFile('workflow_with_all_dispatched_events');
430-
431-
$workflowDefinition = $container->getDefinition('state_machine.my_workflow.definition');
432-
$dispatchedEvents = $workflowDefinition->getArgument(4);
433-
434-
$this->assertNull($dispatchedEvents);
435-
}
436-
437429
public function testWorkflowsWithNoDispatchedEvents()
438430
{
439431
$container = $this->createContainerFromFile('workflow_with_no_dispatched_events');
440432

441-
$workflowDefinition = $container->getDefinition('state_machine.my_workflow.definition');
442-
$dispatchedEvents = $workflowDefinition->getArgument(4);
433+
$dispatchedEvents = $container->getDefinition('state_machine.my_workflow')->getArgument('index_4');
443434

444435
$this->assertSame([], $dispatchedEvents);
445436
}
@@ -448,8 +439,7 @@ public function testWorkflowsWithSpecifiedDispatchedEvents()
448439
{
449440
$container = $this->createContainerFromFile('workflow_with_specified_dispatched_events');
450441

451-
$workflowDefinition = $container->getDefinition('state_machine.my_workflow.definition');
452-
$dispatchedEvents = $workflowDefinition->getArgument(4);
442+
$dispatchedEvents = $container->getDefinition('state_machine.my_workflow')->getArgument('index_4');
453443

454444
$this->assertSame([WorkflowEvents::LEAVE, WorkflowEvents::COMPLETED], $dispatchedEvents);
455445
}

src/Symfony/Component/Workflow/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ CHANGELOG
88
* Added context to the event dispatched
99
* Dispatch an event when the subject enters in the workflow for the very first time
1010
* Added a default context to the previous event
11+
* Added support for specifying which events should be dispatched when calling `workflow->apply()`
1112

1213
5.1.0
1314
-----
1415

1516
* Added context to `TransitionException` and its child classes whenever they are thrown in `Workflow::apply()`
1617
* Added `Registry::has()` to check if a workflow exists
17-
* Added support for specifying which events should be dispatched when calling `workflow->apply()`
18+
* Added support for `$context[Workflow::DISABLE_ANNOUNCE_EVENT] = true` when calling `workflow->apply()` to not fire the announce event
1819

1920
5.0.0
2021
-----

src/Symfony/Component/Workflow/Definition.php

+1-18
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,6 @@
2222
*/
2323
final class Definition
2424
{
25-
/**
26-
* When `null` fire all events (the default behaviour).
27-
* Setting this to an empty array `[]` means no events are dispatched except the Guard Event.
28-
* Passing an array with WorkflowEvents will allow only those events to be dispatched plus
29-
* the Guard Event.
30-
*
31-
* @var array|string[]
32-
*/
33-
private $dispatchedEvents;
34-
3525
private $places = [];
3626
private $transitions = [];
3727
private $initialPlaces = [];
@@ -42,7 +32,7 @@ final class Definition
4232
* @param Transition[] $transitions
4333
* @param string|string[]|null $initialPlaces
4434
*/
45-
public function __construct(array $places, array $transitions, $initialPlaces = null, MetadataStoreInterface $metadataStore = null, array $dispatchedEvents = null)
35+
public function __construct(array $places, array $transitions, $initialPlaces = null, MetadataStoreInterface $metadataStore = null)
4636
{
4737
foreach ($places as $place) {
4838
$this->addPlace($place);
@@ -55,8 +45,6 @@ public function __construct(array $places, array $transitions, $initialPlaces =
5545
$this->setInitialPlaces($initialPlaces);
5646

5747
$this->metadataStore = $metadataStore ?: new InMemoryMetadataStore();
58-
59-
$this->dispatchedEvents = $dispatchedEvents ?? WorkflowEvents::getDefaultDispatchedEvents();
6048
}
6149

6250
/**
@@ -88,11 +76,6 @@ public function getMetadataStore(): MetadataStoreInterface
8876
return $this->metadataStore;
8977
}
9078

91-
public function getDispatchedEvents(): array
92-
{
93-
return $this->dispatchedEvents;
94-
}
95-
9679
private function setInitialPlaces($places = null)
9780
{
9881
if (!$places) {

0 commit comments

Comments
 (0)