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

+3


source to share


1 answer


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);
    }
}

      

0


source







All Articles