diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 146be090225d5..154ae76def0bc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -1005,10 +1005,14 @@ function ($a) {
->arrayNode('middlewares')
->addDefaultsIfNotSet()
->children()
- ->arrayNode('doctrine_transaction')
- ->canBeEnabled()
- ->children()
- ->scalarNode('entity_manager_name')->info('The name of the entity manager to use')->defaultNull()->end()
+ ->arrayNode('doctrine_transaction')
+ ->canBeEnabled()
+ ->children()
+ ->scalarNode('entity_manager_name')->info('The name of the entity manager to use')->defaultNull()->end()
+ ->end()
+ ->end()
+ ->arrayNode('validation')
+ ->{!class_exists(FullStack::class) && class_exists(Validation::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->end()
->end()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index ff7dbeaa5d60b..248ad11eaa890 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -1459,6 +1459,14 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
} else {
$container->removeDefinition('messenger.middleware.doctrine_transaction');
}
+
+ if ($config['middlewares']['validation']['enabled']) {
+ if (!$container->has('validator')) {
+ throw new LogicException('The Validation middleware is only available when the Validator component is installed and enabled. Try running "composer require symfony/validator".');
+ }
+ } else {
+ $container->removeDefinition('messenger.middleware.validator');
+ }
}
private function registerCacheConfiguration(array $config, ContainerBuilder $container)
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
index cbba149b2fb1f..580e2b8f4ae2b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.xml
@@ -25,6 +25,12 @@
+
+
+
+
+
+
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 ab205bd267256..fdf9ec5b0702c 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
@@ -371,6 +371,7 @@
+
@@ -378,4 +379,8 @@
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
index 6fc0ebd1cf8c2..1d96df88a631b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php
@@ -258,6 +258,9 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
'enabled' => false,
'entity_manager_name' => null,
),
+ 'validation' => array(
+ 'enabled' => false,
+ ),
),
),
);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_validation.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_validation.php
new file mode 100644
index 0000000000000..9776e0b5b2abc
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_validation.php
@@ -0,0 +1,11 @@
+loadFromExtension('framework', array(
+ 'messenger' => array(
+ 'middlewares' => array(
+ 'validation' => array(
+ 'enabled' => false,
+ ),
+ ),
+ ),
+));
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_validation.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_validation.xml
new file mode 100644
index 0000000000000..66c104d385965
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_validation.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_validation.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_validation.yml
new file mode 100644
index 0000000000000..276182d2bb3c8
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_validation.yml
@@ -0,0 +1,5 @@
+framework:
+ messenger:
+ middlewares:
+ validation:
+ enabled: false
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 2176afdbcf6f7..2ba8907135b0a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -45,6 +45,7 @@
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass;
+use Symfony\Component\Validator\Validation;
use Symfony\Component\Workflow;
abstract class FrameworkExtensionTest extends TestCase
@@ -532,6 +533,16 @@ public function testMessengerDoctrine()
$this->assertEquals('foobar', $def->getArgument(1));
}
+ public function testMessengerValidationDisabled()
+ {
+ if (!class_exists(Validation::class)) {
+ self::markTestSkipped('Skipping tests since Validator component is not installed');
+ }
+
+ $container = $this->createContainerFromFile('messenger_validation');
+ $this->assertFalse($container->hasDefinition('messenger.middleware.validator'));
+ }
+
public function testTranslator()
{
$container = $this->createContainerFromFile('full');
diff --git a/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php b/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php
new file mode 100644
index 0000000000000..0e06ceaa05ac1
--- /dev/null
+++ b/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php
@@ -0,0 +1,44 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Messenger\Exception;
+
+use Symfony\Component\Validator\ConstraintViolationListInterface;
+
+/**
+ * @author Tobias Nyholm
+ */
+class ValidationFailedException extends \RuntimeException implements ExceptionInterface
+{
+ private $violations;
+ private $violatingMessage;
+
+ /**
+ * @param object $violatingMessage
+ */
+ public function __construct($violatingMessage, ConstraintViolationListInterface $violations)
+ {
+ $this->violatingMessage = $violatingMessage;
+ $this->violations = $violations;
+
+ parent::__construct(sprintf('Message of type "%s" failed validation.', get_class($this->violatingMessage)));
+ }
+
+ public function getViolatingMessage()
+ {
+ return $this->violatingMessage;
+ }
+
+ public function getViolations(): ConstraintViolationListInterface
+ {
+ return $this->violations;
+ }
+}
diff --git a/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php b/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php
new file mode 100644
index 0000000000000..38264a17571ee
--- /dev/null
+++ b/src/Symfony/Component/Messenger/Middleware/ValidationMiddleware.php
@@ -0,0 +1,39 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Messenger\Middleware;
+
+use Symfony\Component\Messenger\Exception\ValidationFailedException;
+use Symfony\Component\Messenger\MiddlewareInterface;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+
+/**
+ * @author Tobias Nyholm
+ */
+class ValidationMiddleware implements MiddlewareInterface
+{
+ private $validator;
+
+ public function __construct(ValidatorInterface $validator)
+ {
+ $this->validator = $validator;
+ }
+
+ public function handle($message, callable $next)
+ {
+ $violations = $this->validator->validate($message);
+ if (count($violations)) {
+ throw new ValidationFailedException($message, $violations);
+ }
+
+ return $next($message);
+ }
+}