Замена службы переводчика в Symfony 3

В моем проекте Symfony 2.8 у меня есть расширение, которое добавляет дополнительную процедуру к методу trans :

parameters: translator.class: MyBundle\Twig\TranslationExtension 

Класс выглядит следующим образом:

 namespace MyBundle\Twig\TranslationExtension; use Symfony\Bundle\FrameworkBundle\Translation\Translator as BaseTranslator; class TranslationExtension extends BaseTranslator { private $currentLocale; public function trans($id, array $parameters = array(), $domain = null, $locale = null) { $translation = parent::trans($id, $parameters, $domain, $locale); // Some extra logic here return $translation; } public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null) { return parent::transChoice($id, $number, $parameters, $domain, $locale); } } 

Теперь я перехожу на Symfony 3, где эти параметры класса устарели, но как я могу реализовать это, перезаписав услугу переводчика ?

Вместо того, чтобы расширяться, было бы лучше украсить услугу translator . Прямо сейчас вы переопределяете имя класса, которое также будет переопределять другие пакеты, которые хотят украсить службу. И я вижу, что вы сделали его расширением из-за Twig, оригинальный фильтр Twig {{ trans() }} будет использовать украшенный сервис.

 services: app.decorating_translator: class: AppBundle\DecoratingTranslator decorates: translator arguments: ['@app.decorating_translator.inner'] # original translator public: false 

См. Документацию об украшении здесь: http://symfony.com/doc/current/service_container/service_decoration.html

Вот полный рабочий пример, как украсить сервис переводчика в symfony 3 и заменить параметр во всех переведенных строках.

Украсить сервис в config:

 # app/config/services.yml app.decorating_translator: class: AppBundle\Translation\Translator decorates: translator arguments: - '@app.decorating_translator.inner' # passing custom parameters - {'%%app_name%%': '%app_name%', '%%PRETTY_ERROR%%': 'This is not nice:'} public: false 

Создайте новый переводчик, который повторно использует оригинальный переводчик и добавляет параметры, определенные в конфигурации службы. Единственный новый код – updateParameters() и вызывает его:

 # AppBundle/Translation/Translator.php namespace AppBundle\Translation; use Symfony\Component\Translation\TranslatorBagInterface; use Symfony\Component\Translation\TranslatorInterface; class Translator implements TranslatorInterface, TranslatorBagInterface { /** @var TranslatorBagInterface|TranslatorInterface */ protected $translator; /** @var array */ private $parameters; /** * @param TranslatorInterface|TranslatorBagInterface $translator * @param array $parameters */ public function __construct($translator, $parameters) { $this->translator = $translator; $this->parameters = $parameters; } /** * @param string $id * @param array $parameters * @param null $domain * @param null $locale * * @return string */ public function trans($id, array $parameters = [], $domain = null, $locale = null) { $parameters = $this->updateParameters($parameters); return $this->translator->trans($id, $parameters, $domain, $locale); } /** * @param string $id * @param int $number * @param array $parameters * @param null $domain * @param null $locale * * @return string */ public function transChoice($id, $number, array $parameters = [], $domain = null, $locale = null) { $parameters = $this->updateParameters($parameters); return $this->translator->transChoice($id, $number, $parameters, $domain, $locale); } /** * @param string $locale */ public function setLocale($locale) { $this->translator->setLocale($locale); } /** * @return string */ public function getLocale() { return $this->translator->getLocale(); } /** * @param string|null $locale * * @return \Symfony\Component\Translation\MessageCatalogueInterface */ public function getCatalogue($locale = null) { return $this->translator->getCatalogue($locale); } /** * @param array $parameters * * @return array */ protected function updateParameters($parameters) { return array_merge($this->parameters, $parameters); } } 

Теперь каждый раз, когда вы переводите сообщение, %app_config% заменяется параметром из config (например, parameters.yml), а %PRETTY_ERROR% заменяется статической строкой. При необходимости можно переопределить такие же параметры при вызове trans:

{{ 'layout.title.home'|trans({'%app_name%': 'Real App No. 1'}) }}

Читайте об украшении услуги здесь