Skip to content

Commit 86c1568

Browse files
committed
[Workflow] Add support for executing custom workflow definition validators during the container compilation
1 parent a0721fd commit 86c1568

File tree

9 files changed

+53
-0
lines changed

9 files changed

+53
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ CHANGELOG
1313
* Add `secrets:reveal` command
1414
* Add `rate_limiter` option to `http_client.default_options` and `http_client.scoped_clients`
1515
* Attach the workflow's configuration to the `workflow` tag
16+
* Add support for executing custom workflow definition validators during the
17+
container compilation
1618

1719
7.0
1820
---

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

Lines 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+
->beforeNormalization()
425+
->ifString()
426+
->then(fn ($v) => [$v])
427+
->end()
428+
->prototype('scalar')
429+
->cannotBeEmpty()
430+
->validate()
431+
->ifTrue(fn ($v) => !class_exists($v) && !interface_exists($v, false))
432+
->thenInvalid('The validation class %s does not exist.')
433+
->end()
434+
->validate()
435+
->ifTrue(fn ($v) => !is_a($v, DefinitionValidatorInterface::class, true))
436+
->thenInvalid(sprintf('The validation class %%s is not an instance of %s.', DefinitionValidatorInterface::class))
437+
->end()
438+
->end()
439+
->end()
421440
->scalarNode('support_strategy')
422441
->cannotBeEmpty()
423442
->end()

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,10 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
10531053
$realDefinition = new Workflow\Definition($places, $trs, $initialMarking);
10541054
$validator->validate($realDefinition, $name);
10551055

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@
386386
<xsd:element name="initial-marking" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
387387
<xsd:element name="marking-store" type="marking_store" minOccurs="0" maxOccurs="1" />
388388
<xsd:element name="support" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
389+
<xsd:element name="definition-validator" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
389390
<xsd:element name="event-to-dispatch" type="event_to_dispatch" minOccurs="0" maxOccurs="unbounded" />
390391
<xsd:element name="place" type="place" minOccurs="0" maxOccurs="unbounded" />
391392
<xsd:element name="transition" type="transition" minOccurs="0" maxOccurs="unbounded" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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+
}
17+

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

Lines 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

Lines 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

Lines 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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Psr\Log\LoggerAwareInterface;
1616
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
1717
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
18+
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator;
1819
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage;
1920
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
2021
use Symfony\Bundle\FullStack;
@@ -289,6 +290,8 @@ public function testProfilerCollectSerializerDataDefaultDisabled()
289290

290291
public function testWorkflows()
291292
{
293+
DefinitionValidator::$called = false;
294+
292295
$container = $this->createContainerFromFile('workflows');
293296

294297
$this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service');
@@ -312,6 +315,7 @@ public function testWorkflows()
312315
], $tags['workflow'][0]['metadata'] ?? null);
313316

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

316320
$workflowDefinition = $container->getDefinition('workflow.article.definition');
317321

0 commit comments

Comments
 (0)