diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 8ee78c3e5b72..a2016b38c485 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -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() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 8536868bec66..8b20c27f4db3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -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']); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index 07213a2602df..3c158abb0235 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -16,6 +16,7 @@ %kernel.cache_dir%/translations %kernel.debug% + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php index 7e3d096180e3..fad9b09a049f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php @@ -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), diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php index fd7fe7158bf7..1f82930b26da 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Translation/TranslatorTest.php @@ -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', @@ -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', @@ -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'); @@ -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', @@ -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', @@ -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 ); } @@ -402,7 +428,8 @@ private function createTranslator($loader, $options, $translatorClass = '\Symfon new MessageFormatter(), $defaultLocale, [$loaderFomat => [$loaderFomat]], - $options + $options, + $enabledLocales ); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php index da4384dadbf9..74675b220530 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/Translator.php @@ -57,6 +57,11 @@ class Translator extends BaseTranslator implements WarmableInterface */ private $scannedDirectories; + /** + * @var string[] + */ + private $enabledLocales; + /** * Constructor. * @@ -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))) { @@ -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]);