[Workflow] Move code from ValidateWorkflowsPass to the FrameworkExtension
This commit is contained in:
parent
18cd3420a4
commit
a608797165
@ -603,20 +603,15 @@ class FrameworkExtension extends Extension
|
||||
|
||||
// Create places
|
||||
$places = array_column($workflow['places'], 'name');
|
||||
$initialPlace = $workflow['initial_place'] ?? null;
|
||||
|
||||
// Create a Definition
|
||||
$definitionDefinition = new Definition(Workflow\Definition::class);
|
||||
$definitionDefinition->setPublic(false);
|
||||
$definitionDefinition->addArgument($places);
|
||||
$definitionDefinition->addArgument($transitions);
|
||||
$definitionDefinition->addArgument($workflow['initial_place'] ?? null);
|
||||
$definitionDefinition->addArgument($initialPlace);
|
||||
$definitionDefinition->addArgument($metadataStoreDefinition);
|
||||
$definitionDefinition->addTag('workflow.definition', [
|
||||
'name' => $name,
|
||||
'type' => $type,
|
||||
'marking_store' => $workflow['marking_store']['type'] ?? null,
|
||||
'single_state' => 'method' === ($workflow['marking_store']['type'] ?? null) && ($workflow['marking_store']['arguments'][0] ?? false),
|
||||
]);
|
||||
|
||||
// Create MarkingStore
|
||||
if (isset($workflow['marking_store']['type'])) {
|
||||
@ -641,6 +636,34 @@ class FrameworkExtension extends Extension
|
||||
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
|
||||
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name.'.'.$type);
|
||||
|
||||
// Validate Workflow
|
||||
$validator = null;
|
||||
switch (true) {
|
||||
case 'state_machine' === $workflow['type']:
|
||||
$validator = new Workflow\Validator\StateMachineValidator();
|
||||
break;
|
||||
case 'method' === ($workflow['marking_store']['type'] ?? null):
|
||||
$singlePlace = $workflow['marking_store']['arguments'][0] ?? false;
|
||||
$validator = new Workflow\Validator\WorkflowValidator($singlePlace);
|
||||
break;
|
||||
case 'single_state' === ($workflow['marking_store']['type'] ?? null):
|
||||
$validator = new Workflow\Validator\WorkflowValidator(true);
|
||||
break;
|
||||
case 'multiple_state' === ($workflow['marking_store']['type'] ?? false):
|
||||
$validator = new Workflow\Validator\WorkflowValidator(false);
|
||||
break;
|
||||
}
|
||||
if ($validator) {
|
||||
$realDefinition = (new Workflow\DefinitionBuilder($places))
|
||||
->addTransitions(array_map(function (Reference $ref) use ($container): Workflow\Transition {
|
||||
return $container->get((string) $ref);
|
||||
}, $transitions))
|
||||
->setInitialPlace($initialPlace)
|
||||
->build()
|
||||
;
|
||||
$validator->validate($realDefinition, $name);
|
||||
}
|
||||
|
||||
// Add workflow to Registry
|
||||
if ($workflow['supports']) {
|
||||
foreach ($workflow['supports'] as $supportedClassName) {
|
||||
|
@ -54,7 +54,6 @@ use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
|
||||
use Symfony\Component\Translation\DependencyInjection\TranslatorPathsPass;
|
||||
use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass;
|
||||
use Symfony\Component\Validator\DependencyInjection\AddValidatorInitializersPass;
|
||||
use Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass;
|
||||
|
||||
/**
|
||||
* Bundle.
|
||||
@ -115,7 +114,6 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new DataCollectorTranslatorPass());
|
||||
$container->addCompilerPass(new ControllerArgumentValueResolverPass());
|
||||
$container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32);
|
||||
$this->addCompilerPassIfExists($container, ValidateWorkflowsPass::class);
|
||||
$container->addCompilerPass(new CachePoolClearerPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
$container->addCompilerPass(new CachePoolPrunerPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
$this->addCompilerPassIfExists($container, FormPass::class);
|
||||
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest;
|
||||
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'my_workflow' => [
|
||||
'type' => 'state_machine',
|
||||
'supports' => [
|
||||
FrameworkExtensionTest::class,
|
||||
],
|
||||
'places' => [
|
||||
'first',
|
||||
'middle',
|
||||
'last',
|
||||
],
|
||||
'transitions' => [
|
||||
'go' => [
|
||||
'from' => [
|
||||
'first',
|
||||
],
|
||||
'to' => [
|
||||
'middle',
|
||||
'last',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
@ -0,0 +1,22 @@
|
||||
<?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="my_workflow" type="state_machine">
|
||||
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
|
||||
<framework:place name="first" />
|
||||
<framework:place name="middle" />
|
||||
<framework:place name="last" />
|
||||
<framework:transition name="go">
|
||||
<framework:from>first</framework:from>
|
||||
<framework:to>middle</framework:to>
|
||||
<framework:to>last</framework:to>
|
||||
</framework:transition>
|
||||
</framework:workflow>
|
||||
</framework:config>
|
||||
</container>
|
@ -29,12 +29,12 @@
|
||||
<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: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_spellchker</framework:from>
|
||||
<framework:from>approved_by_spellchecker</framework:from>
|
||||
<framework:to>published</framework:to>
|
||||
</framework:transition>
|
||||
</framework:workflow>
|
||||
|
@ -0,0 +1,11 @@
|
||||
framework:
|
||||
workflows:
|
||||
my_workflow:
|
||||
type: state_machine
|
||||
supports:
|
||||
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
|
||||
places: [first, middle, last]
|
||||
transitions:
|
||||
go:
|
||||
from: first
|
||||
to: [last, middle ]
|
@ -215,7 +215,6 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$workflowDefinition->getArgument(0),
|
||||
'Places are passed to the workflow definition'
|
||||
);
|
||||
$this->assertSame(['workflow.definition' => [['name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state', 'single_state' => false]]], $workflowDefinition->getTags());
|
||||
$this->assertCount(4, $workflowDefinition->getArgument(1));
|
||||
$this->assertSame('draft', $workflowDefinition->getArgument(2));
|
||||
|
||||
@ -237,7 +236,6 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$stateMachineDefinition->getArgument(0),
|
||||
'Places are passed to the state machine definition'
|
||||
);
|
||||
$this->assertSame(['workflow.definition' => [['name' => 'pull_request', 'type' => 'state_machine', 'marking_store' => 'single_state', 'single_state' => false]]], $stateMachineDefinition->getTags());
|
||||
$this->assertCount(9, $stateMachineDefinition->getArgument(1));
|
||||
$this->assertSame('start', $stateMachineDefinition->getArgument(2));
|
||||
|
||||
@ -272,6 +270,15 @@ abstract class FrameworkExtensionTest extends TestCase
|
||||
$this->assertGreaterThan(0, \count($registryDefinition->getMethodCalls()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @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".
|
||||
*/
|
||||
public function testWorkflowAreValidated()
|
||||
{
|
||||
$this->createContainerFromFile('workflow_not_valid');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||
* @expectedExceptionMessage "type" and "service" cannot be used together.
|
||||
|
@ -56,4 +56,178 @@ class PhpFrameworkExtensionTest extends FrameworkExtensionTest
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException
|
||||
* @expectedExceptionMessage A transition from a place/state must have an unique name. Multiple transitions named "a_to_b" from place/state "a" where found on StateMachine "article".
|
||||
*/
|
||||
public function testWorkflowValidationStateMachine()
|
||||
{
|
||||
$this->createContainerFromClosure(function ($container) {
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'article' => [
|
||||
'type' => 'state_machine',
|
||||
'supports' => [
|
||||
__CLASS__,
|
||||
],
|
||||
'places' => [
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
],
|
||||
'transitions' => [
|
||||
'a_to_b' => [
|
||||
'from' => ['a'],
|
||||
'to' => ['b', 'c'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException
|
||||
* @expectedExceptionMessage The marking store of workflow "article" can not store many places. But the transition "a_to_b" has too many output (2). Only one is accepted.
|
||||
*/
|
||||
public function testWorkflowValidationMethodSingle()
|
||||
{
|
||||
$this->createContainerFromClosure(function ($container) {
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'article' => [
|
||||
'type' => 'workflow',
|
||||
'marking_store' => [
|
||||
'type' => 'method',
|
||||
'arguments' => [
|
||||
true,
|
||||
],
|
||||
],
|
||||
'supports' => [
|
||||
__CLASS__,
|
||||
],
|
||||
'places' => [
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
],
|
||||
'transitions' => [
|
||||
'a_to_b' => [
|
||||
'from' => ['a'],
|
||||
'to' => ['b', 'c'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
public function testWorkflowValidationMethodNotSingle()
|
||||
{
|
||||
$this->createContainerFromClosure(function ($container) {
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'article' => [
|
||||
'type' => 'workflow',
|
||||
'marking_store' => [
|
||||
'type' => 'method',
|
||||
'arguments' => [
|
||||
false,
|
||||
],
|
||||
],
|
||||
'supports' => [
|
||||
__CLASS__,
|
||||
],
|
||||
'places' => [
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
],
|
||||
'transitions' => [
|
||||
'a_to_b' => [
|
||||
'from' => ['a'],
|
||||
'to' => ['b', 'c'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
// the test ensures that the validation does not fail (i.e. it does not throw any exceptions)
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testWorkflowValidationMultipleState()
|
||||
{
|
||||
$this->createContainerFromClosure(function ($container) {
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'article' => [
|
||||
'type' => 'workflow',
|
||||
'marking_store' => [
|
||||
'type' => 'multiple_state',
|
||||
],
|
||||
'supports' => [
|
||||
__CLASS__,
|
||||
],
|
||||
'places' => [
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
],
|
||||
'transitions' => [
|
||||
'a_to_b' => [
|
||||
'from' => ['a'],
|
||||
'to' => ['b', 'c'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
// the test ensures that the validation does not fail (i.e. it does not throw any exceptions)
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Workflow\Exception\InvalidDefinitionException
|
||||
* @expectedExceptionMessage The marking store of workflow "article" can not store many places. But the transition "a_to_b" has too many output (2). Only one is accepted.
|
||||
*/
|
||||
public function testWorkflowValidationSingleState()
|
||||
{
|
||||
$this->createContainerFromClosure(function ($container) {
|
||||
$container->loadFromExtension('framework', [
|
||||
'workflows' => [
|
||||
'article' => [
|
||||
'type' => 'workflow',
|
||||
'marking_store' => [
|
||||
'type' => 'single_state',
|
||||
],
|
||||
'supports' => [
|
||||
__CLASS__,
|
||||
],
|
||||
'places' => [
|
||||
'a',
|
||||
'b',
|
||||
'c',
|
||||
],
|
||||
'transitions' => [
|
||||
'a_to_b' => [
|
||||
'from' => ['a'],
|
||||
'to' => ['b', 'c'],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
||||
// the test ensures that the validation does not fail (i.e. it does not throw any exceptions)
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ use Symfony\Component\Workflow\Validator\WorkflowValidator;
|
||||
|
||||
/**
|
||||
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
|
||||
*
|
||||
* @deprecated since Symfony 4.3
|
||||
*/
|
||||
class ValidateWorkflowsPass implements CompilerPassInterface
|
||||
{
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Workflow\Tests\DependencyInjection;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\Workflow\Definition as WorkflowDefinition;
|
||||
use Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass;
|
||||
use Symfony\Component\Workflow\Transition;
|
||||
|
||||
class ValidateWorkflowsPassTest extends TestCase
|
||||
{
|
||||
public function testProcess()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$container->register('definition1', WorkflowDefinition::class)
|
||||
->addArgument(['a', 'b', 'c'])
|
||||
->addArgument([
|
||||
new Definition(Transition::class, ['t1', 'a', 'b']),
|
||||
new Definition(Transition::class, ['t2', 'a', 'c']),
|
||||
])
|
||||
->addTag('workflow.definition', ['name' => 'wf1', 'type' => 'state_machine', 'marking_store' => 'foo']);
|
||||
|
||||
(new ValidateWorkflowsPass())->process($container);
|
||||
|
||||
$workflowDefinition = $container->get('definition1');
|
||||
|
||||
$this->assertSame(['a' => 'a', 'b' => 'b', 'c' => 'c'], $workflowDefinition->getPlaces());
|
||||
$this->assertEquals([new Transition('t1', 'a', 'b'), new Transition('t2', 'a', 'c')], $workflowDefinition->getTransitions());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user