[FrameworkBundle] Allow multiple transactions with the same name

This commit is contained in:
Adam Prager 2016-12-06 20:04:08 +01:00
parent 16cea37359
commit 7c86e1609b
6 changed files with 177 additions and 4 deletions

View File

@ -295,11 +295,33 @@ class Configuration implements ConfigurationInterface
->end()
->end()
->arrayNode('transitions')
->useAttributeAsKey('name')
->beforeNormalization()
->always()
->then(function ($transitions) {
// It's an indexed array, we let the validation occurs
if (isset($transitions[0])) {
return $transitions;
}
foreach ($transitions as $name => $transition) {
if (array_key_exists('name', $transition)) {
continue;
}
$transition['name'] = $name;
$transitions[$name] = $transition;
}
return $transitions;
})
->end()
->isRequired()
->requiresAtLeastOneElement()
->prototype('array')
->children()
->scalarNode('name')
->isRequired()
->cannotBeEmpty()
->end()
->arrayNode('from')
->beforeNormalization()
->ifString()

View File

@ -408,13 +408,13 @@ class FrameworkExtension extends Extension
$type = $workflow['type'];
$transitions = array();
foreach ($workflow['transitions'] as $transitionName => $transition) {
foreach ($workflow['transitions'] as $transition) {
if ($type === 'workflow') {
$transitions[] = new Definition(Workflow\Transition::class, array($transitionName, $transition['from'], $transition['to']));
$transitions[] = new Definition(Workflow\Transition::class, array($transition['name'], $transition['from'], $transition['to']));
} elseif ($type === 'state_machine') {
foreach ($transition['from'] as $from) {
foreach ($transition['to'] as $to) {
$transitions[] = new Definition(Workflow\Transition::class, array($transitionName, $from, $to));
$transitions[] = new Definition(Workflow\Transition::class, array($transition['name'], $from, $to));
}
}
}

View File

@ -0,0 +1,49 @@
<?php
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest;
$container->loadFromExtension('framework', array(
'workflows' => array(
'article' => array(
'type' => 'workflow',
'marking_store' => array(
'type' => 'multiple_state',
),
'supports' => array(
FrameworkExtensionTest::class,
),
'initial_place' => 'draft',
'places' => array(
'draft',
'wait_for_journalist',
'approved_by_journalist',
'wait_for_spellchecker',
'approved_by_spellchecker',
'published',
),
'transitions' => array(
'request_review' => array(
'from' => 'draft',
'to' => array('wait_for_journalist', 'wait_for_spellchecker'),
),
'journalist_approval' => array(
'from' => 'wait_for_journalist',
'to' => 'approved_by_journalist',
),
'spellchecker_approval' => array(
'from' => 'wait_for_spellchecker',
'to' => 'approved_by_spellchecker',
),
'publish' => array(
'from' => array('approved_by_journalist', 'approved_by_spellchecker'),
'to' => 'published',
),
'publish_editor_in_chief' => array(
'name' => 'publish',
'from' => 'draft',
'to' => 'published',
),
),
),
),
));

View File

@ -0,0 +1,46 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:workflow name="article" type="workflow" initial-place="draft">
<framework:marking-store type="multiple_state">
<framework:argument>a</framework:argument>
<framework:argument>a</framework:argument>
</framework:marking-store>
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
<framework:place>draft</framework:place>
<framework:place>wait_for_journalist</framework:place>
<framework:place>approved_by_journalist</framework:place>
<framework:place>wait_for_spellchecker</framework:place>
<framework:place>approved_by_spellchecker</framework:place>
<framework:place>published</framework:place>
<framework:transition name="request_review">
<framework:from>draft</framework:from>
<framework:to>wait_for_journalist</framework:to>
<framework:to>wait_for_spellchecker</framework:to>
</framework:transition>
<framework:transition name="journalist_approval">
<framework:from>wait_for_journalist</framework:from>
<framework:to>approved_by_journalist</framework:to>
</framework:transition>
<framework:transition name="spellchecker_approval">
<framework:from>wait_for_spellchecker</framework:from>
<framework:to>approved_by_spellchecker</framework:to>
</framework:transition>
<framework:transition name="publish">
<framework:from>approved_by_journalist</framework:from>
<framework:from>approved_by_spellchecker</framework:from>
<framework:to>published</framework:to>
</framework:transition>
<framework:transition name="publish">
<framework:from>draft</framework:from>
<framework:to>published</framework:to>
</framework:transition>
</framework:workflow>
</framework:config>
</container>

View File

@ -0,0 +1,33 @@
framework:
workflows:
article:
type: workflow
marking_store:
type: multiple_state
supports:
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
initial_place: draft
places:
- draft
- wait_for_journalist
- approved_by_journalist
- wait_for_spellchecker
- approved_by_spellchecker
- published
transitions:
request_review:
from: [draft]
to: [wait_for_journalist, wait_for_spellchecker]
journalist_approval:
from: [wait_for_journalist]
to: [approved_by_journalist]
spellchecker_approval:
from: [wait_for_spellchecker]
to: [approved_by_spellchecker]
publish:
from: [approved_by_journalist, approved_by_spellchecker]
to: [published]
publish_editor_in_chief:
name: publish
from: [draft]
to: [published]

View File

@ -185,6 +185,29 @@ abstract class FrameworkExtensionTest extends TestCase
$this->createContainerFromFile('workflow_with_arguments_and_service');
}
public function testWorkflowMultipleTransitionsWithSameName()
{
$container = $this->createContainerFromFile('workflow_with_multiple_transitions_with_same_name');
$this->assertTrue($container->hasDefinition('workflow.article', 'Workflow is registered as a service'));
$this->assertTrue($container->hasDefinition('workflow.article.definition', 'Workflow definition is registered as a service'));
$workflowDefinition = $container->getDefinition('workflow.article.definition');
$transitions = $workflowDefinition->getArgument(1);
$this->assertCount(5, $transitions);
$this->assertSame('request_review', $transitions[0]->getArgument(0));
$this->assertSame('journalist_approval', $transitions[1]->getArgument(0));
$this->assertSame('spellchecker_approval', $transitions[2]->getArgument(0));
$this->assertSame('publish', $transitions[3]->getArgument(0));
$this->assertSame('publish', $transitions[4]->getArgument(0));
$this->assertSame(array('approved_by_journalist', 'approved_by_spellchecker'), $transitions[3]->getArgument(1));
$this->assertSame(array('draft'), $transitions[4]->getArgument(1));
}
public function testRouter()
{
$container = $this->createContainerFromFile('full');