Skip to content

Commit

Permalink
feature #32433 [Translation] Introduce a way to configure the enabled…
Browse files Browse the repository at this point in the history
… locales (javiereguiluz)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[Translation] Introduce a way to configure the enabled locales

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #31563
| License       | MIT
| Doc PR        | -

This implements the idea #31563 so we can decide if we want to add this or not. I tested it in the "Symfony Demo" app. Before: 107 catalogs created in cache/dev/translations/. After: 43 catalogs. But that's because the app is translated into lots of languages. In most cases, only 2 catalog files will be generated (vs 107 before).

If this idea is approved, I'll add tests and docs. Thanks.

Commits
-------

7658434 [Translation] Introduce a way to configure the enabled locales
  • Loading branch information
fabpot committed Feb 4, 2020
2 parents 61774e6 + 7658434 commit f23aa96
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 12 deletions.
Expand Up @@ -686,6 +686,16 @@ private function addTranslatorSection(ArrayNodeDefinition $rootNode)
->arrayNode('paths')
->prototype('scalar')->end()
->end()
->arrayNode('enabled_locales')
->prototype('scalar')
->defaultValue([])
->beforeNormalization()
->always()
->then(function ($config) {
return array_unique((array) $config);
})
->end()
->end()
->end()
->end()
->end()
Expand Down
Expand Up @@ -1066,6 +1066,8 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder
$defaultOptions['cache_dir'] = $config['cache_dir'];
$translator->setArgument(4, $defaultOptions);

$translator->setArgument(6, $config['enabled_locales']);

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

