Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 94073df

Browse filesBrowse files
committed
[FrameworkBundle] Make Translator works with any PSR-11 container
1 parent 2a99e16 commit 94073df
Copy full SHA for 94073df

File tree

8 files changed

+213
-21
lines changed
Filter options

8 files changed

+213
-21
lines changed

‎UPGRADE-3.3.md

Copy file name to clipboardExpand all lines: UPGRADE-3.3.md
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ FrameworkBundle
172172
class has been deprecated and will be removed in 4.0. Use the
173173
`Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` class instead.
174174

175+
* The `Symfony\Bundle\FrameworkBundle\Translation\Translator` constructor now takes the
176+
default locale as 3rd argument. Not passing it will trigger an error in 4.0.
177+
175178
HttpKernel
176179
-----------
177180

‎UPGRADE-4.0.md

Copy file name to clipboardExpand all lines: UPGRADE-4.0.md
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,9 @@ FrameworkBundle
271271
class has been removed. Use the
272272
`Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` class instead.
273273

274+
* The `Symfony\Bundle\FrameworkBundle\Translation\Translator` constructor now takes the
275+
default locale as 3rd argument.
276+
274277
HttpFoundation
275278
---------------
276279

‎src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ CHANGELOG
3030
* Deprecated `ControllerArgumentValueResolverPass`. Use
3131
`Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass` instead
3232
* Deprecated `RoutingResolverPass`, use `Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` instead
33+
* Added `$defaultLocale` as 3rd argument of `Translator::__construct()` and
34+
made `Translator` works with any PSR-11 container
3335

3436
3.2.0
3537
-----

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php
+9-2Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1415
use Symfony\Component\DependencyInjection\Reference;
1516
use Symfony\Component\DependencyInjection\ContainerBuilder;
1617
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
@@ -24,7 +25,9 @@ public function process(ContainerBuilder $container)
2425
}
2526

2627
$loaders = array();
28+
$loaderRefs = array();
2729
foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) {
30+
$loaderRefs[$id] = new Reference($id);
2831
$loaders[$id][] = $attributes[0]['alias'];
2932
if (isset($attributes[0]['legacy-alias'])) {
3033
$loaders[$id][] = $attributes[0]['legacy-alias'];
@@ -35,11 +38,15 @@ public function process(ContainerBuilder $container)
3538
$definition = $container->getDefinition('translation.loader');
3639
foreach ($loaders as $id => $formats) {
3740
foreach ($formats as $format) {
38-
$definition->addMethodCall('addLoader', array($format, new Reference($id)));
41+
$definition->addMethodCall('addLoader', array($format, $loaderRefs[$id]));
3942
}
4043
}
4144
}
4245

43-
$container->findDefinition('translator.default')->replaceArgument(2, $loaders);
46+
$container
47+
->findDefinition('translator.default')
48+
->replaceArgument(0, new ServiceLocatorArgument($loaderRefs))
49+
->replaceArgument(3, $loaders)
50+
;
4451
}
4552
}

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
<services>
88
<service id="translator.default" class="Symfony\Bundle\FrameworkBundle\Translation\Translator">
9-
<argument type="service" id="service_container" />
9+
<argument type="service-locator" /> <!-- translation loaders -->
1010
<argument type="service" id="translator.selector" />
11-
<argument type="collection" /> <!-- translation loaders -->
11+
<argument>%kernel.default_locale%</argument>
12+
<argument type="collection" /> <!-- translation loaders ids -->
1213
<argument type="collection">
1314
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
1415
<argument key="debug">%kernel.debug%</argument>
1516
</argument>
16-
<argument type="collection" /> <!-- translation resources -->
1717
<call method="setConfigCacheFactory">
1818
<argument type="service" id="config_cache_factory" />
1919
</call>

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/TranslatorPassTest.php
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
1516
use Symfony\Component\DependencyInjection\Reference;
1617
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslatorPass;
1718

@@ -39,7 +40,15 @@ public function testValidCollector()
3940
->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf')))));
4041
$container->expects($this->once())
4142
->method('findDefinition')
42-
->will($this->returnValue($this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock()));
43+
->will($this->returnValue($translator = $this->getMockBuilder('Symfony\Component\DependencyInjection\Definition')->getMock()));
44+
$translator->expects($this->at(0))
45+
->method('replaceArgument')
46+
->with(0, $this->equalTo(new ServiceLocatorArgument(array('xliff' => new Reference('xliff')))))
47+
->willReturn($translator);
48+
$translator->expects($this->at(1))
49+
->method('replaceArgument')
50+
->with(3, array('xliff' => array('xliff', 'xlf')))
51+
->willReturn($translator);
4352
$pass = new TranslatorPass();
4453
$pass->process($container);
4554
}

‎src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php
+167-12Lines changed: 167 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,158 @@ protected function deleteTmpDir()
4242
$fs->remove($dir);
4343
}
4444

