From 652c658e5873de3273ea92bb2cd3ec84f1c403b0 Mon Sep 17 00:00:00 2001 From: "hubert.lenoir" Date: Fri, 29 Dec 2023 10:09:04 +0100 Subject: [PATCH] [Translation] Allow default parameters --- .../DependencyInjection/Configuration.php | 28 +++++++++++ .../FrameworkExtension.php | 5 ++ .../Resources/config/schema/symfony-1.0.xsd | 19 +++++++ .../DependencyInjection/ConfigurationTest.php | 1 + .../Fixtures/php/translator_globals.php | 15 ++++++ .../php/translator_without_globals.php | 9 ++++ .../Fixtures/xml/translator_globals.xml | 20 ++++++++ .../xml/translator_without_globals.xml | 14 ++++++ .../Fixtures/yml/translator_globals.yml | 11 ++++ .../yml/translator_without_globals.yml | 8 +++ .../FrameworkExtensionTestCase.php | 31 ++++++++++++ .../Bundle/FrameworkBundle/composer.json | 4 +- .../views/Collector/translation.html.twig | 21 ++++++++ .../Component/Translation/CHANGELOG.md | 5 ++ .../TranslationDataCollector.php | 9 ++++ .../Translation/DataCollectorTranslator.php | 9 ++++ .../TranslationDataCollectorTest.php | 3 ++ .../Tests/DataCollectorTranslatorTest.php | 13 +++++ .../Translation/Tests/TranslatorTest.php | 50 +++++++++++++++++++ .../Component/Translation/Translator.php | 40 ++++++++++++++- 20 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_globals.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_without_globals.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_globals.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_without_globals.xml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_globals.yml create mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_without_globals.yml diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index fd77de26e6bc6..17b4a438b2aec 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -967,6 +967,7 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e ->fixXmlConfig('fallback') ->fixXmlConfig('path') ->fixXmlConfig('provider') + ->fixXmlConfig('global') ->children() ->arrayNode('fallbacks') ->info('Defaults to the value of "default_locale".') @@ -1021,6 +1022,33 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode, callable $e ->end() ->defaultValue([]) ->end() + ->arrayNode('globals') + ->info('Global parameters.') + ->example(['app_version' => 3.14]) + ->normalizeKeys(false) + ->useAttributeAsKey('name') + ->arrayPrototype() + ->fixXmlConfig('parameter') + ->children() + ->variableNode('value')->end() + ->stringNode('message')->end() + ->arrayNode('parameters') + ->normalizeKeys(false) + ->useAttributeAsKey('name') + ->scalarPrototype()->end() + ->end() + ->stringNode('domain')->end() + ->end() + ->beforeNormalization() + ->ifTrue(static fn ($v) => !\is_array($v)) + ->then(static fn ($v) => ['value' => $v]) + ->end() + ->validate() + ->ifTrue(static fn ($v) => !(isset($v['value']) xor isset($v['message']))) + ->thenInvalid('The "globals" parameter should be either a string or an array with a "value" or a "message" key') + ->end() + ->end() + ->end() ->end() ->end() ->end() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 418ee739c6863..fdcae2a344981 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -185,6 +185,7 @@ use Symfony\Component\Translation\Extractor\PhpAstExtractor; use Symfony\Component\Translation\LocaleSwitcher; use Symfony\Component\Translation\PseudoLocalizationTranslator; +use Symfony\Component\Translation\TranslatableMessage; use Symfony\Component\Translation\Translator; use Symfony\Component\TypeInfo\Type; use Symfony\Component\TypeInfo\TypeResolver\PhpDocAwareReflectionTypeResolver; @@ -1614,6 +1615,10 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $translator->replaceArgument(4, $options); } + foreach ($config['globals'] as $name => $global) { + $translator->addMethodCall('addGlobalParameter', [$name, $global['value'] ?? new Definition(TranslatableMessage::class, [$global['message'], $global['parameters'] ?? [], $global['domain'] ?? null])]); + } + if ($config['pseudo_localization']['enabled']) { $options = $config['pseudo_localization']; unset($options['enabled']); 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 ae69a5aa9a66c..8661384e2d5b8 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 @@ -256,6 +256,7 @@ + @@ -285,6 +286,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index e4ec77451724b..babfb2eab0b5b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -785,6 +785,7 @@ protected static function getBundleDefaultConfig() 'localizable_html_attributes' => [], ], 'providers' => [], + 'globals' => [], ], 'validation' => [ 'enabled' => !class_exists(FullStack::class), diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_globals.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_globals.php new file mode 100644 index 0000000000000..8ee438ff906d1 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_globals.php @@ -0,0 +1,15 @@ +loadFromExtension('framework', [ + 'annotations' => false, + 'http_method_override' => false, + 'handle_all_throwables' => true, + 'php_errors' => ['log' => true], + 'translator' => [ + 'globals' => [ + '%%app_name%%' => 'My application', + '{app_version}' => '1.2.3', + '{url}' => ['message' => 'url', 'parameters' => ['scheme' => 'https://'], 'domain' => 'global'], + ], + ], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_without_globals.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_without_globals.php new file mode 100644 index 0000000000000..fcc65c9682650 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/translator_without_globals.php @@ -0,0 +1,9 @@ +loadFromExtension('framework', [ + 'annotations' => false, + 'http_method_override' => false, + 'handle_all_throwables' => true, + 'php_errors' => ['log' => true], + 'translator' => ['globals' => []], +]); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_globals.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_globals.xml new file mode 100644 index 0000000000000..017fd9393b85c --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_globals.xml @@ -0,0 +1,20 @@ + + + + + + + + + My application + + + https:// + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_without_globals.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_without_globals.xml new file mode 100644 index 0000000000000..6c686bd30b210 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/translator_without_globals.xml @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_globals.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_globals.yml new file mode 100644 index 0000000000000..ed42b676c8fd5 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_globals.yml @@ -0,0 +1,11 @@ +framework: + annotations: false + http_method_override: false + handle_all_throwables: true + php_errors: + log: true + translator: + globals: + '%%app_name%%': 'My application' + '{app_version}': '1.2.3' + '{url}': { message: 'url', parameters: { scheme: 'https://' }, domain: 'global' } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_without_globals.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_without_globals.yml new file mode 100644 index 0000000000000..dc7323868d762 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/translator_without_globals.yml @@ -0,0 +1,8 @@ +framework: + annotations: false + http_method_override: false + handle_all_throwables: true + php_errors: + log: true + translator: + globals: [] diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php index 3a719b8634b77..fdc586cc922ba 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTestCase.php @@ -83,6 +83,7 @@ use Symfony\Component\Serializer\Serializer; use Symfony\Component\Translation\DependencyInjection\TranslatorPass; use Symfony\Component\Translation\LocaleSwitcher; +use Symfony\Component\Translation\TranslatableMessage; use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass; use Symfony\Component\Validator\Validation; use Symfony\Component\Validator\Validator\ValidatorInterface; @@ -1241,6 +1242,36 @@ public function testTranslatorCacheDirDisabled() $this->assertNull($options['cache_dir']); } + public function testTranslatorGlobals() + { + $container = $this->createContainerFromFile('translator_globals'); + + $calls = $container->getDefinition('translator.default')->getMethodCalls(); + + $this->assertCount(5, $calls); + $this->assertSame( + ['addGlobalParameter', ['%%app_name%%', 'My application']], + $calls[2], + ); + $this->assertSame( + ['addGlobalParameter', ['{app_version}', '1.2.3']], + $calls[3], + ); + $this->assertEquals( + ['addGlobalParameter', ['{url}', new Definition(TranslatableMessage::class, ['url', ['scheme' => 'https://'], 'global'])]], + $calls[4], + ); + } + + public function testTranslatorWithoutGlobals() + { + $container = $this->createContainerFromFile('translator_without_globals'); + + $calls = $container->getDefinition('translator.default')->getMethodCalls(); + + $this->assertCount(2, $calls); + } + public function testValidation() { $container = $this->createContainerFromFile('full'); diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index 999dd7fedcdb7..72d33ed884df2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -62,7 +62,7 @@ "symfony/serializer": "^7.1", "symfony/stopwatch": "^6.4|^7.0", "symfony/string": "^6.4|^7.0", - "symfony/translation": "^6.4.3|^7.0", + "symfony/translation": "^7.3", "symfony/twig-bundle": "^6.4|^7.0", "symfony/type-info": "^7.1", "symfony/validator": "^6.4|^7.0", @@ -101,7 +101,7 @@ "symfony/security-core": "<6.4", "symfony/serializer": "<7.1", "symfony/stopwatch": "<6.4", - "symfony/translation": "<6.4.3", + "symfony/translation": "<7.3", "symfony/twig-bridge": "<6.4", "symfony/twig-bundle": "<6.4", "symfony/validator": "<6.4", diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig index eeb8a06a88dee..53560cf306713 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/translation.html.twig @@ -156,6 +156,27 @@ {% endblock messages %} {% endif %} + {% if collector.globalParameters|default([]) %} +

Global parameters

+ + + + + + + + + + {% for id, value in collector.globalParameters %} + + + + + {% endfor %} + +
Message IDValue
{{ id }}{{ profiler_dump(value) }}
+ {% endif %} + {% endblock %} {% macro render_table(messages, is_fallback) %} diff --git a/src/Symfony/Component/Translation/CHANGELOG.md b/src/Symfony/Component/Translation/CHANGELOG.md index 622c7f75dd04a..365c5cf1cdc7e 100644 --- a/src/Symfony/Component/Translation/CHANGELOG.md +++ b/src/Symfony/Component/Translation/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.3 +--- + + * Add `Translator::addGlobalParameter()` to allow defining global translation parameters + 7.2 --- diff --git a/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php b/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php index e6bd619db5f02..e2e597a705e86 100644 --- a/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php +++ b/src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php @@ -44,6 +44,7 @@ public function collect(Request $request, Response $response, ?\Throwable $excep { $this->data['locale'] = $this->translator->getLocale(); $this->data['fallback_locales'] = $this->translator->getFallbackLocales(); + $this->data['global_parameters'] = $this->translator->getGlobalParameters(); } public function reset(): void @@ -84,6 +85,14 @@ public function getFallbackLocales(): Data|array return (isset($this->data['fallback_locales']) && \count($this->data['fallback_locales']) > 0) ? $this->data['fallback_locales'] : []; } + /** + * @internal + */ + public function getGlobalParameters(): Data|array + { + return $this->data['global_parameters'] ?? []; + } + public function getName(): string { return 'translation'; diff --git a/src/Symfony/Component/Translation/DataCollectorTranslator.php b/src/Symfony/Component/Translation/DataCollectorTranslator.php index dcabedeb85333..c85318f772c6d 100644 --- a/src/Symfony/Component/Translation/DataCollectorTranslator.php +++ b/src/Symfony/Component/Translation/DataCollectorTranslator.php @@ -82,6 +82,15 @@ public function getFallbackLocales(): array return []; } + public function getGlobalParameters(): array + { + if ($this->translator instanceof Translator || method_exists($this->translator, 'getGlobalParameters')) { + return $this->translator->getGlobalParameters(); + } + + return []; + } + public function __call(string $method, array $args): mixed { return $this->translator->{$method}(...$args); diff --git a/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php b/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php index 149ccacdc717f..64af1284c21e8 100644 --- a/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php +++ b/src/Symfony/Component/Translation/Tests/DataCollector/TranslationDataCollectorTest.php @@ -137,17 +137,20 @@ public function testCollectAndReset() $translator = $this->getTranslator(); $translator->method('getLocale')->willReturn('fr'); $translator->method('getFallbackLocales')->willReturn(['en']); + $translator->method('getGlobalParameters')->willReturn(['welcome' => 'Welcome {name}!']); $dataCollector = new TranslationDataCollector($translator); $dataCollector->collect($this->createMock(Request::class), $this->createMock(Response::class)); $this->assertSame('fr', $dataCollector->getLocale()); $this->assertSame(['en'], $dataCollector->getFallbackLocales()); + $this->assertSame(['welcome' => 'Welcome {name}!'], $dataCollector->getGlobalParameters()); $dataCollector->reset(); $this->assertNull($dataCollector->getLocale()); $this->assertSame([], $dataCollector->getFallbackLocales()); + $this->assertSame([], $dataCollector->getGlobalParameters()); } private function getTranslator() diff --git a/src/Symfony/Component/Translation/Tests/DataCollectorTranslatorTest.php b/src/Symfony/Component/Translation/Tests/DataCollectorTranslatorTest.php index c6cdbbea2b3af..fe37566a65138 100644 --- a/src/Symfony/Component/Translation/Tests/DataCollectorTranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/DataCollectorTranslatorTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Translation\DataCollectorTranslator; use Symfony\Component\Translation\Loader\ArrayLoader; +use Symfony\Component\Translation\TranslatableMessage; use Symfony\Component\Translation\Translator; class DataCollectorTranslatorTest extends TestCase @@ -84,6 +85,18 @@ public function testCollectMessages() $this->assertEquals($expectedMessages, $collector->getCollectedMessages()); } + public function testGetGlobalParameters() + { + $translatable = new TranslatableMessage('url.front'); + + $translator = new Translator('en'); + $translator->addGlobalParameter('app', 'My app'); + $translator->addGlobalParameter('url', $translatable); + $collector = new DataCollectorTranslator($translator); + + $this->assertEquals(['app' => 'My app', 'url' => $translatable], $collector->getGlobalParameters()); + } + private function createCollector() { $translator = new Translator('en'); diff --git a/src/Symfony/Component/Translation/Tests/TranslatorTest.php b/src/Symfony/Component/Translation/Tests/TranslatorTest.php index 27f47d2865d6d..c4dee1bb34fe7 100644 --- a/src/Symfony/Component/Translation/Tests/TranslatorTest.php +++ b/src/Symfony/Component/Translation/Tests/TranslatorTest.php @@ -602,6 +602,56 @@ public function testMissingLoaderForResourceError() $translator->getCatalogue('en'); } + + public function testTransWithGlobalParameters() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['welcome' => 'Welcome {name}!'], 'en'); + $translator->addResource('array', ['welcome' => 'Bienvenue {name}!'], 'fr'); + $translator->addGlobalParameter('{name}', 'Global name'); + + $this->assertSame('Welcome Global name!', $translator->trans('welcome')); + $this->assertSame('Bienvenue Global name!', $translator->trans('welcome', [], null, 'fr')); + $this->assertSame('Welcome John!', $translator->trans('welcome', ['{name}' => 'John'])); + $this->assertSame('Bienvenue Jean!', $translator->trans('welcome', ['{name}' => 'Jean'], null, 'fr')); + } + + public function testTransWithGlobalTranslatableParameters() + { + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', ['welcome' => 'Welcome on {link}!'], 'en'); + $translator->addResource('array', ['welcome' => 'Bienvenue sur {link}!'], 'fr'); + + $translator->addResource('array', ['url' => 'example.com/admin'], 'en', 'globals'); + $translator->addResource('array', ['url' => 'example.fr/admin'], 'fr', 'globals'); + + $translator->addGlobalParameter('{link}', new TranslatableMessage('url', [], 'globals')); + + $this->assertSame('Welcome on example.com/admin!', $translator->trans('welcome')); + $this->assertSame('Bienvenue sur example.fr/admin!', $translator->trans('welcome', [], null, 'fr')); + $this->assertSame('Welcome on other.com!', $translator->trans('welcome', ['{link}' => 'other.com'])); + $this->assertSame('Bienvenue sur autre.fr!', $translator->trans('welcome', ['{link}' => 'autre.fr'], null, 'fr')); + } + + /** + * @requires extension intl + */ + public function testTransICUWithGlobalParameters() + { + $domain = 'test.'.MessageCatalogue::INTL_DOMAIN_SUFFIX; + + $translator = new Translator('en'); + $translator->addLoader('array', new ArrayLoader()); + $translator->addResource('array', [ + 'apples' => '{apples, plural, =0 {There are no apples} one {There is one apple} other {There are # apples}}', + ], 'en', $domain); + $translator->addGlobalParameter('{apples}', 42); + + $this->assertSame('There are 42 apples', $translator->trans('apples', [], $domain)); + $this->assertSame('There is one apple', $translator->trans('apples', ['{apples}' => 1], $domain)); + } } class StringClass diff --git a/src/Symfony/Component/Translation/Translator.php b/src/Symfony/Component/Translation/Translator.php index 7c0a458e8afac..4ce3edad3e97b 100644 --- a/src/Symfony/Component/Translation/Translator.php +++ b/src/Symfony/Component/Translation/Translator.php @@ -60,6 +60,16 @@ class Translator implements TranslatorInterface, TranslatorBagInterface, LocaleA private bool $hasIntlFormatter; + /** + * @var array + */ + private array $globalParameters = []; + + /** + * @var array + */ + private array $globalTranslatedParameters = []; + /** * @throws InvalidArgumentException If a locale contains invalid characters */ @@ -155,6 +165,17 @@ public function getFallbackLocales(): array return $this->fallbackLocales; } + public function addGlobalParameter(string $id, string|int|float|TranslatableInterface $value): void + { + $this->globalParameters[$id] = $value; + $this->globalTranslatedParameters = []; + } + + public function getGlobalParameters(): array + { + return $this->globalParameters; + } + public function trans(?string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string { if (null === $id || '' === $id) { @@ -174,7 +195,24 @@ public function trans(?string $id, array $parameters = [], ?string $domain = nul } } - $parameters = array_map(fn ($parameter) => $parameter instanceof TranslatableInterface ? $parameter->trans($this, $locale) : $parameter, $parameters); + foreach ($parameters as $key => $value) { + if ($value instanceof TranslatableInterface) { + $parameters[$key] = $value->trans($this, $locale); + } + } + + if (null === $globalParameters =& $this->globalTranslatedParameters[$locale]) { + $globalParameters = $this->globalParameters; + foreach ($globalParameters as $key => $value) { + if ($value instanceof TranslatableInterface) { + $globalParameters[$key] = $value->trans($this, $locale); + } + } + } + + if ($globalParameters) { + $parameters += $globalParameters; + } $len = \strlen(MessageCatalogue::INTL_DOMAIN_SUFFIX); if ($this->hasIntlFormatter