Symfony2 Override Translator
I am trying to override the symfony translator to have some translations from my database. I first check if there is a translation in the directory and if it is not loaded from the database
<?php
namespace Competitive\TranslationBundle\Translation;
use Competitive\TranslationBundle\Entity\TranslationManager;
use Symfony\Component\Translation\MessageSelector;
use Symfony\Component\Translation\Translator as BaseTranslator;
class Translator extends BaseTranslator
{
/**
* @var TranslationManager
*/
private $translationManager;
public function __construct($locale, TranslationManager $translationManager, MessageSelector $selector = null, $cacheDir = null, $debug = false)
{
parent::__construct($locale, $selector, $cacheDir, $debug);
$this->translationManager = $translationManager;
}
/**
* {@inheritdoc}
*/
public function trans($id, array $parameters = array(), $domain = null, $locale = null)
{
$catalogueDomain = $domain;
if (null === $catalogueDomain) {
$catalogueDomain = 'messages';
}
$locale = $locale === null ? $this->getLocale() : $locale;
if ($this->getCatalogue($locale)->has($id, $domain)) {
return parent::trans($id, $parameters, $catalogueDomain, $locale);
}
$translations = $this->translationManager->findTranslationsBy([
'key' => $id,
'locale' => $locale
]);
if (empty($translations)) {
$translation = $this->translationManager->create($id, $id, $locale);
} elseif (null === $domain) {
$translation = $translations[0];
} else {
foreach ($translations as $trans) {
if ($trans->getDomain() == $domain) {
$translation = $trans;
break;
}
}
if (!isset($translation)) {
$translation = $translations[0];
}
}
return strtr($translation->getValue(), $parameters);
}
/**
* {@inheritdoc}
*/
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
{
return $this->trans($id, $parameters, $domain, $locale);
}
}
translation.yml
services:
translator:
class: Competitive\TranslationBundle\Translation\Translator
arguments:
- %locale%
- @competitive_translation.translation_manager
The translation is loaded from the database without problems.
But it $this->getCatalogue($locale)->has($id, $domain)
always returns false (translations from the directory worked before overriding)
And my cache translation folder is app/cache/dev/translations
not generated
source to share
You can use the compiler skip to override the default translator class and use the installer to enter the translation manager.
Also you should extend \ Symfony \ Bundle \ FrameworkBundle \ Translation \ Translator, not \ Symfony \ Component \ Translation \ Translator
TranslatorPass.php:
<?php
namespace Competitive\TranslationBundle\DependencyInjection\Compiler;
use Competitive\TranslationBundle\Translation\Translator;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class TranslatorPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('translator.default')) {
return;
}
$definition = $container->getDefinition('translator.default');
$definition->setClass(Translator::class);
$definition->addMethodCall('setTranslationManager', array(new Reference('competitive_translation.translation_manager')));
}
}
TranslationBundle.php:
<?php
namespace Competitive\TranslationBundle;
use Competitive\TranslationBundle\DependencyInjection\Compiler\TranslatorPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class TranslationBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new TranslatorPass());
}
}
Translator.php:
<?php
namespace Competitive\TranslationBundle\Translation;
use Competitive\TranslationBundle\Entity\TranslationManager;
use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator;
class Translator extends BaseTranslator
{
/**
* @var TranslationManager
*/
private $translationManager;
public function setTranslationManager(TranslationManager $translationManager){
$this->translationManager = $translationManager;
}
public function trans($id, array $parameters = array(), $domain = null, $locale = null){
// custom logic
return parent::trans($id, $parameters, $domain, $locale);
}
}
source to share