Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[FrameworkBundle][Translation] Add support for Translator paths, Twig paths and Translator aware services paths in commands #29121

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

Merged
merged 1 commit into from
Feb 13, 2019
Merged
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
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ CHANGELOG
* Added information about deprecated aliases in `debug:autowiring`
* Added php ini session options `sid_length` and `sid_bits_per_character`
to the `session` section of the configuration
* Added support for Translator paths, Twig paths in translation commands.

4.2.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ class TranslationDebugCommand extends Command
private $extractor;
private $defaultTransPath;
private $defaultViewsPath;
private $transPaths;
private $viewsPaths;

/**
* @param TranslatorInterface $translator
*/
public function __construct($translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultTransPath = null, string $defaultViewsPath = null)
public function __construct($translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $viewsPaths = [])
{
if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
Expand All @@ -66,6 +68,8 @@ public function __construct($translator, TranslationReaderInterface $reader, Ext
$this->extractor = $extractor;
$this->defaultTransPath = $defaultTransPath;
$this->defaultViewsPath = $defaultViewsPath;
$this->transPaths = $transPaths;
$this->viewsPaths = $viewsPaths;
}

/**
Expand Down Expand Up @@ -131,7 +135,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$rootDir = $kernel->getContainer()->getParameter('kernel.root_dir');

// Define Root Paths
$transPaths = [];
$transPaths = $this->transPaths;
if (is_dir($dir = $rootDir.'/Resources/translations')) {
if ($dir !== $this->defaultTransPath) {
$notice = sprintf('Storing translations in the "%s" directory is deprecated since Symfony 4.2, ', $dir);
Expand All @@ -142,7 +146,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
if ($this->defaultTransPath) {
$transPaths[] = $this->defaultTransPath;
}
$viewsPaths = [];
$viewsPaths = $this->viewsPaths;
if (is_dir($dir = $rootDir.'/Resources/views')) {
if ($dir !== $this->defaultViewsPath) {
$notice = sprintf('Storing templates in the "%s" directory is deprecated since Symfony 4.2, ', $dir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ class TranslationUpdateCommand extends Command
private $defaultLocale;
private $defaultTransPath;
private $defaultViewsPath;
private $transPaths;
private $viewsPaths;

public function __construct(TranslationWriterInterface $writer, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultLocale, string $defaultTransPath = null, string $defaultViewsPath = null)
public function __construct(TranslationWriterInterface $writer, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultLocale, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $viewsPaths = [])
{
parent::__construct();

Expand All @@ -55,6 +57,8 @@ public function __construct(TranslationWriterInterface $writer, TranslationReade
$this->defaultLocale = $defaultLocale;
$this->defaultTransPath = $defaultTransPath;
$this->defaultViewsPath = $defaultViewsPath;
$this->transPaths = $transPaths;
$this->viewsPaths = $viewsPaths;
}

/**
Expand Down Expand Up @@ -122,7 +126,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$rootDir = $kernel->getContainer()->getParameter('kernel.root_dir');

// Define Root Paths
$transPaths = [];
$transPaths = $this->transPaths;
if (is_dir($dir = $rootDir.'/Resources/translations')) {
if ($dir !== $this->defaultTransPath) {
$notice = sprintf('Storing translations in the "%s" directory is deprecated since Symfony 4.2, ', $dir);
Expand All @@ -133,7 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
if ($this->defaultTransPath) {
$transPaths[] = $this->defaultTransPath;
}
$viewsPaths = [];
$viewsPaths = $this->viewsPaths;
if (is_dir($dir = $rootDir.'/Resources/views')) {
if ($dir !== $this->defaultViewsPath) {
$notice = sprintf('Storing templates in the "%s" directory is deprecated since Symfony 4.2, ', $dir);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1023,20 +1023,21 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder

// Discover translation directories
$dirs = [];
$transPaths = [];
if (class_exists('Symfony\Component\Validator\Validation')) {
$r = new \ReflectionClass('Symfony\Component\Validator\Validation');

$dirs[] = \dirname($r->getFileName()).'/Resources/translations';
$dirs[] = $transPaths[] = \dirname($r->getFileName()).'/Resources/translations';
}
if (class_exists('Symfony\Component\Form\Form')) {
$r = new \ReflectionClass('Symfony\Component\Form\Form');

$dirs[] = \dirname($r->getFileName()).'/Resources/translations';
$dirs[] = $transPaths[] = \dirname($r->getFileName()).'/Resources/translations';
}
if (class_exists('Symfony\Component\Security\Core\Exception\AuthenticationException')) {
$r = new \ReflectionClass('Symfony\Component\Security\Core\Exception\AuthenticationException');

$dirs[] = \dirname(\dirname($r->getFileName())).'/Resources/translations';
$dirs[] = $transPaths[] = \dirname(\dirname($r->getFileName())).'/Resources/translations';
}
$defaultDir = $container->getParameterBag()->resolveValue($config['default_path']);
$rootDir = $container->getParameter('kernel.root_dir');
Expand All @@ -1053,11 +1054,13 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder

foreach ($config['paths'] as $dir) {
if ($container->fileExists($dir)) {
$dirs[] = $dir;
$dirs[] = $transPaths[] = $dir;
} else {
throw new \UnexpectedValueException(sprintf('%s defined in translator.paths does not exist or is not a directory', $dir));
}
}
$container->getDefinition('console.command.translation_debug')->replaceArgument(5, $transPaths);
$container->getDefinition('console.command.translation_update')->replaceArgument(6, $transPaths);

if ($container->fileExists($defaultDir)) {
$dirs[] = $defaultDir;
Expand Down
4 changes: 3 additions & 1 deletion src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_AFTER_REMOVING, -255);
$this->addCompilerPassIfExists($container, AddValidatorInitializersPass::class);
$this->addCompilerPassIfExists($container, AddConsoleCommandPass::class, PassConfig::TYPE_BEFORE_REMOVING);
$this->addCompilerPassIfExists($container, TranslatorPass::class);
// must be registered as late as possible to get access to all Twig paths registered in
// twig.template_iterator definition
$this->addCompilerPassIfExists($container, TranslatorPass::class, PassConfig::TYPE_BEFORE_OPTIMIZATION, -32);
$container->addCompilerPass(new LoggingTranslatorPass());
$container->addCompilerPass(new AddExpressionLanguageProvidersPass(false));
$this->addCompilerPassIfExists($container, TranslationExtractorPass::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@
<argument type="service" id="translation.extractor" />
<argument>%translator.default_path%</argument>
<argument /> <!-- %twig.default_path% -->
<argument type="collection" /> <!-- Translator paths -->
<argument type="collection" /> <!-- Twig paths -->
<tag name="console.command" command="debug:translation" />
</service>

Expand All @@ -111,6 +113,8 @@
<argument>%kernel.default_locale%</argument>
<argument>%translator.default_path%</argument>
<argument /> <!-- %twig.default_path% -->
<argument type="collection" /> <!-- Translator paths -->
<argument type="collection" /> <!-- Twig paths -->
<tag name="console.command" command="translation:update" />
</service>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function testDebugDefaultRootDirectory()
$this->fs->mkdir($this->translationDir.'/translations');
$this->fs->mkdir($this->translationDir.'/templates');

$tester = $this->createCommandTester(['foo' => 'foo'], ['bar' => 'bar']);
$tester = $this->createCommandTester(['foo' => 'foo'], ['bar' => 'bar'], null, [$this->translationDir.'/trans'], [$this->translationDir.'/views']);
$tester->execute(['locale' => 'en']);

$this->assertRegExp('/missing/', $tester->getDisplay());
Expand Down Expand Up @@ -145,7 +145,7 @@ protected function tearDown()
/**
* @return CommandTester
*/
private function createCommandTester($extractedMessages = [], $loadedMessages = [], $kernel = null)
private function createCommandTester($extractedMessages = [], $loadedMessages = [], $kernel = null, array $transPaths = [], array $viewsPaths = [])
{
$translator = $this->getMockBuilder('Symfony\Component\Translation\Translator')
->disableOriginalConstructor()
Expand Down Expand Up @@ -207,7 +207,7 @@ private function createCommandTester($extractedMessages = [], $loadedMessages =
->method('getContainer')
->will($this->returnValue($container));

$command = new TranslationDebugCommand($translator, $loader, $extractor, $this->translationDir.'/translations', $this->translationDir.'/templates');
$command = new TranslationDebugCommand($translator, $loader, $extractor, $this->translationDir.'/translations', $this->translationDir.'/templates', $transPaths, $viewsPaths);

$application = new Application($kernel);
$application->add($command);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function testDumpMessagesAndCleanInRootDirectory()
$this->fs->mkdir($this->translationDir.'/translations');
$this->fs->mkdir($this->translationDir.'/templates');

$tester = $this->createCommandTester(['messages' => ['foo' => 'foo']]);
$tester = $this->createCommandTester(['messages' => ['foo' => 'foo']], [], null, [$this->translationDir.'/trans'], [$this->translationDir.'/views']);
$tester->execute(['command' => 'translation:update', 'locale' => 'en', '--dump-messages' => true, '--clean' => true]);
$this->assertRegExp('/foo/', $tester->getDisplay());
$this->assertRegExp('/1 message was successfully extracted/', $tester->getDisplay());
Expand Down Expand Up @@ -121,7 +121,7 @@ protected function tearDown()
/**
* @return CommandTester
*/
private function createCommandTester($extractedMessages = [], $loadedMessages = [], HttpKernel\KernelInterface $kernel = null)
private function createCommandTester($extractedMessages = [], $loadedMessages = [], HttpKernel\KernelInterface $kernel = null, array $transPaths = [], array $viewsPaths = [])
{
$translator = $this->getMockBuilder('Symfony\Component\Translation\Translator')
->disableOriginalConstructor()
Expand Down Expand Up @@ -197,7 +197,7 @@ private function createCommandTester($extractedMessages = [], $loadedMessages =
->method('getContainer')
->will($this->returnValue($container));

$command = new TranslationUpdateCommand($writer, $loader, $extractor, 'en', $this->translationDir.'/translations', $this->translationDir.'/templates');
$command = new TranslationUpdateCommand($writer, $loader, $extractor, 'en', $this->translationDir.'/translations', $this->translationDir.'/templates', $transPaths, $viewsPaths);

$application = new Application($kernel);
$application->add($command);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
* Remove in Symfony 5.0 when the templates directory deprecation is gone.
*/
class TranslationDebugPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if ($container->hasDefinition('console.command.translation_debug')) {
// skipping the /Resources/views path deprecation
$container->getDefinition('console.command.translation_debug')
->setArgument(4, '%kernel.project_dir%/Resources/views');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\AnnotationReaderPass;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\Config\CustomConfig;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\TranslationDebugPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
Expand All @@ -29,5 +30,6 @@ public function build(ContainerBuilder $container)
$extension->setCustomConfig(new CustomConfig());

$container->addCompilerPass(new AnnotationReaderPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new TranslationDebugPass());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;

use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Tester\CommandTester;

/**
* @group functional
*/
class TranslationDebugCommandTest extends WebTestCase
{
private $application;

protected function setUp()
{
$kernel = static::createKernel(['test_case' => 'TransDebug', 'root_config' => 'config.yml']);
$this->application = new Application($kernel);
}

public function testDumpAllTrans()
{
$tester = $this->createCommandTester();
$ret = $tester->execute(['locale' => 'en']);

$this->assertSame(0, $ret, 'Returns 0 in case of success');
$this->assertContains('unused validators This value should be blank.', $tester->getDisplay());
$this->assertContains('unused security Invalid CSRF token.', $tester->getDisplay());
}

private function createCommandTester(): CommandTester
{
$command = $this->application->find('debug:translation');

return new CommandTester($command);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;

return [
new FrameworkBundle(),
new TestBundle(),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
imports:
- { resource: ../config/default.yml }

framework:
secret: '%secret%'
default_locale: '%env(LOCALE)%'
translator:
fallbacks:
- '%env(LOCALE)%'

parameters:
env(LOCALE): en
secret: test
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"symfony/property-info": "<3.4",
"symfony/serializer": "<4.2",
"symfony/stopwatch": "<3.4",
"symfony/translation": "<4.2",
"symfony/translation": "<4.3",
"symfony/twig-bridge": "<4.1.1",
"symfony/validator": "<4.1",
"symfony/workflow": "<4.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,16 @@ public function process(ContainerBuilder $container)
return;
}

$paths = array_keys($container->getDefinition('twig.template_iterator')->getArgument(2));
if ($container->hasDefinition($this->debugCommandServiceId)) {
$container->getDefinition($this->debugCommandServiceId)->replaceArgument(4, $container->getParameter('twig.default_path'));
$definition = $container->getDefinition($this->debugCommandServiceId);
$definition->replaceArgument(4, $container->getParameter('twig.default_path'));
$definition->replaceArgument(6, $paths);
}

if ($container->hasDefinition($this->updateCommandServiceId)) {
$container->getDefinition($this->updateCommandServiceId)->replaceArgument(5, $container->getParameter('twig.default_path'));
$definition = $container->getDefinition($this->updateCommandServiceId);
$definition->replaceArgument(5, $container->getParameter('twig.default_path'));
$definition->replaceArgument(7, $paths);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,32 @@ public function testValidCollector()
$expected = ['translation.xliff_loader' => new ServiceClosureArgument(new Reference('translation.xliff_loader'))];
$this->assertEquals($expected, $container->getDefinition((string) $translator->getArgument(0))->getArgument(0));
}

public function testValidCommandsViewPathsArgument()
{
$container = new ContainerBuilder();
$container->register('translator.default')
->setArguments([null, null, null, null])
;
$debugCommand = $container->register('console.command.translation_debug')
->setArguments([null, null, null, null, null, [], []])
;
$updateCommand = $container->register('console.command.translation_update')
->setArguments([null, null, null, null, null, null, [], []])
;
$container->register('twig.template_iterator')
->setArguments([null, null, ['other/templates' => null, 'tpl' => 'App']])
;
$container->setParameter('twig.default_path', 'templates');

$pass = new TranslatorPass('translator.default');
$pass->process($container);

$expectedViewPaths = ['other/templates', 'tpl'];

$this->assertSame('templates', $debugCommand->getArgument(4));
$this->assertSame('templates', $updateCommand->getArgument(5));
$this->assertSame($expectedViewPaths, $debugCommand->getArgument(6));
$this->assertSame($expectedViewPaths, $updateCommand->getArgument(7));
}
}