45+
/**
46+
* @group legacy
47+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
48+
*/
49+
public function testTransWithoutCachingOmittingLocale()
50+
{
51+
$translator = $this->getTranslator($this->getLoader(), array(), 'loader', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
52+
$translator->setLocale('fr');
53+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
54+
55+
$this->assertEquals('foo (FR)', $translator->trans('foo'));
56+
$this->assertEquals('bar (EN)', $translator->trans('bar'));
57+
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
58+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
59+
$this->assertEquals('no translation', $translator->trans('no translation'));
60+
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
61+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
62+
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
63+
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
64+
}
65+
66+
/**
67+
* @group legacy
68+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
69+
*/
70+
public function testTransWithCachingOmittingLocale()
71+
{
72+
// prime the cache
73+
$translator = $this->getTranslator($this->getLoader(), array('cache_dir' => $this->tmpDir), 'loader', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
74+
$translator->setLocale('fr');
75+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
76+
77+
$this->assertEquals('foo (FR)', $translator->trans('foo'));
78+
$this->assertEquals('bar (EN)', $translator->trans('bar'));
79+
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
80+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
81+
$this->assertEquals('no translation', $translator->trans('no translation'));
82+
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
83+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
84+
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
85+
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
86+
87+
// do it another time as the cache is primed now
88+
$loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
89+
$loader->expects($this->never())->method('load');
90+
91+
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), 'loader', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
92+
$translator->setLocale('fr');
93+
$translator->setFallbackLocales(array('en', 'es', 'pt-PT', 'pt_BR', 'fr.UTF-8', 'sr@latin'));
94+
95+
$this->assertEquals('foo (FR)', $translator->trans('foo'));
96+
$this->assertEquals('bar (EN)', $translator->trans('bar'));
97+
$this->assertEquals('foobar (ES)', $translator->trans('foobar'));
98+
$this->assertEquals('choice 0 (EN)', $translator->transChoice('choice', 0));
99+
$this->assertEquals('no translation', $translator->trans('no translation'));
100+
$this->assertEquals('foobarfoo (PT-PT)', $translator->trans('foobarfoo'));
101+
$this->assertEquals('other choice 1 (PT-BR)', $translator->transChoice('other choice', 1));
102+
$this->assertEquals('foobarbaz (fr.UTF-8)', $translator->trans('foobarbaz'));
103+
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
104+
}
105+
106+
/**
107+
* @group legacy
108+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
109+
* @expectedException \InvalidArgumentException
110+
*/
111+
public function testTransWithCachingWithInvalidLocaleOmittingLocale()
112+
{
113+
$loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
114+
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), 'loader', '\Symfony\Bundle\FrameworkBundle\Tests\Translation\TranslatorWithInvalidLocale', null);
115+
116+
$translator->trans('foo');
117+
}
118+
119+
/**
120+
* @group legacy
121+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
122+
*/
123+
public function testLoadResourcesWithoutCachingOmittingLocale()
124+
{
125+
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
126+
$resourceFiles = array(
127+
'fr' => array(
128+
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
129+
),
130+
);
131+
132+
$translator = $this->getTranslator($loader, array('resource_files' => $resourceFiles), 'yml', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
133+
$translator->setLocale('fr');
134+
135+
$this->assertEquals('répertoire', $translator->trans('folder'));
136+
}
137+
138+
/**
139+
* @group legacy
140+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
141+
*/
142+
public function testGetDefaultLocaleOmittingLocale()
143+
{
144+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
145+
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
146+
$container
147+
->expects($this->once())
148+
->method('getParameter')
149+
->with('kernel.default_locale')
150+
->will($this->returnValue('en'))
151+
;
152+
$translator = new Translator($container, new MessageSelector());
153+
154+
$this->assertSame('en', $translator->getLocale());
155+
}
156+
157+
/**
158+
* @group legacy
159+
* @expectedException \InvalidArgumentException
160+
* @expectedExceptionMessage Missing third $defaultLocale argument.
161+
*/
162+
public function testGetDefaultLocaleOmittingLocaleWithPsrContainer()
163+
{
164+
$container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock();
165+
$translator = new Translator($container, new MessageSelector());
166+
}
167+
168+
/**
169+
* @group legacy
170+
* @expectedDeprecation Method Symfony\Bundle\FrameworkBundle\Translation\Translator::__construct() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.
171+
*/
172+
public function testWarmupOmittingLocale()
173+
{
174+
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
175+
$resourceFiles = array(
176+
'fr' => array(
177+
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
178+
),
179+
);
180+
181+
// prime the cache
182+
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
183+
$translator->setFallbackLocales(array('fr'));
184+
$translator->warmup($this->tmpDir);
185+
186+
$loader = $this->getMockBuilder('Symfony\Component\Translation\Loader\LoaderInterface')->getMock();
187+
$loader
188+
->expects($this->never())
189+
->method('load');
190+
191+
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles), 'yml', '\Symfony\Bundle\FrameworkBundle\Translation\Translator', null);
192+
$translator->setLocale('fr');
193+
$translator->setFallbackLocales(array('fr'));
194+
$this->assertEquals('répertoire', $translator->trans('folder'));
195+
}
196+
45197
public function testTransWithoutCaching()
46198
{
47199
$translator = $this->getTranslator($this->getLoader());
@@ -123,15 +275,8 @@ public function testLoadResourcesWithoutCaching()
123275

124276
public function testGetDefaultLocale()
125277
{
126-
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\ContainerInterface')->getMock();
127-
$container
128-
->expects($this->once())
129-
->method('getParameter')
130-
->with('kernel.default_locale')
131-
->will($this->returnValue('en'))
132-
;
133-
134-
$translator = new Translator($container, new MessageSelector());
278+
$container = $this->getMockBuilder('Psr\Container\ContainerInterface')->getMock();
279+
$translator = new Translator($container, new MessageSelector(), 'en');
135280

136281
$this->assertSame('en', $translator->getLocale());
137282
}
@@ -219,9 +364,9 @@ protected function getContainer($loader)
219364
return $container;
220365
}
221366

