Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 67b9b6b

Browse filesBrowse files
committed
[Workflow] Add support for executing custom workflow definition validators during the container compilation
1 parent 2ffd266 commit 67b9b6b
Copy full SHA for 67b9b6b

File tree

Expand file treeCollapse file tree

10 files changed

+110
-0
lines changed
Filter options
Expand file treeCollapse file tree

10 files changed

+110
-0
lines changed

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ CHANGELOG
1616
* Deprecate `session.sid_length` and `session.sid_bits_per_character` config options
1717
* Add the ability to use an existing service as a lock/semaphore resource
1818
* Add support for configuring multiple serializer instances via the configuration
19+
* Add support for executing custom workflow definition validators during the
20+
container compilation
1921

2022
7.1
2123
---

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+19Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
use Symfony\Component\Validator\Validation;
5050
use Symfony\Component\Webhook\Controller\WebhookController;
5151
use Symfony\Component\WebLink\HttpHeaderSerializer;
52+
use Symfony\Component\Workflow\Validator\DefinitionValidatorInterface;
5253
use Symfony\Component\Workflow\WorkflowEvents;
5354

5455
/**
@@ -381,6 +382,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
381382
->useAttributeAsKey('name')
382383
->prototype('array')
383384
->fixXmlConfig('support')
385+
->fixXmlConfig('definition_validator')
384386
->fixXmlConfig('place')
385387
->fixXmlConfig('transition')
386388
->fixXmlConfig('event_to_dispatch', 'events_to_dispatch')
@@ -418,6 +420,23 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
418420
->end()
419421
->end()
420422
->end()
423+
->arrayNode('definition_validators')
424+
->prototype('scalar')
425+
->cannotBeEmpty()
426+
->validate()
427+
->ifTrue(fn ($v) => !class_exists($v))
428+
->thenInvalid('The validation class %s does not exist.')
429+
->end()
430+
->validate()
431+
->ifTrue(fn ($v) => !is_a($v, DefinitionValidatorInterface::class, true))
432+
->thenInvalid(\sprintf('The validation class %%s is not an instance of %s.', DefinitionValidatorInterface::class))
433+
->end()
434+
->validate()
435+
->ifTrue(fn ($v) => 1 <= (new \ReflectionClass($v))->getConstructor()?->getNumberOfRequiredParameters())
436+
->thenInvalid('The validation class %s constructor must not have any arguments.')
437+
->end()
438+
->end()
439+
->end()
421440
->scalarNode('support_strategy')
422441
->cannotBeEmpty()
423442
->end()

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,10 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
10541054
$realDefinition = new Workflow\Definition($places, $trs, $initialMarking);
10551055
$validator->validate($realDefinition, $name);
10561056

1057+
foreach ($workflow['definition_validators'] as $validatorClass) {
1058+
(new $validatorClass())->validate($realDefinition, $name);
1059+
}
1060+
10571061
// Add workflow to Registry
10581062
if ($workflow['supports']) {
10591063
foreach ($workflow['supports'] as $supportedClassName) {

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@
397397
<xsd:element name="initial-marking" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
398398
<xsd:element name="marking-store" type="marking_store" minOccurs="0" maxOccurs="1" />
399399
<xsd:element name="support" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
400+
<xsd:element name="definition-validator" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
400401
<xsd:element name="event-to-dispatch" type="event_to_dispatch" minOccurs="0" maxOccurs="unbounded" />
401402
<xsd:element name="place" type="place" minOccurs="0" maxOccurs="unbounded" />
402403
<xsd:element name="transition" type="transition" minOccurs="0" maxOccurs="unbounded" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator;
4+
5+
use Symfony\Component\Workflow\Definition;
6+
use Symfony\Component\Workflow\Validator\DefinitionValidatorInterface;
7+
8+
class DefinitionValidator implements DefinitionValidatorInterface
9+
{
10+
public static bool $called = false;
11+
12+
public function validate(Definition $definition, string $name): void
13+
{
14+
self::$called = true;
15+
}
16+
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/workflows.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
'supports' => [
1414
FrameworkExtensionTestCase::class,
1515
],
16+
'definition_validators' => [
17+
Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator::class,
18+
],
1619
'initial_marking' => ['draft'],
1720
'metadata' => [
1821
'title' => 'article workflow',

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<framework:audit-trail enabled="true"/>
1414
<framework:initial-marking>draft</framework:initial-marking>
1515
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase</framework:support>
16+
<framework:definition-validator>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator</framework:definition-validator>
1617
<framework:place name="draft" />
1718
<framework:place name="wait_for_journalist" />
1819
<framework:place name="approved_by_journalist" />

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ framework:
99
type: workflow
1010
supports:
1111
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase
12+
definition_validators:
13+
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator
1214
initial_marking: [draft]
1315
metadata:
1416
title: article workflow

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Bridge\PhpUnit\ExpectUserDeprecationMessageTrait;
1717
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
1818
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
19+
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator;
1920
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage;
2021
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
2122
use Symfony\Bundle\FullStack;
@@ -295,6 +296,8 @@ public function testProfilerCollectSerializerDataDefaultDisabled()
295296

296297
public function testWorkflows()
297298
{
299+
DefinitionValidator::$called = false;
300+
298301
$container = $this->createContainerFromFile('workflows');
299302

300303
$this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service');
@@ -318,6 +321,7 @@ public function testWorkflows()
318321
], $tags['workflow'][0]['metadata'] ?? null);
319322

320323
$this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service');
324+
$this->assertTrue(DefinitionValidator::$called, 'DefinitionValidator is called');
321325

322326
$workflowDefinition = $container->getDefinition('workflow.article.definition');
323327

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
+58Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,53 @@ public function testWorkflowValidationStateMachine()
128128
});
129129
}
130130

131+
/**
132+
* @dataProvider provideWorkflowValidationCustomTests
133+
*/
134+
public function testWorkflowValidationCustomBroken(string $class, string $message)
135+
{
136+
$this->expectException(InvalidConfigurationException::class);
137+
$this->expectExceptionMessage($message);
138+
$this->createContainerFromClosure(function ($container) use ($class) {
139+
$container->loadFromExtension('framework', [
140+
'annotations' => false,
141+
'http_method_override' => false,
142+
'handle_all_throwables' => true,
143+
'php_errors' => ['log' => true],
144+
'workflows' => [
145+
'article' => [
146+
'type' => 'state_machine',
147+
'supports' => [
148+
__CLASS__,
149+
],
150+
'places' => [
151+
'a',
152+
'b',
153+
],
154+
'transitions' => [
155+
'a_to_b' => [
156+
'from' => ['a'],
157+
'to' => ['b'],
158+
],
159+
],
160+
'definition_validators' => [
161+
$class,
162+
],
163+
],
164+
],
165+
]);
166+
});
167+
}
168+
169+
public static function provideWorkflowValidationCustomTests()
170+
{
171+
yield ['classDoesNotExist', 'Invalid configuration for path "framework.workflows.workflows.article.definition_validators.0": The validation class "classDoesNotExist" does not exist.'];
172+
173+
yield [\DateTime::class, 'Invalid configuration for path "framework.workflows.workflows.article.definition_validators.0": The validation class "DateTime" is not an instance of Symfony\Component\Workflow\Validator\DefinitionValidatorInterface.'];
174+
175+
yield [WorkflowValidatorWithConstructor::class, 'Invalid configuration for path "framework.workflows.workflows.article.definition_validators.0": The validation class "Symfony\\\\Bundle\\\\FrameworkBundle\\\\Tests\\\\DependencyInjection\\\\WorkflowValidatorWithConstructor" constructor must not have any arguments.'];
176+
}
177+
131178
public function testWorkflowDefaultMarkingStoreDefinition()
132179
{
133180
$container = $this->createContainerFromClosure(function ($container) {
@@ -266,3 +313,14 @@ public function testRateLimiterIsTagged()
266313
$this->assertSame('second', $container->getDefinition('limiter.second')->getTag('rate_limiter')[0]['name']);
267314
}
268315
}
316+
317+
class WorkflowValidatorWithConstructor implements \Symfony\Component\Workflow\Validator\DefinitionValidatorInterface
318+
{
319+
public function __construct(bool $enabled)
320+
{
321+
}
322+
323+
public function validate(\Symfony\Component\Workflow\Definition $definition, string $name): void
324+
{
325+
}
326+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.