У меня есть устаревшее приложение symfony2, которое я пытаюсь обновить для работы на 3.4 LTS. В приложении есть зарегистрированный сервис - класс, расширенный с Symfony\Bundle\FrameworkBundle\Translation\Translator
и имеющий только один переопределенный метод. Внутри этого метода мы добавляем переводы из таблицы БД, специфичные для этого самого арендатора (приложение является мультитенантным и основано на поддоменах):
protected function loadCatalogue($locale)
{
parent::loadCatalogue($locale);
$twig = $this->container->get('twig');
//then we fetch the tenant entity from Twig globals
Это расширение службы подключено services.xml
, как:
<service id="translator.default" class="Path\ToBundle\Translation\Class">
<argument type="service" id="service_container" />
<argument type="service" id="translator.selector" />
<argument type="string" >%locale%</argument>
<argument type="collection" />
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
<argument key="debug">%kernel.debug%</argument>
</argument>
</service>
Теперь проблема в том, что при запуске этого кода среда сообщает мне, что этот контейнер службы знает только о специфичных для переводчика компонентах, таких как "translation.loader.csv", "translation.loader.dat" и так далее. Что правильно с точки зрения DI и скрывает другие ненужные для этого компонента. Но мне нужно как-то получить компонент ветки из контейнера приложения.
PS. Напоминаем, что базовый конструктор Symfony\Bundle\FrameworkBundle\Translation\Translator
выглядит так:
* @param ContainerInterface $container A ContainerInterface instance
* @param MessageFormatterInterface $formatter The message formatter
* @param string $defaultLocale
* @param array $loaderIds An array of loader Ids
* @param array $options An array of options
*
* @throws InvalidArgumentException
*/
public function __construct(ContainerInterface $container, $formatter, $defaultLocale = null, array $loaderIds = array(), array $options = array())
{
UPDATE:
Используя подсказку из первого ответа, я ввел параметр $twig
в конструктор моего сервиса:
вот сервис в services.xml:
class MyTranslator extends Translator {
protected $twig;
public function __construct(\Twig_Environment $twig, ContainerInterface $container, MessageFormatterInterface $formatter, $defaultLocale = null, array $loaderIds = array(), array $options = array())
{
parent::__construct($container, $formatter, $defaultLocale, $loaderIds, $options);
$this->twig = $twig;
}
Вот как services.xml
выглядит сейчас:
<service id="translator.default" class="MyBundle\MyTranslator">
<argument type="service" id="twig" />
<argument type="service" id="service_container" />
<argument type="service" id="translator.selector" />
<argument type="string" >%locale%</argument>
<argument type="collection" />
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%/translations</argument>
<argument key="debug">%kernel.debug%</argument>
</argument>
</service>
и вот ошибка, которую я все еще получаю после изменений (без кеша - тестирование в dev env):
Fatal error: Uncaught TypeError: Argument 1 passed to MyBundle\MyTranslator::__construct() must be an instance of Twig_Environment, instance of Symfony\Component\DependencyInjection\ServiceLocator given, called in /path/app/cache/dev/ContainerXk9jorc/appDevDebugProjectContainer.php on line 3883 and defined in /path/MyBundle/Translation/MyTranslator.php on line 22
Кэш очищен, а папка кеша удалена:
root@3e5838c2cff6:/var/www/project# rm -rf app/cache/
root@3e5838c2cff6:/var/www/project# php app/console cache:clear --env=dev
[27-Apr-2018 16:59:30 Europe/Berlin] PHP Fatal error: Uncaught TypeError: Argument 1 passed to MyBundle\Translation\MyTranslator::__construct() must be an instance of Twig_Environment, instance of Symfony\Component\DependencyInjection\ServiceLocator given, called in /var/www/project/app/cache/dev/ContainerKj0tifc/appDevDebugProjectContainer.php on line 3886 and defined in /var/www/project/src/Project/MyBundle/Translation/MyTranslator.php:22