diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 772c8fe1ffeb7..aac1d4a9fd42a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -1466,9 +1466,75 @@ function ($a) {
})
->end()
->fixXmlConfig('option')
+ ->validate()
+ ->ifTrue(static fn (array $transportConf) => \count(array_intersect(['serializer', 'incoming_message_serializer', 'outgoing_message_serializer'], array_keys($transportConf))) > 1)
+ ->thenInvalid('Only one of "serializer", "incoming_message_serializer" and "outgoing_message_serializer" could be used.')
+ ->end()
->children()
->scalarNode('dsn')->end()
- ->scalarNode('serializer')->defaultNull()->info('Service id of a custom serializer to use.')->end()
+ ->arrayNode('serializer')
+ ->info('Transport serializer configuration for messages produced and handled by this application.')
+ ->beforeNormalization()
+ ->ifString()
+ ->then(static fn (string $serviceId) => ['service_id' => $serviceId])
+ ->end()
+ ->children()
+ ->scalarNode('service_id')->info('Service id of a custom transport serializer to use (incompatible with "format", "context" and "serializer" options).')->defaultNull()->end()
+ ->scalarNode('format')->info('Serialization format for this transport\'s serializer (will use Symfony serializer).')->end()
+ ->arrayNode('context')
+ ->normalizeKeys(false)
+ ->useAttributeAsKey('name')
+ ->defaultValue([])
+ ->info('Context serialization array for this transport\'s serializer (will use Symfony serializer).')
+ ->prototype('variable')->end()
+ ->end()
+ ->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
+ ->end()
+ ->validate()
+ ->ifTrue(static fn (array $serializerConf) => !(isset($serializerConf['service_id']) xor (isset($serializerConf['format']) || [] !== $serializerConf['context'] || isset($serializerConf['serializer']))))
+ ->thenInvalid('Either "service_id" OR at least one of "format" or "context" or "serializer" should be provided.')
+ ->end()
+ ->end()
+ ->arrayNode('incoming_message_serializer')
+ ->info('Transport serializer configuration for messages coming from other applications (uses Symfony serializer).')
+ ->children()
+ ->scalarNode('messageClass')
+ ->info('The class in which the message should be deserialized (incompatible with "messageClassResolver" option).')
+ ->validate()
+ ->ifTrue(static fn ($class) => $class && !class_exists($class))
+ ->thenInvalid('The "messageClass" should be a valid class.')
+ ->end()
+ ->end()
+ ->scalarNode('messageClassResolver')->info('Service id of a message class resolver to use (incompatible with "messageClass" option).')->end()
+ ->scalarNode('format')->info('Serialization format for this transport\'s serializer.')->end()
+ ->arrayNode('context')
+ ->normalizeKeys(false)
+ ->useAttributeAsKey('name')
+ ->defaultValue([])
+ ->info('Context serialization array for this transport\'s serializer.')
+ ->prototype('variable')->end()
+ ->end()
+ ->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
+ ->end()
+ ->validate()
+ ->ifTrue(static fn (array $incomingMessageConf) => !(isset($incomingMessageConf['messageClass']) xor isset($incomingMessageConf['messageClassResolver'])))
+ ->thenInvalid('A message class OR a message class resolver should be provided.')
+ ->end()
+ ->end()
+ ->arrayNode('outgoing_message_serializer')
+ ->info('Transport serializer configuration for sending messages to other applications (uses Symfony serializer).')
+ ->children()
+ ->scalarNode('format')->info('Serialization format for this transport\'s serializer.')->end()
+ ->arrayNode('context')
+ ->normalizeKeys(false)
+ ->useAttributeAsKey('name')
+ ->defaultValue([])
+ ->info('Context serialization array for this transport\'s serializer.')
+ ->prototype('variable')->end()
+ ->end()
+ ->scalarNode('serializer')->info('Service id of a custom Symfony serializer to use.')->end()
+ ->end()
+ ->end()
->arrayNode('options')
->normalizeKeys(false)
->defaultValue([])
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 358ec36f10bea..01a59bf609f88 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -120,6 +120,9 @@
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Middleware\RouterContextMiddleware;
+use Symfony\Component\Messenger\Transport\Serialization\IncomingMessageSerializer;
+use Symfony\Component\Messenger\Transport\Serialization\OutgoingMessageSerializer;
+use Symfony\Component\Messenger\Transport\Serialization\Serializer;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
use Symfony\Component\Messenger\Transport\TransportFactoryInterface;
use Symfony\Component\Messenger\Transport\TransportInterface;
@@ -2086,7 +2089,47 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
$transportRetryReferences = [];
$transportRateLimiterReferences = [];
foreach ($config['transports'] as $name => $transport) {
- $serializerId = $transport['serializer'] ?? 'messenger.default_serializer';
+ if (isset($transport['serializer'])) {
+ $basicSerializerConf = $transport['serializer'];
+
+ $serializerId = $basicSerializerConf['service_id'] ?? "messenger.transport.{$name}.serializer";
+
+ if (($basicSerializerConf['serializer'] ?? null) || ($basicSerializerConf['format'] ?? null) || [] !== $basicSerializerConf['context']) {
+ $serializerDefinition = (new Definition(Serializer::class))
+ ->setArguments([
+ new Reference($basicSerializerConf['serializer'] ?? 'serializer'),
+ $basicSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
+ $basicSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
+ ]);
+
+ $container->setDefinition($serializerId, $serializerDefinition);
+ }
+ } elseif (isset($transport['incoming_message_serializer'])) {
+ $incomingSerializerConf = $transport['incoming_message_serializer'];
+
+ $serializerDefinition = (new Definition(IncomingMessageSerializer::class))
+ ->setArguments([
+ $incomingSerializerConf['messageClass'] ?? new Reference($incomingSerializerConf['messageClassResolver']),
+ new Reference($incomingSerializerConf['serializer'] ?? 'serializer'),
+ $incomingSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
+ $incomingSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
+ ]);
+
+ $container->setDefinition($serializerId = "messenger.transport.{$name}.serializer", $serializerDefinition);
+ } elseif (isset($transport['outgoing_message_serializer'])) {
+ $outgoingSerializerConf = $transport['outgoing_message_serializer'];
+
+ $serializerDefinition = (new Definition(OutgoingMessageSerializer::class))
+ ->setArguments([
+ new Reference($outgoingSerializerConf['serializer'] ?? 'serializer'),
+ $outgoingSerializerConf['format'] ?? $config['serializer']['symfony_serializer']['format'],
+ $outgoingSerializerConf['context'] ?: $config['serializer']['symfony_serializer']['context'],
+ ]);
+
+ $container->setDefinition($serializerId = "messenger.transport.{$name}.serializer", $serializerDefinition);
+ }
+
+ $serializerId ??= 'messenger.default_serializer';
$transportDefinition = (new Definition(TransportInterface::class))
->setFactory([new Reference('messenger.transport_factory'), 'createTransport'])
->setArguments([$transport['dsn'], $transport['options'] + ['transport_name' => $name], new Reference($serializerId)])
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer.php
new file mode 100644
index 0000000000000..22fd14d394216
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer.php
@@ -0,0 +1,64 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'serializer' => [
+ 'symfony_serializer' => [
+ 'format' => 'xml',
+ 'context' => ['default' => 'context'],
+ ]
+ ],
+ 'transports' => [
+ 'default_serializer' => ['dsn' => 'null://'],
+ 'custom_serializer_short_notation' => [
+ 'dsn' => 'null://',
+ 'serializer' => 'messenger.transport.native_php_serializer',
+ ],
+ 'custom_serializer_long_notation' => [
+ 'dsn' => 'null://',
+ 'serializer' => [
+ 'service_id' => 'messenger.transport.native_php_serializer',
+ ],
+ ],
+ 'symfony_serializer_with_context' => [
+ 'dsn' => 'null://',
+ 'serializer' => [
+ 'format' => 'json',
+ 'context' => ['some' => 'context'],
+ 'serializer' => 'my_fancy_serializer',
+ ],
+ ],
+ 'incoming_message_transport' => [
+ 'dsn' => 'null://',
+ 'incoming_message_serializer' => [
+ 'messageClass' => BarMessage::class,
+ 'format' => 'json',
+ 'context' => ['some' => 'context'],
+ 'serializer' => 'my_fancy_serializer',
+ ],
+ ],
+ 'incoming_message_transport_with_default_serializer' => [
+ 'dsn' => 'null://',
+ 'incoming_message_serializer' => [
+ 'messageClassResolver' => 'some_message_class_resolver_id',
+ ],
+ ],
+ 'outgoing_message_transport' => [
+ 'dsn' => 'null://',
+ 'outgoing_message_serializer' => [
+ 'format' => 'json',
+ 'context' => ['some' => 'context'],
+ 'serializer' => 'my_fancy_serializer',
+ ],
+ ],
+ 'outgoing_message_transport_with_default_serializer' => [
+ 'dsn' => 'null://',
+ 'outgoing_message_serializer' => [],
+ ],
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_1.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_1.php
new file mode 100644
index 0000000000000..869db0f98f26b
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_1.php
@@ -0,0 +1,15 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'transports' => [
+ 'invalid_transport' => [
+ 'dsn' => 'null://',
+ 'serializer' => 'messenger.transport.native_php_serializer',
+ 'outgoing_message_serializer' => []
+ ]
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_2.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_2.php
new file mode 100644
index 0000000000000..b51b50a351c8a
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_2.php
@@ -0,0 +1,17 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'transports' => [
+ 'invalid_transport' => [
+ 'dsn' => 'null://',
+ 'serializer' => [
+ 'service_id' => 'messenger.transport.native_php_serializer',
+ 'format' => 'json'
+ ],
+ ]
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_3.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_3.php
new file mode 100644
index 0000000000000..b4a6a7e16de02
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_3.php
@@ -0,0 +1,14 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'transports' => [
+ 'invalid_transport' => [
+ 'dsn' => 'null://',
+ 'serializer' => [],
+ ]
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_4.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_4.php
new file mode 100644
index 0000000000000..96e5e4d07f531
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_4.php
@@ -0,0 +1,19 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'transports' => [
+ 'invalid_transport' => [
+ 'dsn' => 'null://',
+ 'incoming_message_serializer' => [
+ 'messageClass' => BarMessage::class,
+ 'messageClassResolver' => 'foo',
+ ],
+ ]
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_5.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_5.php
new file mode 100644
index 0000000000000..f46fc375be338
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transport_serializer_invalid_5.php
@@ -0,0 +1,16 @@
+loadFromExtension('framework', [
+ 'http_method_override' => false,
+ 'serializer' => true,
+ 'messenger' => [
+ 'transports' => [
+ 'invalid_transport' => [
+ 'dsn' => 'null://',
+ 'incoming_message_serializer' => [
+ 'messageClass' => 'foo',
+ ],
+ ]
+ ],
+ ],
+]);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_serializer.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_serializer.xml
new file mode 100644
index 0000000000000..cf583ec809485
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transport_serializer.xml
@@ -0,0 +1,62 @@
+
+
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: