diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index fcc0e714c8cb6..66934aba6a419 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -247,141 +247,165 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
->fixXmlConfig('workflow')
->children()
->arrayNode('workflows')
- ->useAttributeAsKey('name')
- ->prototype('array')
- ->fixXmlConfig('support')
- ->fixXmlConfig('place')
- ->fixXmlConfig('transition')
- ->children()
- ->arrayNode('audit_trail')
- ->canBeEnabled()
- ->end()
- ->enumNode('type')
- ->values(array('workflow', 'state_machine'))
- ->end()
- ->arrayNode('marking_store')
- ->fixXmlConfig('argument')
+ ->canBeEnabled()
+ ->beforeNormalization()
+ ->always(function ($v) {
+ if (true === $v['enabled']) {
+ $workflows = $v;
+ unset($workflows['enabled']);
+
+ if (count($workflows) === 1 && isset($workflows[0]['enabled'])) {
+ $workflows = array();
+ }
+
+ $v = array(
+ 'enabled' => true,
+ 'workflows' => $workflows,
+ );
+ }
+
+ return $v;
+ })
+ ->end()
+ ->children()
+ ->arrayNode('workflows')
+ ->useAttributeAsKey('name')
+ ->prototype('array')
+ ->fixXmlConfig('support')
+ ->fixXmlConfig('place')
+ ->fixXmlConfig('transition')
->children()
+ ->arrayNode('audit_trail')
+ ->canBeEnabled()
+ ->end()
->enumNode('type')
- ->values(array('multiple_state', 'single_state'))
+ ->values(array('workflow', 'state_machine'))
+ ->end()
+ ->arrayNode('marking_store')
+ ->fixXmlConfig('argument')
+ ->children()
+ ->enumNode('type')
+ ->values(array('multiple_state', 'single_state'))
+ ->end()
+ ->arrayNode('arguments')
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function ($v) { return array($v); })
+ ->end()
+ ->requiresAtLeastOneElement()
+ ->prototype('scalar')
+ ->end()
+ ->end()
+ ->scalarNode('service')
+ ->cannotBeEmpty()
+ ->end()
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) { return isset($v['type']) && isset($v['service']); })
+ ->thenInvalid('"type" and "service" cannot be used together.')
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) { return !empty($v['arguments']) && isset($v['service']); })
+ ->thenInvalid('"arguments" and "service" cannot be used together.')
+ ->end()
->end()
- ->arrayNode('arguments')
+ ->arrayNode('supports')
->beforeNormalization()
->ifString()
->then(function ($v) { return array($v); })
->end()
- ->requiresAtLeastOneElement()
->prototype('scalar')
+ ->cannotBeEmpty()
+ ->validate()
+ ->ifTrue(function ($v) { return !class_exists($v); })
+ ->thenInvalid('The supported class %s does not exist.')
+ ->end()
->end()
->end()
- ->scalarNode('service')
+ ->scalarNode('support_strategy')
->cannotBeEmpty()
->end()
- ->end()
- ->validate()
- ->ifTrue(function ($v) { return isset($v['type']) && isset($v['service']); })
- ->thenInvalid('"type" and "service" cannot be used together.')
- ->end()
- ->validate()
- ->ifTrue(function ($v) { return !empty($v['arguments']) && isset($v['service']); })
- ->thenInvalid('"arguments" and "service" cannot be used together.')
- ->end()
- ->end()
- ->arrayNode('supports')
- ->beforeNormalization()
- ->ifString()
- ->then(function ($v) { return array($v); })
- ->end()
- ->prototype('scalar')
- ->cannotBeEmpty()
- ->validate()
- ->ifTrue(function ($v) { return !class_exists($v); })
- ->thenInvalid('The supported class %s does not exist.')
+ ->scalarNode('initial_place')
+ ->defaultNull()
->end()
- ->end()
- ->end()
- ->scalarNode('support_strategy')
- ->cannotBeEmpty()
- ->end()
- ->scalarNode('initial_place')
- ->defaultNull()
- ->end()
- ->arrayNode('places')
- ->isRequired()
- ->requiresAtLeastOneElement()
- ->prototype('scalar')
- ->cannotBeEmpty()
- ->end()
- ->end()
- ->arrayNode('transitions')
- ->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()
- ->scalarNode('guard')
+ ->arrayNode('places')
+ ->isRequired()
+ ->requiresAtLeastOneElement()
+ ->prototype('scalar')
->cannotBeEmpty()
- ->info('An expression to block the transition')
- ->example('is_fully_authenticated() and has_role(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'')
->end()
- ->arrayNode('from')
- ->beforeNormalization()
- ->ifString()
- ->then(function ($v) { return array($v); })
- ->end()
- ->requiresAtLeastOneElement()
- ->prototype('scalar')
- ->cannotBeEmpty()
- ->end()
+ ->end()
+ ->arrayNode('transitions')
+ ->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()
- ->arrayNode('to')
- ->beforeNormalization()
- ->ifString()
- ->then(function ($v) { return array($v); })
- ->end()
- ->requiresAtLeastOneElement()
- ->prototype('scalar')
- ->cannotBeEmpty()
+ ->isRequired()
+ ->requiresAtLeastOneElement()
+ ->prototype('array')
+ ->children()
+ ->scalarNode('name')
+ ->isRequired()
+ ->cannotBeEmpty()
+ ->end()
+ ->scalarNode('guard')
+ ->cannotBeEmpty()
+ ->info('An expression to block the transition')
+ ->example('is_fully_authenticated() and has_role(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'')
+ ->end()
+ ->arrayNode('from')
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function ($v) { return array($v); })
+ ->end()
+ ->requiresAtLeastOneElement()
+ ->prototype('scalar')
+ ->cannotBeEmpty()
+ ->end()
+ ->end()
+ ->arrayNode('to')
+ ->beforeNormalization()
+ ->ifString()
+ ->then(function ($v) { return array($v); })
+ ->end()
+ ->requiresAtLeastOneElement()
+ ->prototype('scalar')
+ ->cannotBeEmpty()
+ ->end()
+ ->end()
->end()
->end()
->end()
->end()
+ ->validate()
+ ->ifTrue(function ($v) {
+ return $v['supports'] && isset($v['support_strategy']);
+ })
+ ->thenInvalid('"supports" and "support_strategy" cannot be used together.')
+ ->end()
+ ->validate()
+ ->ifTrue(function ($v) {
+ return !$v['supports'] && !isset($v['support_strategy']);
+ })
+ ->thenInvalid('"supports" or "support_strategy" should be configured.')
+ ->end()
->end()
->end()
- ->validate()
- ->ifTrue(function ($v) {
- return $v['supports'] && isset($v['support_strategy']);
- })
- ->thenInvalid('"supports" and "support_strategy" cannot be used together.')
- ->end()
- ->validate()
- ->ifTrue(function ($v) {
- return !$v['supports'] && !isset($v['support_strategy']);
- })
- ->thenInvalid('"supports" or "support_strategy" should be configured.')
- ->end()
->end()
->end()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index f54b74abb6051..2d382712911ef 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -530,13 +530,13 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
/**
* Loads the workflow configuration.
*
- * @param array $workflows A workflow configuration array
+ * @param array $config A workflow configuration array
* @param ContainerBuilder $container A ContainerBuilder instance
* @param XmlFileLoader $loader An XmlFileLoader instance
*/
- private function registerWorkflowConfiguration(array $workflows, ContainerBuilder $container, XmlFileLoader $loader)
+ private function registerWorkflowConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
- if (!$workflows) {
+ if (!$config['enabled']) {
if (!class_exists(Workflow\Workflow::class)) {
$container->removeDefinition(WorkflowDumpCommand::class);
}
@@ -552,7 +552,7 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
$registryDefinition = $container->getDefinition('workflow.registry');
- foreach ($workflows as $name => $workflow) {
+ foreach ($config['workflows'] as $name => $workflow) {
if (!array_key_exists('type', $workflow)) {
$workflow['type'] = 'workflow';
@trigger_error(sprintf('The "type" option of the "framework.workflows.%s" configuration entry must be defined since Symfony 3.3. The default value will be "state_machine" in Symfony 4.0.', $name), E_USER_DEPRECATED);
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 d6138133cf2ea..481c469e36164 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
@@ -254,15 +254,16 @@
-
+
-
-
+
+
-
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index 0d2578db040af..1835625da8611 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -331,7 +331,10 @@ protected static function getBundleDefaultConfig()
'default_redis_provider' => 'redis://localhost',
'default_memcached_provider' => 'memcached://localhost',
),
- 'workflows' => array(),
+ 'workflows' => array(
+ 'enabled' => false,
+ 'workflows' => array(),
+ ),
'php_errors' => array(
'log' => true,
'throw' => true,
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_enabled.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_enabled.php
new file mode 100644
index 0000000000000..9a2fe9136a4b3
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows_enabled.php
@@ -0,0 +1,5 @@
+loadFromExtension('framework', array(
+ 'workflows' => null,
+));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_enabled.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_enabled.xml
new file mode 100644
index 0000000000000..51da644be1f9e
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows_enabled.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_enabled.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_enabled.yml
new file mode 100644
index 0000000000000..2a716ff0a1b14
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows_enabled.yml
@@ -0,0 +1,2 @@
+framework:
+ workflows: ~
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index d63a74c874f02..991eda1ea6ac6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection;
use Doctrine\Common\Annotations\Annotation;
+use Symfony\Bundle\FrameworkBundle\Command\WorkflowDumpCommand;
use Symfony\Bundle\FullStack;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass;
@@ -42,6 +43,7 @@
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass;
+use Symfony\Component\Workflow\Registry;
abstract class FrameworkExtensionTest extends TestCase
{
@@ -307,6 +309,14 @@ public function testWorkflowMultipleTransitionsWithSameName()
$this->assertSame(array('draft'), $transitions[4]->getArgument(1));
}
+ public function testWorkflowServicesCanBeEnabled()
+ {
+ $container = $this->createContainerFromFile('workflows_enabled');
+
+ $this->assertTrue($container->has(Registry::class));
+ $this->assertTrue($container->hasDefinition(WorkflowDumpCommand::class));
+ }
+
public function testRouter()
{
$container = $this->createContainerFromFile('full');