minor #20458 Added XML support for Workflow configuration (wouterj, xabbuh)
This PR was merged into the 3.2-dev branch. Discussion ---------- Added XML support for Workflow configuration | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | symfony/symfony-docs#6871 Commits -------94a7e7e
[Workflow] streamline XML schema definition6381caa
Added XML support for Workflow configuration
This commit is contained in:
commit
de787544f0
@ -231,16 +231,21 @@ class Configuration implements ConfigurationInterface
|
||||
private function addWorkflowSection(ArrayNodeDefinition $rootNode)
|
||||
{
|
||||
$rootNode
|
||||
->fixXmlConfig('workflow')
|
||||
->children()
|
||||
->arrayNode('workflows')
|
||||
->useAttributeAsKey('name')
|
||||
->prototype('array')
|
||||
->fixXmlConfig('support')
|
||||
->fixXmlConfig('place')
|
||||
->fixXmlConfig('transition')
|
||||
->children()
|
||||
->enumNode('type')
|
||||
->values(array('workflow', 'state_machine'))
|
||||
->defaultValue('workflow')
|
||||
->end()
|
||||
->arrayNode('marking_store')
|
||||
->fixXmlConfig('argument')
|
||||
->children()
|
||||
->enumNode('type')
|
||||
->values(array('multiple_state', 'single_state'))
|
||||
|
@ -8,7 +8,7 @@
|
||||
<xsd:element name="config" type="config" />
|
||||
|
||||
<xsd:complexType name="config">
|
||||
<xsd:all>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="assets" type="assets" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="form" type="form" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="csrf-protection" type="csrf_protection" minOccurs="0" maxOccurs="1" />
|
||||
@ -26,8 +26,8 @@
|
||||
<xsd:element name="serializer" type="serializer" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="property-info" type="property_info" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="workflows" type="workflows" minOccurs="0" maxOccurs="1" />
|
||||
</xsd:all>
|
||||
<xsd:element name="workflow" type="workflow" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
|
||||
<xsd:attribute name="http-method-override" type="xsd:boolean" />
|
||||
<xsd:attribute name="trusted-proxies" type="xsd:string" />
|
||||
@ -228,42 +228,45 @@
|
||||
<xsd:attribute name="clearer" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="workflows">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="workflow" type="workflow" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="workflow">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="marking-store" type="marking_store" />
|
||||
<xsd:element name="supports" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="places" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="transitions" type="transitions" />
|
||||
<xsd:element name="support" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="place" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="transition" type="transition" minOccurs="1" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="type" type="workflow_type" />
|
||||
<xsd:attribute name="initial-place" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="marking_store">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="type" type="xsd:string" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="arguments" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="service" type="xsd:string" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="argument" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="type" type="marking_store_type" />
|
||||
<xsd:attribute name="service" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="transitions">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="transition" type="transition" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
<xsd:simpleType name="marking_store_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="multiple_state" />
|
||||
<xsd:enumeration value="single_state" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="transition">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="from" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="to" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="workflow_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="state_machine" />
|
||||
<xsd:enumeration value="workflow" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
||||
|
@ -1,30 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest;
|
||||
|
||||
$container->loadFromExtension('framework', array(
|
||||
'workflows' => array(
|
||||
'my_workflow' => array(
|
||||
'marking_store' => array(
|
||||
'type' => 'multiple_state',
|
||||
),
|
||||
'supports' => array(
|
||||
FrameworkExtensionTest::class,
|
||||
),
|
||||
'places' => array(
|
||||
'first',
|
||||
'last',
|
||||
),
|
||||
'transitions' => array(
|
||||
'go' => array(
|
||||
'from' => array(
|
||||
'first',
|
||||
),
|
||||
'to' => array(
|
||||
'last',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
@ -0,0 +1,92 @@
|
||||
<?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',
|
||||
),
|
||||
),
|
||||
),
|
||||
'pull_request' => array(
|
||||
'type' => 'state_machine',
|
||||
'marking_store' => array(
|
||||
'type' => 'single_state',
|
||||
),
|
||||
'supports' => array(
|
||||
FrameworkExtensionTest::class,
|
||||
),
|
||||
'initial_place' => 'start',
|
||||
'places' => array(
|
||||
'start',
|
||||
'coding',
|
||||
'travis',
|
||||
'review',
|
||||
'merged',
|
||||
'closed',
|
||||
),
|
||||
'transitions' => array(
|
||||
'submit' => array(
|
||||
'from' => 'start',
|
||||
'to' => 'travis',
|
||||
),
|
||||
'update' => array(
|
||||
'from' => array('coding', 'travis', 'review'),
|
||||
'to' => 'travis',
|
||||
),
|
||||
'wait_for_review' => array(
|
||||
'from' => 'travis',
|
||||
'to' => 'review',
|
||||
),
|
||||
'request_change' => array(
|
||||
'from' => 'review',
|
||||
'to' => 'coding',
|
||||
),
|
||||
'accept' => array(
|
||||
'from' => 'review',
|
||||
'to' => 'merged',
|
||||
),
|
||||
'reject' => array(
|
||||
'from' => 'review',
|
||||
'to' => 'closed',
|
||||
),
|
||||
'reopen' => array(
|
||||
'from' => 'closed',
|
||||
'to' => 'review',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
@ -1,29 +0,0 @@
|
||||
<?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:workflows>
|
||||
<framework:workflow name="my_workflow">
|
||||
<framework:marking-store>
|
||||
<framework:type>multiple_state</framework:type>
|
||||
<framework:arguments>a</framework:arguments>
|
||||
<framework:arguments>a</framework:arguments>
|
||||
</framework:marking-store>
|
||||
<framework:supports>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:supports>
|
||||
<framework:places>first</framework:places>
|
||||
<framework:places>last</framework:places>
|
||||
<framework:transitions>
|
||||
<framework:transition name="foobar">
|
||||
<framework:from>a</framework:from>
|
||||
<framework:to>a</framework:to>
|
||||
</framework:transition>
|
||||
</framework:transitions>
|
||||
</framework:workflow>
|
||||
</framework:workflows>
|
||||
</framework:config>
|
||||
</container>
|
@ -0,0 +1,83 @@
|
||||
<?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_spellcheker</framework:from>
|
||||
<framework:to>approved_by_spellchker</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="publish">
|
||||
<framework:from>approved_by_journalist</framework:from>
|
||||
<framework:from>approved_by_spellchker</framework:from>
|
||||
<framework:to>published</framework:to>
|
||||
</framework:transition>
|
||||
</framework:workflow>
|
||||
|
||||
<framework:workflow name="pull_request" type="state_machine" initial-place="start">
|
||||
<framework:marking-store type="single_state"/>
|
||||
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
|
||||
<framework:place>start</framework:place>
|
||||
<framework:place>coding</framework:place>
|
||||
<framework:place>travis</framework:place>
|
||||
<framework:place>review</framework:place>
|
||||
<framework:place>merged</framework:place>
|
||||
<framework:place>closed</framework:place>
|
||||
<framework:transition name="submit">
|
||||
<framework:from>start</framework:from>
|
||||
<framework:to>travis</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="update">
|
||||
<framework:from>coding</framework:from>
|
||||
<framework:from>travis</framework:from>
|
||||
<framework:from>review</framework:from>
|
||||
<framework:to>travis</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="wait_for_review">
|
||||
<framework:from>travis</framework:from>
|
||||
<framework:to>review</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="request_change">
|
||||
<framework:from>review</framework:from>
|
||||
<framework:to>coding</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="accept">
|
||||
<framework:from>review</framework:from>
|
||||
<framework:to>merged</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="reject">
|
||||
<framework:from>review</framework:from>
|
||||
<framework:to>closed</framework:to>
|
||||
</framework:transition>
|
||||
<framework:transition name="reopen">
|
||||
<framework:from>closed</framework:from>
|
||||
<framework:to>review</framework:to>
|
||||
</framework:transition>
|
||||
</framework:workflow>
|
||||
</framework:config>
|
||||
</container>
|
@ -1,16 +0,0 @@
|
||||
framework:
|
||||
workflows:
|
||||
my_workflow:
|
||||
marking_store:
|
||||
type: multiple_state
|
||||
supports:
|
||||
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
|
||||
places:
|
||||
- first
|
||||
- last
|
||||
transitions:
|
||||
go:
|
||||
from:
|
||||
- first
|
||||
to:
|
||||
- last
|
@ -0,0 +1,65 @@
|
||||
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]
|
||||
pull_request:
|
||||
type: state_machine
|
||||
marking_store:
|
||||
type: single_state
|
||||
supports:
|
||||
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
|
||||
initial_place: start
|
||||
places:
|
||||
- start
|
||||
- coding
|
||||
- travis
|
||||
- review
|
||||
- merged
|
||||
- closed
|
||||
transitions:
|
||||
submit:
|
||||
from: start
|
||||
to: travis
|
||||
update:
|
||||
from: [coding, travis, review]
|
||||
to: travis
|
||||
wait_for_review:
|
||||
from: travis
|
||||
to: review
|
||||
request_change:
|
||||
from: review
|
||||
to: coding
|
||||
accept:
|
||||
from: review
|
||||
to: merged
|
||||
reject:
|
||||
from: review
|
||||
to: closed
|
||||
reopen:
|
||||
from: closed
|
||||
to: review
|
@ -120,11 +120,51 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$this->assertFalse($container->hasDefinition('data_collector.config'), '->registerProfilerConfiguration() does not load collectors.xml');
|
||||
}
|
||||
|
||||
public function testWorkflow()
|
||||
public function testWorkflows()
|
||||
{
|
||||
$container = $this->createContainerFromFile('workflow');
|
||||
$container = $this->createContainerFromFile('workflows');
|
||||
|
||||
$this->assertTrue($container->hasDefinition('workflow.my_workflow'));
|
||||
$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');
|
||||
|
||||
$this->assertSame(
|
||||
array(
|
||||
'draft',
|
||||
'wait_for_journalist',
|
||||
'approved_by_journalist',
|
||||
'wait_for_spellchecker',
|
||||
'approved_by_spellchecker',
|
||||
'published',
|
||||
),
|
||||
$workflowDefinition->getArgument(0),
|
||||
'Places are passed to the workflow definition'
|
||||
);
|
||||
$this->assertSame(array('workflow.definition' => array(array('name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state'))), $workflowDefinition->getTags());
|
||||
|
||||
$this->assertTrue($container->hasDefinition('state_machine.pull_request', 'State machine is registered as a service'));
|
||||
$this->assertTrue($container->hasDefinition('state_machine.pull_request.definition', 'State machine definition is registered as a service'));
|
||||
$this->assertCount(4, $workflowDefinition->getArgument(1));
|
||||
$this->assertSame('draft', $workflowDefinition->getArgument(2));
|
||||
|
||||
$stateMachineDefinition = $container->getDefinition('state_machine.pull_request.definition');
|
||||
|
||||
$this->assertSame(
|
||||
array(
|
||||
'start',
|
||||
'coding',
|
||||
'travis',
|
||||
'review',
|
||||
'merged',
|
||||
'closed',
|
||||
),
|
||||
$stateMachineDefinition->getArgument(0),
|
||||
'Places are passed to the state machine definition'
|
||||
);
|
||||
$this->assertSame(array('workflow.definition' => array(array('name' => 'pull_request', 'type' => 'state_machine', 'marking_store' => 'single_state'))), $stateMachineDefinition->getTags());
|
||||
$this->assertCount(9, $stateMachineDefinition->getArgument(1));
|
||||
$this->assertSame('start', $stateMachineDefinition->getArgument(2));
|
||||
}
|
||||
|
||||
public function testRouter()
|
||||
|
Reference in New Issue
Block a user