Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature #10887 [Translation] added LoggingTranslator. (aitboudad)
This PR was squashed before being merged into the 2.6-dev branch (closes #10887). Discussion ---------- [Translation] added LoggingTranslator. | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #3015, #2435 | License | MIT | Doc PR | symfony/symfony-docs/pull/4050 Commits ------- b7770bc [Translation] added LoggingTranslator.
- Loading branch information
Showing
14 changed files
with
385 additions
and
7 deletions.
There are no files selected for viewing
39 changes: 39 additions & 0 deletions
39
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/LoggingTranslatorPass.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; | ||
|
||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
|
||
/** | ||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com> | ||
*/ | ||
class LoggingTranslatorPass implements CompilerPassInterface | ||
{ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
if (!$container->hasAlias('logger')) { | ||
return; | ||
} | ||
|
||
if ($container->getParameter('translator.logging')) { | ||
$translatorAlias = $container->getAlias('translator'); | ||
$definition = $container->getDefinition((string) $translatorAlias); | ||
$class = $container->getParameterBag()->resolveValue($definition->getClass()); | ||
|
||
$refClass = new \ReflectionClass($class); | ||
if ($refClass->implementsInterface('Symfony\Component\Translation\TranslatorInterface') && $refClass->implementsInterface('Symfony\Component\Translation\TranslatorBagInterface')) { | ||
$container->getDefinition('translator.logging')->setDecoratedService('translator'); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
...y/Bundle/FrameworkBundle/Tests/DependencyInjection/Compiler/LoggingTranslatorPassTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\Compiler; | ||
|
||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\LoggingTranslatorPass; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Definition; | ||
|
||
class LoggingTranslatorPassTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
public function testProcess() | ||
{ | ||
$definition = $this->getMock('Symfony\Component\DependencyInjection\Definition'); | ||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); | ||
$parameterBag = $this->getMock('Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface'); | ||
|
||
$container->expects($this->once()) | ||
->method('hasAlias') | ||
->will($this->returnValue(true)); | ||
|
||
$container->expects($this->once()) | ||
->method('getParameter') | ||
->will($this->returnValue(true)); | ||
|
||
$container->expects($this->once()) | ||
->method('getAlias') | ||
->will($this->returnValue('translation.default')); | ||
|
||
$container->expects($this->exactly(2)) | ||
->method('getDefinition') | ||
->will($this->returnValue($definition)); | ||
|
||
$definition->expects($this->once()) | ||
->method('getClass') | ||
->will($this->returnValue("%translator.class%")); | ||
|
||
$parameterBag->expects($this->once()) | ||
->method('resolveValue') | ||
->will($this->returnValue("Symfony\Bundle\FrameworkBundle\Translation\Translator")); | ||
|
||
$container->expects($this->once()) | ||
->method('getParameterBag') | ||
->will($this->returnValue($parameterBag)); | ||
|
||
$pass = new LoggingTranslatorPass(); | ||
$pass->process($container); | ||
} | ||
|
||
public function testThatCompilerPassIsIgnoredIfThereIsNotLoggerDefinition() | ||
{ | ||
$container = $this->getMock('Symfony\Component\DependencyInjection\ContainerBuilder'); | ||
$container->expects($this->once()) | ||
->method('hasAlias') | ||
->will($this->returnValue(false)); | ||
|
||
$pass = new LoggingTranslatorPass(); | ||
$pass->process($container); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
src/Symfony/Component/Translation/LoggingTranslator.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the Symfony package. | ||
* | ||
* (c) Fabien Potencier <fabien@symfony.com> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Symfony\Component\Translation; | ||
|
||
use Psr\Log\LoggerInterface; | ||
|
||
/** | ||
* @author Abdellatif Ait boudad <a.aitboudad@gmail.com> | ||
*/ | ||
class LoggingTranslator implements TranslatorInterface | ||
{ | ||
/** | ||
* @var TranslatorInterface | ||
*/ | ||
private $translator; | ||
|
||
/** | ||
* @var LoggerInterface | ||
*/ | ||
private $logger; | ||
|
||
/** | ||
* @param Translator $translator | ||
* @param LoggerInterface $logger | ||
*/ | ||
public function __construct($translator, LoggerInterface $logger) | ||
{ | ||
if (!($translator instanceof TranslatorInterface && $translator instanceof TranslatorBagInterface)) { | ||
throw new \InvalidArgumentException(sprintf('The Translator "%s" must implements TranslatorInterface and TranslatorBagInterface.', get_class($translator))); | ||
} | ||
|
||
$this->translator = $translator; | ||
$this->logger = $logger; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function trans($id, array $parameters = array(), $domain = null, $locale = null) | ||
{ | ||
$trans = $this->translator->trans($id, $parameters , $domain , $locale); | ||
$this->log($id, $domain, $locale); | ||
|
||
return $trans; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) | ||
{ | ||
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale); | ||
$this->log($id, $domain, $locale); | ||
|
||
return $trans; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @api | ||
*/ | ||
public function setLocale($locale) | ||
{ | ||
$this->translator->setLocale($locale); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* | ||
* @api | ||
*/ | ||
public function getLocale() | ||
{ | ||
return $this->translator->getLocale(); | ||
} | ||
|
||
/** | ||
* Passes through all unknown calls onto the translator object. | ||
*/ | ||
public function __call($method, $args) | ||
{ | ||
return call_user_func_array(array($this->translator, $method), $args); | ||
} | ||
|
||
/** | ||
* Logs for missing translations. | ||
* | ||
* @param string $id | ||
* @param string|null $domain | ||
* @param string|null $locale | ||
*/ | ||
private function log($id, $domain, $locale) | ||
{ | ||
if (null === $locale) { | ||
$locale = $this->getLocale(); | ||
} | ||
|
||
if (null === $domain) { | ||
$domain = 'messages'; | ||
} | ||
|
||
$id = (string) $id; | ||
$catalogue = $this->translator->getCatalogue($locale); | ||
if ($catalogue->defines($id, $domain)) { | ||
return; | ||
} | ||
|
||
if ($catalogue->has($id, $domain)) { | ||
$this->logger->debug('Translation use fallback catalogue.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale())); | ||
} else { | ||
$this->logger->warning('Translation not found.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale())); | ||
} | ||
} | ||
} |
Oops, something went wrong.