Skip to content

Commit 4f15638

Browse files
committed
[Serializer][FrameworkBundle] Add TranslatableNormalizer
1 parent 65af407 commit 4f15638

File tree

6 files changed

+143
-0
lines changed

6 files changed

+143
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
4848
use Symfony\Component\Serializer\Normalizer\ProblemNormalizer;
4949
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
50+
use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer;
5051
use Symfony\Component\Serializer\Normalizer\UidNormalizer;
5152
use Symfony\Component\Serializer\Normalizer\UnwrappingDenormalizer;
5253
use Symfony\Component\Serializer\Serializer;
@@ -113,6 +114,10 @@
113114
->set('serializer.normalizer.uid', UidNormalizer::class)
114115
->tag('serializer.normalizer', ['priority' => -890])
115116

117+
->set('serializer.normalizer.translatable', TranslatableNormalizer::class)
118+
->args([1 => service('translator')->nullOnInvalid()])
119+
->tag('serializer.normalizer', ['priority' => -890])
120+
116121
->set('serializer.normalizer.form_error', FormErrorNormalizer::class)
117122
->tag('serializer.normalizer', ['priority' => -915])
118123

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
use Symfony\Component\Serializer\Normalizer\FormErrorNormalizer;
7777
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
7878
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
79+
use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer;
7980
use Symfony\Component\Serializer\Serializer;
8081
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
8182
use Symfony\Component\Translation\LocaleSwitcher;
@@ -1557,6 +1558,18 @@ public function testConstraintViolationListNormalizerRegistered()
15571558
$this->assertEquals(new Reference('serializer.name_converter.metadata_aware'), $definition->getArgument(1));
15581559
}
15591560

1561+
public function testTranslatableNormalizerRegistered()
1562+
{
1563+
$container = $this->createContainerFromFile('full');
1564+
1565+
$definition = $container->getDefinition('serializer.normalizer.translatable');
1566+
$tag = $definition->getTag('serializer.normalizer');
1567+
1568+
$this->assertEquals(TranslatableNormalizer::class, $definition->getClass());
1569+
$this->assertEquals(-890, $tag[0]['priority']);
1570+
$this->assertEquals(new Reference('translator', ContainerInterface::NULL_ON_INVALID_REFERENCE), $definition->getArgument(1));
1571+
}
1572+
15601573
public function testSerializerCacheActivated()
15611574
{
15621575
$container = $this->createContainerFromFile('serializer_enabled');

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/SerializerTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public static function provideNormalizersAndEncodersWithDefaultContextOption():
6161
['serializer.normalizer.json_serializable.alias'],
6262
['serializer.normalizer.problem.alias'],
6363
['serializer.normalizer.uid.alias'],
64+
['serializer.normalizer.translatable.alias'],
6465
['serializer.normalizer.object.alias'],
6566
['serializer.encoder.xml.alias'],
6667
['serializer.encoder.yaml.alias'],

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Serializer/config.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ services:
3939
alias: serializer.normalizer.uid
4040
public: true
4141

42+
serializer.normalizer.translatable.alias:
43+
alias: serializer.normalizer.translatable
44+
public: true
45+
4246
serializer.normalizer.property.alias:
4347
alias: serializer.normalizer.property
4448
public: true
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Normalizer;
13+
14+
use Symfony\Contracts\Translation\TranslatableInterface;
15+
use Symfony\Contracts\Translation\TranslatorInterface;
16+
17+
final class TranslatableNormalizer implements NormalizerInterface
18+
{
19+
public const NORMALIZATION_LOCALE_KEY = 'translatable_normalization_locale';
20+
21+
private array $defaultContext = [
22+
self::NORMALIZATION_LOCALE_KEY => null,
23+
];
24+
25+
public function __construct(
26+
array $defaultContext = [],
27+
private readonly ?TranslatorInterface $translator = null,
28+
) {
29+
$this->defaultContext = array_merge($this->defaultContext, $defaultContext);
30+
}
31+
32+
/**
33+
* @param TranslatableInterface $object
34+
*/
35+
public function normalize(mixed $object, string $format = null, array $context = []): string
36+
{
37+
return $object->trans($this->translator, $context[self::NORMALIZATION_LOCALE_KEY] ?? $this->defaultContext[self::NORMALIZATION_LOCALE_KEY]);
38+
}
39+
40+
public function supportsNormalization(mixed $data, string $format = null, array $context = []): bool
41+
{
42+
return null !== $this->translator && $data instanceof TranslatableInterface;
43+
}
44+
45+
public function getSupportedTypes(?string $format): array
46+
{
47+
return [TranslatableInterface::class => true];
48+
}
49+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Normalizer;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Serializer\Normalizer\TranslatableNormalizer;
16+
use Symfony\Contracts\Translation\TranslatableInterface;
17+
use Symfony\Contracts\Translation\TranslatorInterface;
18+
19+
class TranslatableNormalizerTest extends TestCase
20+
{
21+
private readonly TranslatableNormalizer $normalizer;
22+
23+
protected function setUp(): void
24+
{
25+
$this->normalizer = new TranslatableNormalizer([], $this->createMock(TranslatorInterface::class));
26+
}
27+
28+
public function testSupportsNormalization()
29+
{
30+
$this->assertTrue($this->normalizer->supportsNormalization(new TestMessage()));
31+
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
32+
}
33+
34+
public function testSupportsNormalizationWithoutTranslator()
35+
{
36+
$normalizer = new TranslatableNormalizer();
37+
38+
$this->assertFalse($normalizer->supportsNormalization(new TestMessage()));
39+
$this->assertFalse($normalizer->supportsNormalization(new \stdClass()));
40+
}
41+
42+
public function testNormalize()
43+
{
44+
$message = new TestMessage();
45+
46+
$this->assertSame('key_null', $this->normalizer->normalize($message));
47+
$this->assertSame('key_fr', $this->normalizer->normalize($message, context: ['translatable_normalization_locale' => 'fr']));
48+
$this->assertSame('key_en', $this->normalizer->normalize($message, context: ['translatable_normalization_locale' => 'en']));
49+
}
50+
51+
public function testNormalizeWithNormalizationLocalePassedInConstructor()
52+
{
53+
$normalizer = new TranslatableNormalizer(
54+
['translatable_normalization_locale' => 'es'],
55+
$this->createMock(TranslatorInterface::class),
56+
);
57+
$message = new TestMessage();
58+
59+
$this->assertSame('key_es', $normalizer->normalize($message));
60+
$this->assertSame('key_fr', $normalizer->normalize($message, context: ['translatable_normalization_locale' => 'fr']));
61+
$this->assertSame('key_en', $normalizer->normalize($message, context: ['translatable_normalization_locale' => 'en']));
62+
}
63+
}
64+
65+
class TestMessage implements TranslatableInterface
66+
{
67+
public function trans(TranslatorInterface $translator, string $locale = null): string
68+
{
69+
return 'key_'.($locale ?? 'null');
70+
}
71+
}

0 commit comments

Comments
 (0)
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