Symfony2 залогинен пользователем в обработчик событий доктрины

Я создал класс прослушивателя событий для методов доктрины postPersist, PostUpdate и postRemove.

Мне нужно войти в систему с идентификатором пользователя в моем классе, я пробовал вводить @security.context , @security.token_storage а также @session
Я получил ошибку круговой ссылки, даже если я пытался ввести @service_container и использовать container->get() я получил ту же ошибку круговой ссылки.

ServiceCircularReferenceException: обнаружена циклическая ссылка для> службы «doctrine.orm.default_entity_manager»

мой код в коде serviec.yml похож

    my.listener:
class: \projectCreateEventListener
arguments: ["@service_container"]
tags:
- { name: doctrine.event_listener, event: postPersist }
- { name: doctrine.event_listener, event: postUpdate }
- { name: doctrine.event_listener, event: postRemove }

мой класс слушателя событий похож

    class myListener
{
private $container;

public function
__construct(ContainerInterface $container)
{
$this->container = $container;
}

public function prePersist(LifeCycleEventArgs $args)
{
$entity = $args->getEntity();

//Circular reference error
$user = $this->container->get('security.context')-
>getToken()->getUser();

//getToken() is always null

//Circular reference error
$user = $this->container->get('security.token_storage')-
>getToken()->getUser();

//getToken() is always null

//Circular reference error
$userId = $this->container->get('auth.user')-
>getIdentity()['id'];
}
}

Хотя я получаю информацию о пользователе в моем коде раньше $this->persist() в $this->container->get('auth.user')->getIdentity()['id'];

0

Решение

Это сложно. При создании сервиса доктрины слушатель прикрепляется при конструировании. Если слушатель, которого вы пытаетесь создать, использует другой сервис (или какой-либо другой сервис в дальнейшем), который требует доктрины, вы получаете циклическую ссылку.

Но вы можете построить вокруг этого.

  1. Вставьте eventDispatcher в ваш слушатель
  2. Создать пользовательское событие (или несколько) http://symfony.com/doc/current/components/event_dispatcher.html#creating-and-dispatching-an-event
  3. Отправьте событие в методы prePersist, postPersists.
  4. Создайте другого слушателя, который подписывается на ваше пользовательское событие и обрабатывает вашу логику там.

Это достигается следующим образом: ваш пользовательский прослушиватель событий будет инициализирован только тогда, когда ваше пользовательское событие действительно будет запущено. На этом этапе такие важные сервисы, как доктрина, уже запущены и работают, и вы избегаете проблемы циклических ссылок.

У меня была похожая проблема в моем проекте, и я решил ее таким образом. Не совсем уверен, что это самый элегантный способ, но он определенно работает. (Если у кого-то есть лучшее решение, я бы тоже его приветствовал).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]