Expand Down
Expand Up @@ -16,6 +16,7 @@
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
<argument key="debug">%kernel.debug%</argument>
</argument>
<argument type="collection" /> <!-- enabled locales -->
<call method="setConfigCacheFactory">
<argument type="service" id="config_cache_factory" />
</call>
Expand Down
Expand Up @@ -373,6 +373,7 @@ protected static function getBundleDefaultConfig()
'formatter' => 'translator.formatter.default',
'paths' => [],
'default_path' => '%kernel.project_dir%/translations',
'enabled_locales' => [],
],
'validation' => [
'enabled' => !class_exists(FullStack::class),
Expand Down
Expand Up @@ -109,7 +109,7 @@ public function testTransWithCachingWithInvalidLocale()

public function testLoadResourcesWithoutCaching()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
$loader = new YamlFileLoader();
$resourceFiles = [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
Expand Down Expand Up @@ -186,7 +186,7 @@ public function getDebugModeAndCacheDirCombinations()

public function testCatalogResourcesAreAddedForScannedDirectories()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
$loader = new YamlFileLoader();
$resourceFiles = [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
Expand Down Expand Up @@ -329,9 +329,9 @@ protected function getContainer($loader)
return $container;
}

public function getTranslator($loader, $options = [], $loaderFomat = 'loader', $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $defaultLocale = 'en')
public function getTranslator($loader, $options = [], $loaderFomat = 'loader', $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $defaultLocale = 'en', array $enabledLocales = [])
{
$translator = $this->createTranslator($loader, $options, $translatorClass, $loaderFomat, $defaultLocale);
$translator = $this->createTranslator($loader, $options, $translatorClass, $loaderFomat, $defaultLocale, $enabledLocales);

if ('loader' === $loaderFomat) {
$translator->addResource('loader', 'foo', 'fr');
Expand All @@ -348,7 +348,7 @@ public function getTranslator($loader, $options = [], $loaderFomat = 'loader', $

public function testWarmup()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
$loader = new YamlFileLoader();
$resourceFiles = [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
Expand All @@ -371,9 +371,34 @@ public function testWarmup()
$this->assertEquals('répertoire', $translator->trans('folder'));
}

public function testEnabledLocales()
{
$loader = new YamlFileLoader();
$resourceFiles = [
'fr' => [
__DIR__.'/../Fixtures/Resources/translations/messages.fr.yml',
],
];

// prime the cache without configuring the enabled locales
$translator = $this->getTranslator($loader, ['cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles], 'yml', Translator::class, 'en', []);
$translator->setFallbackLocales(['fr']);
$translator->warmup($this->tmpDir);

$this->assertCount(2, glob($this->tmpDir.'/catalogue.*.*.php'), 'Both "en" and "fr" catalogues are generated.');

// prime the cache and configure the enabled locales
$this->deleteTmpDir();
$translator = $this->getTranslator($loader, ['cache_dir' => $this->tmpDir, 'resource_files' => $resourceFiles], 'yml', Translator::class, 'en', ['fr']);
$translator->setFallbackLocales(['fr']);
$translator->warmup($this->tmpDir);

$this->assertCount(1, glob($this->tmpDir.'/catalogue.*.*.php'), 'Only the "fr" catalogue is generated.');
}

public function testLoadingTranslationFilesWithDotsInMessageDomain()
{
$loader = new \Symfony\Component\Translation\Loader\YamlFileLoader();
$loader = new YamlFileLoader();
$resourceFiles = [
'en' => [
__DIR__.'/../Fixtures/Resources/translations/domain.with.dots.en.yml',
Expand All @@ -386,14 +411,15 @@ public function testLoadingTranslationFilesWithDotsInMessageDomain()
$this->assertEquals('It works!', $translator->trans('message', [], 'domain.with.dots'));
}

private function createTranslator($loader, $options, $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $loaderFomat = 'loader', $defaultLocale = 'en')
private function createTranslator($loader, $options, $translatorClass = '\Symfony\Bundle\FrameworkBundle\Translation\Translator', $loaderFomat = 'loader', $defaultLocale = 'en', array $enabledLocales = [])
{
if (null === $defaultLocale) {
return new $translatorClass(
$this->getContainer($loader),
new MessageFormatter(),
[$loaderFomat => [$loaderFomat]],
$options
$options,
$enabledLocales
);
}

Expand All @@ -402,7 +428,8 @@ private function createTranslator($loader, $options, $translatorClass = '\Symfon
new MessageFormatter(),
$defaultLocale,
[$loaderFomat => [$loaderFomat]],
$options
$options,
$enabledLocales
);
}
}
Expand Down
13 changes: 10 additions & 3 deletions src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php
Expand Up @@ -57,6 +57,11 @@ class Translator extends BaseTranslator implements WarmableInterface
*/
private $scannedDirectories;

/**
* @var string[]
*/
private $enabledLocales;

/**
* Constructor.
*
Expand All @@ -69,10 +74,11 @@ class Translator extends BaseTranslator implements WarmableInterface
*
* @throws InvalidArgumentException
*/
public function __construct(ContainerInterface $container, MessageFormatterInterface $formatter, string $defaultLocale, array $loaderIds = [], array $options = [])
public function __construct(ContainerInterface $container, MessageFormatterInterface $formatter, string $defaultLocale, array $loaderIds = [], array $options = [], array $enabledLocales = [])
{
$this->container = $container;
$this->loaderIds = $loaderIds;
$this->enabledLocales = $enabledLocales;

// check option names
if ($diff = array_diff(array_keys($options), array_keys($this->options))) {
Expand All @@ -97,8 +103,9 @@ public function warmUp(string $cacheDir)
return;
}

$locales = array_merge($this->getFallbackLocales(), [$this->getLocale()], $this->resourceLocales);
foreach (array_unique($locales) as $locale) {
$localesToWarmUp = $this->enabledLocales ?: array_merge($this->getFallbackLocales(), [$this->getLocale()], $this->resourceLocales);

foreach (array_unique($localesToWarmUp) as $locale) {
// reset catalogue in case it's already loaded during the dump of the other locales.
if (isset($this->catalogues[$locale])) {
unset($this->catalogues[$locale]);
Expand Down

0 comments on commit f23aa96

Please sign in to comment.