Skip to content

Commit cb5139b

Browse files
Jean-Berufabpot
authored andcommitted
[Translation] Allow default parameters
1 parent 01fe898 commit cb5139b

File tree

7 files changed

+128
-1
lines changed

7 files changed

+128
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
7+
* Add `Translator::addGlobalParameter()` to allow defining global translation parameters
8+
49
7.2
510
---
611

DataCollector/TranslationDataCollector.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep
4444
{
4545
$this->data['locale'] = $this->translator->getLocale();
4646
$this->data['fallback_locales'] = $this->translator->getFallbackLocales();
47+
$this->data['global_parameters'] = $this->translator->getGlobalParameters();
4748
}
4849

4950
public function reset(): void
@@ -84,6 +85,14 @@ public function getFallbackLocales(): Data|array
8485
return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : [];
8586
}
8687

88+
/**
89+
* @internal
90+
*/
91+
public function getGlobalParameters(): Data|array
92+
{
93+
return $this->data['global_parameters'] ?? [];
94+
}
95+
8796
public function getName(): string
8897
{
8998
return 'translation';

DataCollectorTranslator.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ public function getFallbackLocales(): array
8282
return [];
8383
}
8484

85+
public function getGlobalParameters(): array
86+
{
87+
if ($this->translator instanceof Translator || method_exists($this->translator, 'getGlobalParameters')) {
88+
return $this->translator->getGlobalParameters();
89+
}
90+
91+
return [];
92+
}
93+
8594
public function __call(string $method, array $args): mixed
8695
{
8796
return $this->translator->{$method}(...$args);

Tests/DataCollector/TranslationDataCollectorTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,20 @@ public function testCollectAndReset()
137137
$translator = $this->getTranslator();
138138
$translator->method('getLocale')->willReturn('fr');
139139
$translator->method('getFallbackLocales')->willReturn(['en']);
140+
$translator->method('getGlobalParameters')->willReturn(['welcome' => 'Welcome {name}!']);
140141

141142
$dataCollector = new TranslationDataCollector($translator);
142143
$dataCollector->collect($this->createMock(Request::class), $this->createMock(Response::class));
143144

144145
$this->assertSame('fr', $dataCollector->getLocale());
145146
$this->assertSame(['en'], $dataCollector->getFallbackLocales());
147+
$this->assertSame(['welcome' => 'Welcome {name}!'], $dataCollector->getGlobalParameters());
146148

147149
$dataCollector->reset();
148150

149151
$this->assertNull($dataCollector->getLocale());
150152
$this->assertSame([], $dataCollector->getFallbackLocales());
153+
$this->assertSame([], $dataCollector->getGlobalParameters());
151154
}
152155

153156
private function getTranslator()

Tests/DataCollectorTranslatorTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Translation\DataCollectorTranslator;
1616
use Symfony\Component\Translation\Loader\ArrayLoader;
17+
use Symfony\Component\Translation\TranslatableMessage;
1718
use Symfony\Component\Translation\Translator;
1819

1920
class DataCollectorTranslatorTest extends TestCase
@@ -84,6 +85,18 @@ public function testCollectMessages()
8485
$this->assertEquals($expectedMessages, $collector->getCollectedMessages());
8586
}
8687

