Skip to content

[Translator] move loading catalogue out of Translator. #17563

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\MessageCatalogueProvider\MessageCatalogueProvider;
use Symfony\Component\Translation\Loader\ArrayLoader;

class TranslationExtensionTest extends \PHPUnit_Framework_TestCase
Expand All @@ -34,7 +34,7 @@ public function testTrans($template, $expected, array $variables = array())
echo $template."\n";
$loader = new \Twig_Loader_Array(array('index' => $template));
$twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false));
$twig->addExtension(new TranslationExtension(new Translator('en', new MessageSelector())));
$twig->addExtension(new TranslationExtension($this->getTranslator('en')));

echo $twig->compile($twig->parse($twig->tokenize($twig->getLoader()->getSource('index'), 'index')))."\n\n";
$this->assertEquals($expected, $this->getTemplate($template)->render($variables));
Expand Down Expand Up @@ -136,12 +136,13 @@ public function testDefaultTranslationDomain()
',
);

$translator = new Translator('en', new MessageSelector());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array('foo' => 'foo (messages)'), 'en');
$translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom');
$translator->addResource('array', array('foo' => 'foo (foo)'), 'en', 'foo');

$loaders = array('array' => new ArrayLoader());
$resources = array(
array('array', array('foo' => 'foo (messages)'), 'en'),
array('array', array('foo' => 'foo (custom)'), 'en', 'custom'),
array('array', array('foo' => 'foo (foo)'), 'en', 'foo'),
);
$translator = $this->getTranslator('en', $loaders, $resources);
$template = $this->getTemplate($templates, $translator);

$this->assertEquals('foo (foo)foo (custom)foo (foo)foo (custom)foo (foo)foo (custom)', trim($template->render(array())));
Expand Down Expand Up @@ -169,13 +170,15 @@ public function testDefaultTranslationDomainWithNamedArguments()
',
);

$translator = new Translator('en', new MessageSelector());
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', array('foo' => 'foo (messages)'), 'en');
$translator->addResource('array', array('foo' => 'foo (custom)'), 'en', 'custom');
$translator->addResource('array', array('foo' => 'foo (foo)'), 'en', 'foo');
$translator->addResource('array', array('foo' => 'foo (fr)'), 'fr', 'custom');
$loaders = array('array' => new ArrayLoader());
$resources = array(
array('array', array('foo' => 'foo (messages)'), 'en'),
array('array', array('foo' => 'foo (custom)'), 'en', 'custom'),
array('array', array('foo' => 'foo (foo)'), 'en', 'foo'),
array('array', array('foo' => 'foo (fr)'), 'fr', 'custom'),
);

$translator = $this->getTranslator('en', $loaders, $resources);
$template = $this->getTemplate($templates, $translator);

