diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 56242bf318de7..e2d93d365f986 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1879,6 +1879,10 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $container->removeDefinition('serializer.normalizer.mime_message'); } + if (!class_exists(Translator::class)) { + $container->removeDefinition('serializer.normalizer.translatable'); + } + // compat with Symfony < 6.3 if (!is_subclass_of(ProblemNormalizer::class, SerializerAwareInterface::class)) { $container->getDefinition('serializer.normalizer.problem') diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php index 6459dfa4442bd..ba8d5c6ee2d83 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php @@ -47,6 +47,7 @@ use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Normalizer\ProblemNormalizer; use Symfony\Component\Serializer\Normalizer\PropertyNormalizer; +use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer; use Symfony\Component\Serializer\Normalizer\UidNormalizer; use Symfony\Component\Serializer\Normalizer\UnwrappingDenormalizer; use Symfony\Component\Serializer\Serializer; @@ -113,6 +114,10 @@ ->set('serializer.normalizer.uid', UidNormalizer::class) ->tag('serializer.normalizer', ['priority' => -890]) + ->set('serializer.normalizer.translatable', TranslatableNormalizer::class) + ->args(['$translator' => service('translator')]) + ->tag('serializer.normalizer', ['priority' => -890]) + ->set('serializer.normalizer.form_error', FormErrorNormalizer::class) ->tag('serializer.normalizer', ['priority' => -915]) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 0b34bcd9f7f9f..8aa91a0616a96 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -75,6 +75,7 @@ use Symfony\Component\Serializer\Normalizer\FormErrorNormalizer; use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; +use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer; use Symfony\Component\Serializer\Serializer; use Symfony\Component\Translation\DependencyInjection\TranslatorPass; use Symfony\Component\Translation\LocaleSwitcher; @@ -1586,6 +1587,18 @@ public function testConstraintViolationListNormalizerRegistered() $this->assertEquals(new Reference('serializer.name_converter.metadata_aware'), $definition->getArgument(1)); } + public function testTranslatableNormalizerRegistered() + { + $container = $this->createContainerFromFile('full'); + + $definition = $container->getDefinition('serializer.normalizer.translatable'); + $tag = $definition->getTag('serializer.normalizer'); + + $this->assertSame(TranslatableNormalizer::class, $definition->getClass()); + $this->assertSame(-890, $tag[0]['priority']); + $this->assertEquals(new Reference('translator'), $definition->getArgument('$translator')); + } + public function testSerializerCacheActivated() { $container = $this->createContainerFromFile('serializer_enabled'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php index 0793769a1a506..630bfb7cd3004 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php @@ -60,6 +60,7 @@ public static function provideNormalizersAndEncodersWithDefaultContextOption(): ['serializer.normalizer.json_serializable.alias'], ['serializer.normalizer.problem.alias'], ['serializer.normalizer.uid.alias'], + ['serializer.normalizer.translatable.alias'], ['serializer.normalizer.object.alias'], ['serializer.encoder.xml.alias'], ['serializer.encoder.yaml.alias'], diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml index e51b738580255..016e41291fdbb 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml @@ -39,6 +39,10 @@ services: alias: serializer.normalizer.uid public: true + serializer.normalizer.translatable.alias: + alias: serializer.normalizer.translatable + public: true + serializer.normalizer.property.alias: alias: serializer.normalizer.property public: true diff --git a/src/Symfony/Component/Serializer/Normalizer/TranslatableNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/TranslatableNormalizer.php new file mode 100644 index 0000000000000..b79a0ffb99488 --- /dev/null +++ b/src/Symfony/Component/Serializer/Normalizer/TranslatableNormalizer.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Normalizer; + +use Symfony\Component\Serializer\Exception\InvalidArgumentException; +use Symfony\Contracts\Translation\TranslatableInterface; +use Symfony\Contracts\Translation\TranslatorInterface; + +final class TranslatableNormalizer implements NormalizerInterface +{ + public const NORMALIZATION_LOCALE_KEY = 'translatable_normalization_locale'; + + private array $defaultContext = [ + self::NORMALIZATION_LOCALE_KEY => null, + ]; + + public function __construct( + private readonly TranslatorInterface $translator, + array $defaultContext = [], + ) { + $this->defaultContext = array_merge($this->defaultContext, $defaultContext); + } + + /** + * @throws InvalidArgumentException + */ + public function normalize(mixed $object, string $format = null, array $context = []): string + { + if (!$object instanceof TranslatableInterface) { + throw new InvalidArgumentException(sprintf('The object must implement the "%s".', TranslatableInterface::class)); + } + + return $object->trans($this->translator, $context[self::NORMALIZATION_LOCALE_KEY] ?? $this->defaultContext[self::NORMALIZATION_LOCALE_KEY]); + } + + public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool + { + return $data instanceof TranslatableInterface; + } + + public function getSupportedTypes(?string $format): array + { + return [TranslatableInterface::class => true]; + } +} diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/TranslatableNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/TranslatableNormalizerTest.php new file mode 100644 index 0000000000000..54338b07e55be --- /dev/null +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/TranslatableNormalizerTest.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Normalizer; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer; +use Symfony\Contracts\Translation\TranslatableInterface; +use Symfony\Contracts\Translation\TranslatorInterface; + +class TranslatableNormalizerTest extends TestCase +{ + private readonly TranslatableNormalizer $normalizer; + + protected function setUp(): void + { + $this->normalizer = new TranslatableNormalizer($this->createMock(TranslatorInterface::class)); + } + + public function testSupportsNormalization() + { + $this->assertTrue($this->normalizer->supportsNormalization(new TestMessage())); + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + public function testNormalize() + { + $message = new TestMessage(); + + $this->assertSame('key_null', $this->normalizer->normalize($message)); + $this->assertSame('key_fr', $this->normalizer->normalize($message, context: ['translatable_normalization_locale' => 'fr'])); + $this->assertSame('key_en', $this->normalizer->normalize($message, context: ['translatable_normalization_locale' => 'en'])); + } + + public function testNormalizeWithNormalizationLocalePassedInConstructor() + { + $normalizer = new TranslatableNormalizer( + $this->createMock(TranslatorInterface::class), + ['translatable_normalization_locale' => 'es'], + ); + $message = new TestMessage(); + + $this->assertSame('key_es', $normalizer->normalize($message)); + $this->assertSame('key_fr', $normalizer->normalize($message, context: ['translatable_normalization_locale' => 'fr'])); + $this->assertSame('key_en', $normalizer->normalize($message, context: ['translatable_normalization_locale' => 'en'])); + } +} + +class TestMessage implements TranslatableInterface +{ + public function trans(TranslatorInterface $translator, string $locale = null): string + { + return 'key_'.($locale ?? 'null'); + } +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy