diff --git a/UPGRADE-4.3.md b/UPGRADE-4.3.md index 52165c10b539e..a45814f09e673 100644 --- a/UPGRADE-4.3.md +++ b/UPGRADE-4.3.md @@ -127,6 +127,27 @@ Security } ``` +Workflow +-------- + + * `initial_place` is deprecated in favour of `initial_places`. + + Before: + ```yaml + framework: + workflows: + article: + initial_place: draft + ``` + + After: + ```yaml + framework: + workflows: + article: + initial_places: [draft] + ``` + Yaml ---- diff --git a/UPGRADE-5.0.md b/UPGRADE-5.0.md index 60b16b1c58df8..16a034a85dc05 100644 --- a/UPGRADE-5.0.md +++ b/UPGRADE-5.0.md @@ -368,6 +368,7 @@ Workflow * `SupportStrategyInterface` has been removed, use `WorkflowSupportStrategyInterface` instead. * `ClassInstanceSupportStrategy` has been removed, use `InstanceOfSupportStrategy` instead. * `MarkingStoreInterface::setMarking()` has a third argument: `array $context = []`. + * Removed support of `initial_place`. Use `initial_places` instead. Yaml ---- diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 1e52ce9322486..04f2bdbe16c26 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -231,7 +231,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) $workflows = []; } - if (1 === \count($workflows) && isset($workflows['workflows']) && array_keys($workflows['workflows']) !== range(0, \count($workflows) - 1) && !empty(array_diff(array_keys($workflows['workflows']), ['audit_trail', 'type', 'marking_store', 'supports', 'support_strategy', 'initial_place', 'places', 'transitions']))) { + if (1 === \count($workflows) && isset($workflows['workflows']) && array_keys($workflows['workflows']) !== range(0, \count($workflows) - 1) && !empty(array_diff(array_keys($workflows['workflows']), ['audit_trail', 'type', 'marking_store', 'supports', 'support_strategy', 'initial_places', 'places', 'transitions']))) { $workflows = $workflows['workflows']; } @@ -258,6 +258,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) ->prototype('array') ->fixXmlConfig('support') ->fixXmlConfig('place') + ->fixXmlConfig('initial_place') ->fixXmlConfig('transition') ->children() ->arrayNode('audit_trail') @@ -312,8 +313,17 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) ->cannotBeEmpty() ->end() ->scalarNode('initial_place') + ->setDeprecated('The "%path%.%node%" configuration key has been deprecated in Symfony 4.3, use the "initial_places" configuration key instead.') ->defaultNull() ->end() + ->arrayNode('initial_places') + ->beforeNormalization() + ->ifTrue(function ($v) { return !\is_array($v); }) + ->then(function ($v) { return [$v]; }) + ->end() + ->defaultValue([]) + ->prototype('scalar')->end() + ->end() ->arrayNode('places') ->beforeNormalization() ->always() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 870c499aafbd6..f2f2ab00fcf7e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -615,14 +615,14 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ // Create places $places = array_column($workflow['places'], 'name'); - $initialPlace = $workflow['initial_place'] ?? null; + $initialPlaces = $workflow['initial_places'] ?? $workflow['initial_place'] ?? []; // Create a Definition $definitionDefinition = new Definition(Workflow\Definition::class); $definitionDefinition->setPublic(false); $definitionDefinition->addArgument($places); $definitionDefinition->addArgument($transitions); - $definitionDefinition->addArgument($initialPlace); + $definitionDefinition->addArgument($initialPlaces); $definitionDefinition->addArgument($metadataStoreDefinition); // Create MarkingStore @@ -670,7 +670,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ ->addTransitions(array_map(function (Reference $ref) use ($container): Workflow\Transition { return $container->get((string) $ref); }, $transitions)) - ->setInitialPlace($initialPlace) + ->setInitialPlace($initialPlaces) ->build() ; $validator->validate($realDefinition, $name); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd index 98baeb978b440..254c0085e8d15 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd @@ -270,6 +270,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow-legacy.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow-legacy.php new file mode 100644 index 0000000000000..e7d8919315da9 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow-legacy.php @@ -0,0 +1,25 @@ +loadFromExtension('framework', [ + 'workflows' => [ + 'legacy' => [ + 'type' => 'workflow', + 'supports' => [ + stdClass::class, + ], + 'initial_place' => 'draft', + 'places' => [ + 'draft', + 'published', + ], + 'transitions' => [ + 'publish' => [ + 'from' => 'draft', + 'to' => 'published', + ], + ], + ], + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php index 19de6363e62c0..03b6a0b79b0cb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_guard_expression.php @@ -12,7 +12,7 @@ 'supports' => [ FrameworkExtensionTest::class, ], - 'initial_place' => 'draft', + 'initial_places' => ['draft'], 'places' => [ 'draft', 'wait_for_journalist', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_multiple_transitions_with_same_name.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_multiple_transitions_with_same_name.php index c1a525db03cdc..613a38c6c0ebe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_multiple_transitions_with_same_name.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflow_with_multiple_transitions_with_same_name.php @@ -12,7 +12,7 @@ 'supports' => [ FrameworkExtensionTest::class, ], - 'initial_place' => 'draft', + 'initial_places' => ['draft'], 'places' => [ 'draft', 'wait_for_journalist', diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php index 9d066a21ba361..17a0e1fa4a7eb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php @@ -12,7 +12,7 @@ 'supports' => [ FrameworkExtensionTest::class, ], - 'initial_place' => 'draft', + 'initial_places' => ['draft'], 'places' => [ 'draft', 'wait_for_journalist', @@ -47,7 +47,7 @@ 'supports' => [ FrameworkExtensionTest::class, ], - 'initial_place' => 'start', + 'initial_places' => ['start'], 'metadata' => [ 'title' => 'workflow title', ], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled.php index 165d0daa11ae5..1c8190bd09d5c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled.php @@ -6,7 +6,7 @@ 'foo' => [ 'type' => 'workflow', 'supports' => ['Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest'], - 'initial_place' => 'bar', + 'initial_places' => ['bar'], 'places' => ['bar', 'baz'], 'transitions' => [ 'bar_baz' => [ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled_named_workflows.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled_named_workflows.php index 17055ec16f7df..6faae44f45ced 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled_named_workflows.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_explicitly_enabled_named_workflows.php @@ -6,7 +6,7 @@ 'workflows' => [ 'type' => 'workflow', 'supports' => ['Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest'], - 'initial_place' => 'bar', + 'initial_places' => ['bar'], 'places' => ['bar', 'baz'], 'transitions' => [ 'bar_baz' => [ diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow-legacy.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow-legacy.xml new file mode 100644 index 0000000000000..d1339d5f65cc1 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow-legacy.xml @@ -0,0 +1,20 @@ + + + + + + + stdClass + + + + draft + published + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml index fa5a96ab11881..32c33db5b812a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_guard_expression.xml @@ -7,7 +7,8 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + draft a a diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_multiple_transitions_with_same_name.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_multiple_transitions_with_same_name.xml index 51413201298de..ffc316c99e70a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_multiple_transitions_with_same_name.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflow_with_multiple_transitions_with_same_name.xml @@ -7,7 +7,8 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + draft a a diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml index 862ecae17cde5..da5cd4c758200 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml @@ -7,7 +7,8 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + draft a a diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled.xml index 08855f7569aa2..b564c6ff7644a 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled.xml @@ -6,7 +6,8 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + bar Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest bar baz diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled_named_workflows.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled_named_workflows.xml index 8415c9c280668..b218480fe68a7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled_named_workflows.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_explicitly_enabled_named_workflows.xml @@ -6,7 +6,8 @@ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + bar Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest bar baz diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow-legacy.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow-legacy.yml new file mode 100644 index 0000000000000..7ff70074d400c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow-legacy.yml @@ -0,0 +1,14 @@ +framework: + workflows: + legacy: + type: workflow + initial_place: draft + supports: + - stdClass + places: + - draft + - published + transitions: + publish: + from: draft + to: published diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml index 458cb4ae1ee77..433771601c3d7 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_guard_expression.yml @@ -6,7 +6,7 @@ framework: type: multiple_state supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: draft + initial_places: [draft] places: - draft - wait_for_journalist diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_multiple_transitions_with_same_name.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_multiple_transitions_with_same_name.yml index 36d00de46501c..fee71c2645693 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_multiple_transitions_with_same_name.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflow_with_multiple_transitions_with_same_name.yml @@ -6,7 +6,7 @@ framework: type: multiple_state supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: draft + initial_places: [draft] places: - draft - wait_for_journalist diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml index c82c92791c864..894d5dcde207c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml @@ -6,7 +6,7 @@ framework: type: multiple_state supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: draft + initial_places: [draft] places: # simple format - draft @@ -33,7 +33,7 @@ framework: type: single_state supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: start + initial_places: [start] metadata: title: workflow title places: diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled.yml index 21abbf03055a4..d1545374705d3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled.yml @@ -6,7 +6,7 @@ framework: type: workflow supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: bar + initial_places: [bar] places: - bar - baz diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled_named_workflows.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled_named_workflows.yml index a6c03de95d1b3..bb468254aca0b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled_named_workflows.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_explicitly_enabled_named_workflows.yml @@ -5,7 +5,7 @@ framework: type: workflow supports: - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest - initial_place: bar + initial_places: [bar] places: - bar - baz diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php index 5c0352b2658da..dd626d62c40bf 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php @@ -217,7 +217,7 @@ public function testWorkflows() 'Places are passed to the workflow definition' ); $this->assertCount(4, $workflowDefinition->getArgument(1)); - $this->assertSame('draft', $workflowDefinition->getArgument(2)); + $this->assertSame(['draft'], $workflowDefinition->getArgument(2)); $this->assertTrue($container->hasDefinition('state_machine.pull_request'), 'State machine is registered as a service'); $this->assertSame('state_machine.abstract', $container->getDefinition('state_machine.pull_request')->getParent()); @@ -238,7 +238,7 @@ public function testWorkflows() 'Places are passed to the state machine definition' ); $this->assertCount(9, $stateMachineDefinition->getArgument(1)); - $this->assertSame('start', $stateMachineDefinition->getArgument(2)); + $this->assertSame(['start'], $stateMachineDefinition->getArgument(2)); $metadataStoreDefinition = $stateMachineDefinition->getArgument(3); $this->assertInstanceOf(Definition::class, $metadataStoreDefinition); @@ -271,6 +271,28 @@ public function testWorkflows() $this->assertGreaterThan(0, \count($registryDefinition->getMethodCalls())); } + public function testWorkflowLegacy() + { + $container = $this->createContainerFromFile('workflow-legacy'); + + $this->assertTrue($container->hasDefinition('workflow.legacy'), 'Workflow is registered as a service'); + $this->assertSame('workflow.abstract', $container->getDefinition('workflow.legacy')->getParent()); + $this->assertTrue($container->hasDefinition('workflow.legacy.definition'), 'Workflow definition is registered as a service'); + + $workflowDefinition = $container->getDefinition('workflow.legacy.definition'); + + $this->assertSame(['draft'], $workflowDefinition->getArgument(2)); + + $this->assertSame( + [ + 'draft', + 'published', + ], + $workflowDefinition->getArgument(0), + 'Places are passed to the workflow definition' + ); + } + /** * @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException * @expectedExceptionMessage A transition from a place/state must have an unique name. Multiple transitions named "go" from place/state "first" where found on StateMachine "my_workflow". diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 8279d4c7a3e7f..86ad2fe1e6e6e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -54,7 +54,7 @@ "symfony/twig-bundle": "~2.8|~3.2|~4.0", "symfony/validator": "^4.1", "symfony/var-dumper": "~3.4|~4.0", - "symfony/workflow": "^4.1", + "symfony/workflow": "^4.3", "symfony/yaml": "~3.4|~4.0", "symfony/property-info": "~3.4|~4.0", "symfony/lock": "~3.4|~4.0", @@ -79,7 +79,7 @@ "symfony/translation": "<4.3", "symfony/twig-bridge": "<4.1.1", "symfony/validator": "<4.1", - "symfony/workflow": "<4.1" + "symfony/workflow": "<4.3" }, "suggest": { "ext-apcu": "For best performance of the system caches", diff --git a/src/Symfony/Component/Workflow/CHANGELOG.md b/src/Symfony/Component/Workflow/CHANGELOG.md index a37db3857c474..0801deccc711b 100644 --- a/src/Symfony/Component/Workflow/CHANGELOG.md +++ b/src/Symfony/Component/Workflow/CHANGELOG.md @@ -26,6 +26,7 @@ CHANGELOG * Dispatch `EnteredEvent` on `workflow.entered` * Dispatch `CompletedEvent` on `workflow.completed` * Dispatch `AnnounceEvent` on `workflow.announce` + * Added support for many `initialPlaces` 4.1.0 ----- diff --git a/src/Symfony/Component/Workflow/Definition.php b/src/Symfony/Component/Workflow/Definition.php index f614d46a30551..dd0c0626cf785 100644 --- a/src/Symfony/Component/Workflow/Definition.php +++ b/src/Symfony/Component/Workflow/Definition.php @@ -24,14 +24,15 @@ final class Definition { private $places = []; private $transitions = []; - private $initialPlace; + private $initialPlaces = []; private $metadataStore; /** - * @param string[] $places - * @param Transition[] $transitions + * @param string[] $places + * @param Transition[] $transitions + * @param string|string[]|null $initialPlaces */ - public function __construct(array $places, array $transitions, string $initialPlace = null, MetadataStoreInterface $metadataStore = null) + public function __construct(array $places, array $transitions, $initialPlaces = null, MetadataStoreInterface $metadataStore = null) { foreach ($places as $place) { $this->addPlace($place); @@ -41,17 +42,33 @@ public function __construct(array $places, array $transitions, string $initialPl $this->addTransition($transition); } - $this->setInitialPlace($initialPlace); + $this->setInitialPlaces($initialPlaces); $this->metadataStore = $metadataStore ?: new InMemoryMetadataStore(); } /** + * @deprecated since Symfony 4.3. Use the getInitialPlaces() instead. + * * @return string|null */ public function getInitialPlace() { - return $this->initialPlace; + @trigger_error(sprintf('Calling %s::getInitialPlace() is deprecated. Call %s::getInitialPlaces() instead.', __CLASS__, __CLASS__)); + + if (!$this->initialPlaces) { + return null; + } + + return reset($this->initialPlaces); + } + + /** + * @return string[] + */ + public function getInitialPlaces(): array + { + return $this->initialPlaces; } /** @@ -75,23 +92,27 @@ public function getMetadataStore(): MetadataStoreInterface return $this->metadataStore; } - private function setInitialPlace(string $place = null) + private function setInitialPlaces($places = null) { - if (null === $place) { + if (null === $places) { return; } - if (!isset($this->places[$place])) { - throw new LogicException(sprintf('Place "%s" cannot be the initial place as it does not exist.', $place)); + $places = (array) $places; + + foreach ($places as $place) { + if (!isset($this->places[$place])) { + throw new LogicException(sprintf('Place "%s" cannot be the initial place as it does not exist.', $place)); + } } - $this->initialPlace = $place; + $this->initialPlaces = $places; } private function addPlace(string $place) { if (!\count($this->places)) { - $this->initialPlace = $place; + $this->initialPlaces = [$place]; } $this->places[$place] = $place; diff --git a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php index 6822eab86bdac..55cd832bbd7b2 100644 --- a/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php +++ b/src/Symfony/Component/Workflow/Dumper/GraphvizDumper.php @@ -69,7 +69,7 @@ protected function findPlaces(Definition $definition, Marking $marking = null) foreach ($definition->getPlaces() as $place) { $attributes = []; - if ($place === $definition->getInitialPlace()) { + if (\in_array($place, $definition->getInitialPlaces(), true)) { $attributes['style'] = 'filled'; } if ($marking && $marking->has($place)) { diff --git a/src/Symfony/Component/Workflow/Dumper/PlantUmlDumper.php b/src/Symfony/Component/Workflow/Dumper/PlantUmlDumper.php index 50d9046f26550..977ef69cdd2fa 100644 --- a/src/Symfony/Component/Workflow/Dumper/PlantUmlDumper.php +++ b/src/Symfony/Component/Workflow/Dumper/PlantUmlDumper.php @@ -199,7 +199,7 @@ private function getState(string $place, Definition $definition, Marking $markin $placeEscaped = $this->escape($place); $output = "state $placeEscaped". - ($definition->getInitialPlace() === $place ? ' '.self::INITIAL : ''). + (\in_array($place, $definition->getInitialPlaces(), true) ? ' '.self::INITIAL : ''). ($marking && $marking->has($place) ? ' '.self::MARKED : ''); $backgroundColor = $workflowMetadata->getMetadata('bg_color', $place); diff --git a/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php b/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php index fdc4703a1b426..62351d7d9218a 100644 --- a/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php +++ b/src/Symfony/Component/Workflow/Tests/DefinitionBuilderTest.php @@ -15,7 +15,7 @@ public function testSetInitialPlace() $builder->setInitialPlace('b'); $definition = $builder->build(); - $this->assertEquals('b', $definition->getInitialPlace()); + $this->assertEquals(['b'], $definition->getInitialPlaces()); } public function testAddTransition() diff --git a/src/Symfony/Component/Workflow/Tests/DefinitionTest.php b/src/Symfony/Component/Workflow/Tests/DefinitionTest.php index e10aad81cf143..8bbac4a8c784d 100644 --- a/src/Symfony/Component/Workflow/Tests/DefinitionTest.php +++ b/src/Symfony/Component/Workflow/Tests/DefinitionTest.php @@ -15,7 +15,7 @@ public function testAddPlaces() $this->assertCount(5, $definition->getPlaces()); - $this->assertEquals('a', $definition->getInitialPlace()); + $this->assertEquals(['a'], $definition->getInitialPlaces()); } public function testSetInitialPlace() @@ -23,7 +23,15 @@ public function testSetInitialPlace() $places = range('a', 'e'); $definition = new Definition($places, [], $places[3]); - $this->assertEquals($places[3], $definition->getInitialPlace()); + $this->assertEquals([$places[3]], $definition->getInitialPlaces()); + } + + public function testSetInitialPlaces() + { + $places = range('a', 'e'); + $definition = new Definition($places, [], ['a', 'e']); + + $this->assertEquals(['a', 'e'], $definition->getInitialPlaces()); } /** diff --git a/src/Symfony/Component/Workflow/Tests/Validator/StateMachineValidatorTest.php b/src/Symfony/Component/Workflow/Tests/Validator/StateMachineValidatorTest.php index 4e344560557d4..35da1f2ec8061 100644 --- a/src/Symfony/Component/Workflow/Tests/Validator/StateMachineValidatorTest.php +++ b/src/Symfony/Component/Workflow/Tests/Validator/StateMachineValidatorTest.php @@ -109,4 +109,32 @@ public function testValid() // | t2 | --> | c | // +----+ +----+ } + + /** + * @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException + * @expectedExceptionMessage The state machine "foo" can not store many places. But the definition has 2 initial places. Only one is supported. + */ + public function testWithTooManyInitialPlaces() + { + $places = range('a', 'c'); + $transitions = []; + $definition = new Definition($places, $transitions, ['a', 'b']); + + (new StateMachineValidator())->validate($definition, 'foo'); + + // the test ensures that the validation does not fail (i.e. it does not throw any exceptions) + $this->addToAssertionCount(1); + + // The graph looks like: + // + // +----+ +----+ +---+ + // | a | --> | t1 | --> | b | + // +----+ +----+ +---+ + // | + // | + // v + // +----+ +----+ + // | t2 | --> | c | + // +----+ +----+ + } } diff --git a/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php b/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php index 4a5c5a57dd85f..5aa020fea45ae 100644 --- a/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php +++ b/src/Symfony/Component/Workflow/Tests/Validator/WorkflowValidatorTest.php @@ -51,6 +51,20 @@ public function testWorkflowWithInvalidNames() (new WorkflowValidator())->validate($definition, 'foo'); } + /** + * @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException + * @expectedExceptionMessage The marking store of workflow "foo" can not store many places. But the definition has 2 initial places. Only one is supported. + */ + public function testWithTooManyInitialPlaces() + { + $places = range('a', 'c'); + $transitions = []; + + $definition = new Definition($places, $transitions, ['a', 'b']); + + (new WorkflowValidator(true))->validate($definition, 'foo'); + } + public function testSameTransitionNameButNotSamePlace() { $places = range('a', 'd'); diff --git a/src/Symfony/Component/Workflow/Validator/DefinitionValidatorInterface.php b/src/Symfony/Component/Workflow/Validator/DefinitionValidatorInterface.php index 244dceae9a9da..1282c966b7d32 100644 --- a/src/Symfony/Component/Workflow/Validator/DefinitionValidatorInterface.php +++ b/src/Symfony/Component/Workflow/Validator/DefinitionValidatorInterface.php @@ -16,6 +16,7 @@ /** * @author Tobias Nyholm + * @author Grégoire Pineau */ interface DefinitionValidatorInterface { diff --git a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php index 7dbe694940518..78b32e648e328 100644 --- a/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php +++ b/src/Symfony/Component/Workflow/Validator/StateMachineValidator.php @@ -37,10 +37,15 @@ public function validate(Definition $definition, $name) // Enforcing uniqueness of the names of transitions starting at each node $from = reset($froms); if (isset($transitionFromNames[$from][$transition->getName()])) { - throw new InvalidDefinitionException(sprintf('A transition from a place/state must have an unique name. Multiple transitions named "%s" from place/state "%s" where found on StateMachine "%s". ', $transition->getName(), $from, $name)); + throw new InvalidDefinitionException(sprintf('A transition from a place/state must have an unique name. Multiple transitions named "%s" from place/state "%s" where found on StateMachine "%s".', $transition->getName(), $from, $name)); } $transitionFromNames[$from][$transition->getName()] = true; } + + $initialPlaces = $definition->getInitialPlaces(); + if (2 <= count($initialPlaces)) { + throw new InvalidDefinitionException(sprintf('The state machine "%s" can not store many places. But the definition has %s initial places. Only one is supported.', $name, \count($initialPlaces))); + } } } diff --git a/src/Symfony/Component/Workflow/Validator/WorkflowValidator.php b/src/Symfony/Component/Workflow/Validator/WorkflowValidator.php index 0cb420ba6ad4a..2a31ec8e46594 100644 --- a/src/Symfony/Component/Workflow/Validator/WorkflowValidator.php +++ b/src/Symfony/Component/Workflow/Validator/WorkflowValidator.php @@ -16,6 +16,7 @@ /** * @author Tobias Nyholm + * @author Grégoire Pineau */ class WorkflowValidator implements DefinitionValidatorInterface { @@ -48,5 +49,10 @@ public function validate(Definition $definition, $name) throw new InvalidDefinitionException(sprintf('The marking store of workflow "%s" can not store many places. But the transition "%s" has too many output (%d). Only one is accepted.', $name, $transition->getName(), \count($transition->getTos()))); } } + + $initialPlaces = $definition->getInitialPlaces(); + if (2 <= count($initialPlaces)) { + throw new InvalidDefinitionException(sprintf('The marking store of workflow "%s" can not store many places. But the definition has %s initial places. Only one is supported.', $name, \count($initialPlaces))); + } } } diff --git a/src/Symfony/Component/Workflow/Workflow.php b/src/Symfony/Component/Workflow/Workflow.php index c0866c663796a..11fbe5f348375 100644 --- a/src/Symfony/Component/Workflow/Workflow.php +++ b/src/Symfony/Component/Workflow/Workflow.php @@ -61,10 +61,12 @@ public function getMarking($subject) // check if the subject is already in the workflow if (!$marking->getPlaces()) { - if (!$this->definition->getInitialPlace()) { + if (!$this->definition->getInitialPlaces()) { throw new LogicException(sprintf('The Marking is empty and there is no initial place for workflow "%s".', $this->name)); } - $marking->mark($this->definition->getInitialPlace()); + foreach ($this->definition->getInitialPlaces() as $place) { + $marking->mark($place); + } // update the subject with the new marking $this->markingStore->setMarking($subject, $marking); 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