diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
index 52624c2cd173..b17af2960dda 100644
--- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
@@ -13,6 +13,8 @@ CHANGELOG
* Add `secrets:reveal` command
* Add `rate_limiter` option to `http_client.default_options` and `http_client.scoped_clients`
* Attach the workflow's configuration to the `workflow` tag
+ * Add support for executing custom workflow definition validators during the
+ container compilation
7.0
---
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 1d15c93611f7..003c74172731 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -49,6 +49,7 @@
use Symfony\Component\Validator\Validation;
use Symfony\Component\Webhook\Controller\WebhookController;
use Symfony\Component\WebLink\HttpHeaderSerializer;
+use Symfony\Component\Workflow\Validator\DefinitionValidatorInterface;
use Symfony\Component\Workflow\WorkflowEvents;
/**
@@ -381,6 +382,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
->useAttributeAsKey('name')
->prototype('array')
->fixXmlConfig('support')
+ ->fixXmlConfig('definition_validator')
->fixXmlConfig('place')
->fixXmlConfig('transition')
->fixXmlConfig('event_to_dispatch', 'events_to_dispatch')
@@ -418,6 +420,23 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void
->end()
->end()
->end()
+ ->arrayNode('definition_validators')
+ ->beforeNormalization()
+ ->ifString()
+ ->then(fn ($v) => [$v])
+ ->end()
+ ->prototype('scalar')
+ ->cannotBeEmpty()
+ ->validate()
+ ->ifTrue(fn ($v) => !class_exists($v) && !interface_exists($v, false))
+ ->thenInvalid('The validation class %s does not exist.')
+ ->end()
+ ->validate()
+ ->ifTrue(fn ($v) => !is_a($v, DefinitionValidatorInterface::class, true))
+ ->thenInvalid(sprintf('The validation class %%s is not an instance of %s.', DefinitionValidatorInterface::class))
+ ->end()
+ ->end()
+ ->end()
->scalarNode('support_strategy')
->cannotBeEmpty()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 7a52d9f9bf8a..90c898291d1c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1053,6 +1053,10 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
$realDefinition = new Workflow\Definition($places, $trs, $initialMarking);
$validator->validate($realDefinition, $name);
+ foreach ($workflow['definition_validators'] as $validatorClass) {
+ (new $validatorClass())->validate($realDefinition, $name);
+ }
+
// Add workflow to Registry
if ($workflow['supports']) {
foreach ($workflow['supports'] as $supportedClassName) {
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 f1169e630caf..5fa8cc4abcb4 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
@@ -386,6 +386,7 @@
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/Workflow/Validator/DefinitionValidator.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/Workflow/Validator/DefinitionValidator.php
new file mode 100644
index 000000000000..29fd60ef3e43
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/Workflow/Validator/DefinitionValidator.php
@@ -0,0 +1,17 @@
+ [
FrameworkExtensionTestCase::class,
],
+ 'definition_validators' => [
+ Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator::class,
+ ],
'initial_marking' => ['draft'],
'metadata' => [
'title' => 'article workflow',
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
index 76b4f07a87a4..c5dae479d3d6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/workflows.xml
@@ -13,6 +13,7 @@
draft
Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase
+ Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
index a9b427d89408..cac5f6f230f9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/workflows.yml
@@ -9,6 +9,8 @@ framework:
type: workflow
supports:
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTestCase
+ definition_validators:
+ - Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator
initial_marking: [draft]
metadata:
title: article workflow
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
index c73197607900..216f0131e37f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php
@@ -15,6 +15,7 @@
use Psr\Log\LoggerAwareInterface;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
+use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Fixtures\Workflow\Validator\DefinitionValidator;
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Bundle\FullStack;
@@ -289,6 +290,8 @@ public function testProfilerCollectSerializerDataDefaultDisabled()
public function testWorkflows()
{
+ DefinitionValidator::$called = false;
+
$container = $this->createContainerFromFile('workflows');
$this->assertTrue($container->hasDefinition('workflow.article'), 'Workflow is registered as a service');
@@ -312,6 +315,7 @@ public function testWorkflows()
], $tags['workflow'][0]['metadata'] ?? null);
$this->assertTrue($container->hasDefinition('workflow.article.definition'), 'Workflow definition is registered as a service');
+ $this->assertTrue(DefinitionValidator::$called, 'DefinitionValidator is called');
$workflowDefinition = $container->getDefinition('workflow.article.definition');