$this->assertEquals('foo (custom)foo (foo)foo (custom)foo (custom)foo (fr)foo (custom)foo (fr)', trim($template->render(array())));
Expand All @@ -184,7 +187,7 @@ public function testDefaultTranslationDomainWithNamedArguments()
protected function getTemplate($template, $translator = null)
{
if (null === $translator) {
$translator = new Translator('en', new MessageSelector());
$translator = $this->getTranslator('en');
}

if (is_array($template)) {
Expand All @@ -197,4 +200,9 @@ protected function getTemplate($template, $translator = null)

return $twig->loadTemplate('index');
}

private function getTranslator($locale, $loaders = array(), $resources = array())
{
return new Translator($locale, new MessageCatalogueProvider($loaders, $resources));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Translation\MessageCatalogueProvider\MessageCatalogueProviderInterface;

/**
* Generates the catalogues for translations.
Expand All @@ -23,10 +24,12 @@
class TranslationsCacheWarmer implements CacheWarmerInterface
{
private $translator;
private $messageCatalogueProvider;

public function __construct(TranslatorInterface $translator)
public function __construct(TranslatorInterface $translator, MessageCatalogueProviderInterface $messageCatalogueProvider = null)
{
$this->translator = $translator;
$this->messageCatalogueProvider = $messageCatalogueProvider;
}

/**
Expand All @@ -36,6 +39,8 @@ public function warmUp($cacheDir)
{
if ($this->translator instanceof WarmableInterface) {
$this->translator->warmUp($cacheDir);
} elseif ($this->messageCatalogueProvider instanceof WarmableInterface) {
$this->messageCatalogueProvider->warmUp($cacheDir);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@ public function process(ContainerBuilder $container)
}

$container->findDefinition('translator.default')->replaceArgument(2, $loaders);
$container->findDefinition('translation.message_catalogue_provider.resource')->replaceArgument(1, $loaders);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,13 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
$this->translationConfigEnabled = true;

// Use the "real" translator instead of the identity default
$container->setAlias('translator', 'translator.default');
$container->setAlias('translator', 'translation.translator');
$translator = $container->findDefinition('translator.default');
$translator->addMethodCall('setFallbackLocales', array($config['fallbacks']));
$resourceMessageCatalogueProvider = $container->findDefinition('translation.message_catalogue_provider.resource');
if ($config['fallbacks']) {
$translator->addMethodCall('setFallbackLocales', array($config['fallbacks']));
$resourceMessageCatalogueProvider->replaceArgument(3, $config['fallbacks']);
}

$container->setParameter('translator.logging', $config['logging']);

Expand Down Expand Up @@ -704,6 +708,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
}

$files = array();
$resources = array();
$finder = Finder::create()
->files()
->filter(function (\SplFileInfo $file) {
Expand All @@ -719,6 +724,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
$files[$locale] = array();
}

$resources[] = array($format, (string) $file, $locale, $domain);
$files[$locale][] = (string) $file;
}

Expand All @@ -728,6 +734,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
);

$translator->replaceArgument(3, $options);
$resourceMessageCatalogueProvider->replaceArgument(2, $resources);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<argument type="service" id="security.csrf.token_manager" />
<argument>%form.type_extension.csrf.enabled%</argument>
<argument>%form.type_extension.csrf.field_name%</argument>
<argument type="service" id="translator.default" />
<argument type="service" id="translation.translator" />
<argument>%validator.translation_domain%</argument>
</service>
</services>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,33 @@

<service id="translation.warmer" class="Symfony\Bundle\FrameworkBundle\CacheWarmer\TranslationsCacheWarmer" public="false">
<argument type="service" id="translator" />
<argument type="service" id="translation.message_catalogue_provider.warmable" />
<tag name="kernel.cache_warmer" />
</service>

<service id="translation.translator" class="Symfony\Component\Translation\Translator">
<argument>%kernel.debug%</argument>
<argument type="service" id="translation.message_catalogue_provider" />
<argument type="service" id="translator.selector" />
</service>

<service id="translation.message_catalogue_provider.warmable" class="Symfony\Bundle\FrameworkBundle\Translation\WarmableMessageCatalogueProvider" public="false">
<argument type="service" id="translation.message_catalogue_provider" />
<argument type="service" id="translation.message_catalogue_provider.resource" />
</service>

<service id="translation.message_catalogue_provider.resource" class="Symfony\Component\Translation\MessageCatalogueProvider\ContainerAwareMessageCatalogueProvider" public="false">
<argument type="service" id="service_container" />
<argument type="collection" /> <!-- translation loaders -->
<argument type="collection" /> <!-- translation resources -->
<argument type="collection" /> <!-- fallback locales -->
</service>

<service id="translation.message_catalogue_provider.cache" class="Symfony\Component\Translation\MessageCatalogueProvider\CachedMessageCatalogueProvider" public="false">
<argument type="service" id="translation.message_catalogue_provider.resource" />
<argument type="service" id="config_cache_factory" />
<argument>%kernel.cache_dir%/translations</argument> <!-- cache directory -->
</service>
<service id="translation.message_catalogue_provider" alias="translation.message_catalogue_provider.cache"/>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function testProcess()

$parameterBag->expects($this->once())
->method('resolveValue')
->will($this->returnValue("Symfony\Bundle\FrameworkBundle\Translation\Translator"));
->will($this->returnValue("Symfony\Component\Translation\Translator"));

$container->expects($this->once())
->method('getParameterBag')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function testValidCollector()
$container->expects($this->once())
->method('findTaggedServiceIds')
->will($this->returnValue(array('xliff' => array(array('alias' => 'xliff', 'legacy-alias' => 'xlf')))));
$container->expects($this->once())
$container->expects($this->any())
->method('findDefinition')
->will($this->returnValue($this->getMock('Symfony\Component\DependencyInjection\Definition')));
$pass = new TranslatorPass();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,53 @@ public function testAssetsDefaultVersionStrategyAsService()
public function testTranslator()
{
$container = $this->createContainerFromFile('full');
$this->assertTrue($container->hasDefinition('translator.default'), '->registerTranslatorConfiguration() loads translation.xml');
$this->assertEquals('translator.default', (string) $container->getAlias('translator'), '->registerTranslatorConfiguration() redefines translator service from identity to real translator');
$this->assertTrue($container->hasDefinition('translation.translator'), '->registerTranslatorConfiguration() loads translation.xml');
$this->assertEquals('translation.translator', (string) $container->getAlias('translator'), '->registerTranslatorConfiguration() redefines translator service from identity to real translator');

$resources = $container->getDefinition('translation.message_catalogue_provider.resource')->getArgument(2);
$files = array_map(function ($resource) { return realpath($resource[1]); }, $resources);
$ref = new \ReflectionClass('Symfony\Component\Validator\Validation');
$this->assertContains(
strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR),
$files,
'->registerTranslatorConfiguration() finds Validator translation resources'
);
$ref = new \ReflectionClass('Symfony\Component\Form\Form');
$this->assertContains(
strtr(dirname($ref->getFileName()).'/Resources/translations/validators.en.xlf', '/', DIRECTORY_SEPARATOR),
$files,
'->registerTranslatorConfiguration() finds Form translation resources'
);
$ref = new \ReflectionClass('Symfony\Component\Security\Core\Security');
$this->assertContains(
strtr(dirname($ref->getFileName()).'/Resources/translations/security.en.xlf', '/', DIRECTORY_SEPARATOR),
$files,
'->registerTranslatorConfiguration() finds Security translation resources'
);
$this->assertContains(
strtr(__DIR__.'/Fixtures/translations/test_paths.en.yml', '/', DIRECTORY_SEPARATOR),
$files,
'->registerTranslatorConfiguration() finds translation resources in custom paths'
);

$this->assertEquals(array('fr'), $container->getDefinition('translation.message_catalogue_provider.resource')->getArgument(3));
}

/**
* @group legacy
*/
public function testLegacyTranslator()
{
$container = $this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', array(
'translator' => array(
'fallback' => 'fr',
'paths' => array('%kernel.root_dir%/Fixtures/translations'),
'paths' => array('%kernel.root_dir%/Fixtures/translations'),
),
));
});

