be able to enable workflow support explicitly
This commit is contained in:
parent
012c56b8cb
commit
eaa506f562
@ -247,141 +247,165 @@ class Configuration implements ConfigurationInterface
|
||||
->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()
|
||||
->enumNode('type')
|
||||
->values(array('multiple_state', 'single_state'))
|
||||
->arrayNode('audit_trail')
|
||||
->canBeEnabled()
|
||||
->end()
|
||||
->arrayNode('arguments')
|
||||
->enumNode('type')
|
||||
->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('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()
|
||||
->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')
|
||||
->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()
|
||||
->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;
|
||||
->validate()
|
||||
->ifTrue(function ($v) {
|
||||
return $v['supports'] && isset($v['support_strategy']);
|
||||
})
|
||||
->thenInvalid('"supports" and "support_strategy" cannot be used together.')
|
||||
->end()
|
||||
->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()
|
||||
->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()
|
||||
|
@ -530,13 +530,13 @@ class FrameworkExtension extends Extension
|
||||
/**
|
||||
* 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 @@ class FrameworkExtension extends Extension
|
||||
|
||||
$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);
|
||||
|
@ -254,15 +254,16 @@
|
||||
|
||||
<xsd:complexType name="workflow">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="marking-store" type="marking_store" />
|
||||
<xsd:element name="marking-store" type="marking_store" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="support" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="place" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="transition" type="transition" minOccurs="1" maxOccurs="unbounded" />
|
||||
<xsd:element name="place" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="transition" type="transition" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="workflow_type" />
|
||||
<xsd:attribute name="initial-place" type="xsd:string" />
|
||||
<xsd:attribute name="support-strategy" type="xsd:string" />
|
||||
<xsd:attribute name="enabled" type="xsd:boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="marking_store">
|
||||
|
@ -331,7 +331,10 @@ class ConfigurationTest extends TestCase
|
||||
'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,
|
||||
|
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
$container->loadFromExtension('framework', array(
|
||||
'workflows' => null,
|
||||
));
|
@ -0,0 +1,11 @@
|
||||
<?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 enabled="true" />
|
||||
</framework:config>
|
||||
</container>
|
@ -0,0 +1,2 @@
|
||||
framework:
|
||||
workflows: ~
|
@ -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\DateTimeNormalizer;
|
||||
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 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$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');
|
||||
|
Reference in New Issue
Block a user