222-
public function getTranslator($loader, $options = array(), $loaderFomat = 'loader', $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator')
367+
public function getTranslator($loader, $options = array(), $loaderFomat = 'loader', $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $defaultLocale = 'en')
223368
{
224-
$translator = $this->createTranslator($loader, $options, $translatorClass, $loaderFomat);
369+
$translator = $this->createTranslator($loader, $options, $translatorClass, $loaderFomat, $defaultLocale);
225370

226371
if ('loader' === $loaderFomat) {
227372
$translator->addResource('loader', 'foo', 'fr');
@@ -261,11 +406,21 @@ public function testWarmup()
261406
$this->assertEquals('répertoire', $translator->trans('folder'));
262407
}
263408

264-
private function createTranslator($loader, $options, $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $loaderFomat = 'loader')
409+
private function createTranslator($loader, $options, $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $loaderFomat = 'loader', $defaultLocale = 'en')
265410
{
411+
if (null === $defaultLocale) {
412+
return new $translatorClass(
413+
$this->getContainer($loader),
414+
new MessageSelector(),
415+
array($loaderFomat => array($loaderFomat)),
416+
$options
417+
);
418+
}
419+
266420
return new $translatorClass(
267421
$this->getContainer($loader),
268422
new MessageSelector(),
423+
$defaultLocale,
269424
array($loaderFomat => array($loaderFomat)),
270425
$options
271426
);

‎src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
+16-3Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Translation;
1313

14+
use Psr\Container\ContainerInterface;
15+
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
1416
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
1517
use Symfony\Component\Translation\Translator as BaseTranslator;
1618
use Symfony\Component\Translation\MessageSelector;
17-
use Symfony\Component\DependencyInjection\ContainerInterface;
1819
use Symfony\Component\Translation\Exception\InvalidArgumentException;
1920

2021
/**
@@ -54,8 +55,20 @@ class Translator extends BaseTranslator implements WarmableInterface
5455
*
5556
* @throws InvalidArgumentException
5657
*/
57-
public function __construct(ContainerInterface $container, MessageSelector $selector, $loaderIds = array(), array $options = array())
58+
public function __construct(ContainerInterface $container, MessageSelector $selector, $defaultLocale = null, array $loaderIds = array(), array $options = array())
5859
{
60+
// BC 3.x, to be removed in 4.0 along with the $defaultLocale default value
61+
if (is_array($defaultLocale) || 3 > func_num_args()) {
62+
if (!$container instanceof SymfonyContainerInterface) {
63+
throw new \InvalidArgumentException('Missing third $defaultLocale argument.');
64+
}
65+
66+
$options = $loaderIds;
67+
$loaderIds = $defaultLocale;
68+
$defaultLocale = $container->getParameter('kernel.default_locale');
69+
@trigger_error(sprintf('Method %s() takes the default locale as 3rd argument since version 3.3. Not passing it is deprecated and will trigger an error in 4.0.', __METHOD__), E_USER_DEPRECATED);
70+
}
71+
5972
$this->container = $container;
6073
$this->loaderIds = $loaderIds;
6174

@@ -70,7 +83,7 @@ public function __construct(ContainerInterface $container, MessageSelector $sele
7083
$this->loadResources();
7184
}
7285

73-
parent::__construct($container->getParameter('kernel.default_locale'), $selector, $this->options['cache_dir'], $this->options['debug']);
86+
parent::__construct($defaultLocale, $selector, $this->options['cache_dir'], $this->options['debug']);
7487
}
7588

7689
/**

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.