$options = $container->getDefinition('translator.default')->getArgument(3);

$files = array_map(function ($resource) { return realpath($resource); }, $options['resource_files']['en']);
Expand Down Expand Up @@ -273,14 +318,30 @@ public function testTranslator()
$this->assertEquals(array('fr'), $calls[1][1][0]);
}

public function testTranslatorMultipleFallbacks()
/**
* @group legacy
*/
public function testLegacyTranslatorMultipleFallbacks()
{
$container = $this->createContainerFromFile('translator_fallbacks');
$container = $this->createContainerFromClosure(function ($container) {
$container->loadFromExtension('framework', array(
'translator' => array(
'fallbacks' => array('en', 'fr'),
),
));
});

$calls = $container->getDefinition('translator.default')->getMethodCalls();
$this->assertEquals(array('en', 'fr'), $calls[1][1][0]);
}

public function testTranslatorMultipleFallbacks()
{
$container = $this->createContainerFromFile('translator_fallbacks');

$this->assertEquals(array('en', 'fr'), $container->getDefinition('translation.message_catalogue_provider.resource')->getArgument(3));
}

/**
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\MessageSelector;

/**
* @group legacy
*/
class TranslatorTest extends \PHPUnit_Framework_TestCase
{
protected $tmpDir;
Expand Down Expand Up @@ -94,17 +97,6 @@ public function testTransWithCaching()
$this->assertEquals('foobarbax (sr@latin)', $translator->trans('foobarbax'));
}

/**
* @expectedException \InvalidArgumentException
*/
public function testTransWithCachingWithInvalidLocale()
{
$loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
$translator = $this->getTranslator($loader, array('cache_dir' => $this->tmpDir), 'loader', '\Symfony\Bundle\FrameworkBundle\Tests\Translation\TranslatorWithInvalidLocale');

$translator->trans('foo');
}

public function testLoadResourcesWithoutCaching()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
Expand Down Expand Up @@ -270,14 +262,3 @@ private function createTranslator($loader, $options, $translatorClass = '\Symfon
);
}
}

class TranslatorWithInvalidLocale extends Translator
{
/**
* {@inheritdoc}
*/
public function getLocale()
{
return 'invalid locale';
}
}
8 changes: 6 additions & 2 deletions src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Bundle\FrameworkBundle\Translation;

@trigger_error('The '.__NAMESPACE__.'\Translator class is deprecated since version 2.8 and will be removed in 3.0. Use directly the Symfony\Component\Translation\Translator class instead.', E_USER_DEPRECATED);

use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
use Symfony\Component\Translation\Translator as BaseTranslator;
use Symfony\Component\Translation\MessageSelector;
Expand All @@ -20,6 +22,8 @@
* Translator.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since 2.8, to be removed in 3.0. Use the Symfony\Component\Translation\Translator instead.
*/
class Translator extends BaseTranslator implements WarmableInterface
{
Expand Down Expand Up @@ -65,11 +69,11 @@ public function __construct(ContainerInterface $container, MessageSelector $sele

$this->options = array_merge($this->options, $options);
$this->resourceLocales = array_keys($this->options['resource_files']);

parent::__construct($container->getParameter('kernel.default_locale'), $selector, $this->options['cache_dir'], $this->options['debug']);
if (null !== $this->options['cache_dir'] && $this->options['debug']) {
$this->loadResources();
}

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

/**
Expand Down
Loading