覆盖翻译器Symfony2

时间:2015-07-08 08:54:39

标签: php symfony

我试图覆盖Symfony转换器以从我的数据库中获得一些翻译。 我首先检查翻译是否不在目录中,如果没有从数据库中加载

<?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

从数据库加载转换没有问题。

但是$this->getCatalogue($locale)->has($id, $domain)总是返回false(目录中的翻译在覆盖之前工作)

我的缓存翻译文件夹app/cache/dev/translations未生成

1 个答案:

答案 0 :(得分:0)

您可以使用编译器传递来覆盖默认的翻译器类,并使用setter注入翻译管理器。

你也应该扩展\ Symfony \ Bundle \ FrameworkBundle \ Translation \ Translator,而不是\ 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);
    }
}