88+
public function testGetGlobalParameters()
89+
{
90+
$translatable = new TranslatableMessage('url.front');
91+
92+
$translator = new Translator('en');
93+
$translator->addGlobalParameter('app', 'My app');
94+
$translator->addGlobalParameter('url', $translatable);
95+
$collector = new DataCollectorTranslator($translator);
96+
97+
$this->assertEquals(['app' => 'My app', 'url' => $translatable], $collector->getGlobalParameters());
98+
}
99+
87100
private function createCollector()
88101
{
89102
$translator = new Translator('en');

Tests/TranslatorTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,56 @@ public function testMissingLoaderForResourceError()
602602

603603
$translator->getCatalogue('en');
604604
}
605+
606+
public function testTransWithGlobalParameters()
607+
{
608+
$translator = new Translator('en');
609+
$translator->addLoader('array', new ArrayLoader());
610+
$translator->addResource('array', ['welcome' => 'Welcome {name}!'], 'en');
611+
$translator->addResource('array', ['welcome' => 'Bienvenue {name}!'], 'fr');
612+
$translator->addGlobalParameter('{name}', 'Global name');
613+
614+
$this->assertSame('Welcome Global name!', $translator->trans('welcome'));
615+
$this->assertSame('Bienvenue Global name!', $translator->trans('welcome', [], null, 'fr'));
616+
$this->assertSame('Welcome John!', $translator->trans('welcome', ['{name}' => 'John']));
617+
$this->assertSame('Bienvenue Jean!', $translator->trans('welcome', ['{name}' => 'Jean'], null, 'fr'));
618+
}
619+
620+
public function testTransWithGlobalTranslatableParameters()
621+
{
622+
$translator = new Translator('en');
623+
$translator->addLoader('array', new ArrayLoader());
624+
$translator->addResource('array', ['welcome' => 'Welcome on {link}!'], 'en');
625+
$translator->addResource('array', ['welcome' => 'Bienvenue sur {link}!'], 'fr');
626+
627+
$translator->addResource('array', ['url' => 'example.com/admin'], 'en', 'globals');
628+
$translator->addResource('array', ['url' => 'example.fr/admin'], 'fr', 'globals');
629+
630+
$translator->addGlobalParameter('{link}', new TranslatableMessage('url', [], 'globals'));
631+
632+
$this->assertSame('Welcome on example.com/admin!', $translator->trans('welcome'));
633+
$this->assertSame('Bienvenue sur example.fr/admin!', $translator->trans('welcome', [], null, 'fr'));
634+
$this->assertSame('Welcome on other.com!', $translator->trans('welcome', ['{link}' => 'other.com']));
635+
$this->assertSame('Bienvenue sur autre.fr!', $translator->trans('welcome', ['{link}' => 'autre.fr'], null, 'fr'));
636+
}
637+
638+
/**
639+
* @requires extension intl
640+
*/
641+
public function testTransICUWithGlobalParameters()
642+
{
643+
$domain = 'test.'.MessageCatalogue::INTL_DOMAIN_SUFFIX;
644+
645+
$translator = new Translator('en');
646+
$translator->addLoader('array', new ArrayLoader());
647+
$translator->addResource('array', [
648+
'apples' => '{apples, plural, =0 {There are no apples} one {There is one apple} other {There are # apples}}',
649+
], 'en', $domain);
650+
$translator->addGlobalParameter('{apples}', 42);
651+
652+
$this->assertSame('There are 42 apples', $translator->trans('apples', [], $domain));
653+
$this->assertSame('There is one apple', $translator->trans('apples', ['{apples}' => 1], $domain));
654+
}
605655
}
606656

607657
class StringClass

Translator.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA
6060

6161
private bool $hasIntlFormatter;
6262

63+
/**
64+
* @var array<string, string|int|float|TranslatableInterface>
65+
*/
66+
private array $globalParameters = [];
67+
68+
/**
69+
* @var array<string, string|int|float>
70+
*/
71+
private array $globalTranslatedParameters = [];
72+
6373
/**
6474
* @throws InvalidArgumentException If a locale contains invalid characters
6575
*/
@@ -155,6 +165,17 @@ public function getFallbackLocales(): array
155165
return $this->fallbackLocales;
156166
}
157167

168+
public function addGlobalParameter(string $id, string|int|float|TranslatableInterface $value): void
169+
{
170+
$this->globalParameters[$id] = $value;
171+
$this->globalTranslatedParameters = [];
172+
}
173+
174+
public function getGlobalParameters(): array
175+
{
176+
return $this->globalParameters;
177+
}
178+
158179
public function trans(?string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string
159180
{
160181
if (null === $id || '' === $id) {
@@ -174,7 +195,24 @@ public function trans(?string $id, array $parameters = [], ?string $domain = nul
174195
}
175196
}
176197

177-
$parameters = array_map(fn ($parameter) => $parameter instanceof TranslatableInterface ? $parameter->trans($this, $locale) : $parameter, $parameters);
198+
foreach ($parameters as $key => $value) {
199+
if ($value instanceof TranslatableInterface) {
200+
$parameters[$key] = $value->trans($this, $locale);
201+
}
202+
}
203+
204+
if (null === $globalParameters =& $this->globalTranslatedParameters[$locale]) {
205+
$globalParameters = $this->globalParameters;
206+
foreach ($globalParameters as $key => $value) {
207+
if ($value instanceof TranslatableInterface) {
208+
$globalParameters[$key] = $value->trans($this, $locale);
209+
}
210+
}
211+
}
212+
213+
if ($globalParameters) {
214+
$parameters += $globalParameters;
215+
}
178216

179217
$len = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX);
180218
if ($this->hasIntlFormatter

0 commit comments

Comments
 (0)