Как заставить службу работать в обработчике событий жизненного цикла

У меня есть сервис, который я использую в разных местах в моем проекте. В моих контроллерах это работает отлично.

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

Попытка вызвать метод «get» в классе
«Xx \ ххх \ XxxxBundle \ Lib \ Ыыыы \ OrderUserListener».

Я думаю, что я понимаю, что я должен внедрить свой сервис в моем слушателе событий, но я не понимаю, как это сделать.

Вот как OrderUserListener а также OrderLogger сервисы выглядят соответственно в файле service.yml;

bss.pmod.current_user_id:
class: Xx\Xxx\XxxxBundle\Lib\Yyyy\OrderUserListener
calls:
- [ setServiceContainer, [@service_container] ]
tags:
- { name: doctrine.event_listener, event: prePersist }

bss.pmod.order_logger:
class: Xx\Xxx\XxxxBundle\Lib\Yyyy\OrderLogger
arguments: [ "@doctrine.orm.entity_manager", "@security.token_storage" ]

И это моя функция OrderLogger, которую я хочу добавить в мой сервис;

class OrderLogger {

private $em;
private $tokenStorage;

/**
* Constructor.
*
* @param EntityManager $em
* @param TokenStorage $securityTokenStorage
*/
public function __construct(EntityManager $em, TokenStorage $securityTokenStorage)
{
$this->em = $em;
$this->tokenStorage = $securityTokenStorage;
}

/**
* Log an order action.
*
* @param string $text
*/
public function log($order, $action)
{
$logRecord = new PmodLog();
if (is_object($this->tokenStorage->getToken())) {
$user = $this->tokenStorage->getToken()->getUser();
if (is_object($user)) {
$logRecord->setUser($user);
}
}
$logRecord->setOrder($order);
$logRecord->setAction($action);
$logRecord->setTime(new \DateTime());

$this->em->persist($logRecord);
$this->em->flush();
}

}

Мой слушатель событий выглядит так;

class OrderUserListener
{

/**
* Service container
* @var type
*/
private $serviceContainer;

/**
* Performs tasks before destruction
* @ORM\PrePersist
*/
public function prePersist(LifecycleEventArgs $args)
{
$order = $args->getEntity();

if ($order instanceof PmodOrder) {
$user = $this->serviceContainer->get('security.token_storage')->getToken()->getUser();

if ($user) {
$order->setCreatedBy($user);
$order->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
$order->setDepartment($user->getDepartment());
$order->setStatus(PmodOrder::STATUS_AWAITING_APPROVAL);

//$this->get('bss.pmod.order_logger')->log($order, 'Order Created');      // This is then clearly wrong.
}
}
}

/**
* Sets the sales order exporter object
* @param type $serviceContainer
*/
public function setServiceContainer($serviceContainer)
{
$this->serviceContainer = $serviceContainer;
}
}

Если кто-то может объяснить мне, показывая, как это сделать с моим образцом, я буду очень признателен за это.

0

Решение

Во-первых, похоже, что вы смешиваете ContainerAwareInterface (сейчас не рекомендуется в пользу ContainerAwareTrait) с Symfony’s Controller Базовый класс. ContainerAwareInterface предназначен для различения классов, которым требуется внедрить контейнер службы, и контроллеры получают его автоматически. Так как кажется, что эта строка работает:

$user = $this->serviceContainer->get('security.token_storage')->getToken()->getUser();

, похоже, что контейнер введен правильно.

get() метод, который вы пытаетесь вызвать из вашего сервиса на самом деле напоминает мне о Controller«s get() метод. Но ваш класс не является потомком Controllerи ни в коем случае это, на самом деле, контроллер, насколько я могу судить.

Что нужно делать вместо звонка get() вот вызов контейнера:

$logger = $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');

Однако службы ContainerAware обычно считаются плохой практикой. Вместо этого вы можете добавить сервисы напрямую через конструктор:

# Service definition
bss.pmod.current_user_id:
class: Xx\Xxx\XxxxBundle\Lib\Yyyy\OrderUserListener
arguments:
- "@security.token_storage"- "@bss.pmod.order_logger"tags:
- { name: doctrine.event_listener, event: prePersist }

class OrderUserListener
{
private $tokenStorage;

private $logger;

public function __construct($tokenStorage, $logger)
{
$this->tokenStorage = $tokenStorage;
$this->logger = $logger;
}

// ...

public function prePersist(LifecycleEventArgs $args)
{
// ...

// Here you can call the injected services:
$user = $this->tokenStorage->getToken()->getUser();

$this->logger->log($order, 'Created');
}
}
1

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

+ Изменить $this->get('bss.pmod.order_logger')->log($order, 'Order Created'); в $this->serviceContainer->get('bss.pmod.order_logger')->log($order, 'Order Created');

-1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector