Слушатель Symfony Entity Listener с Swift Mailer и Twig Environment имеет пустую сущность

Я прочитал Документацию Symfony по Entity Listeners и Doctrine Documentation on Entity Listeners в дополнение к этому ответу и эта запись в блоге Эрик Гелоен, но я не могу заставить своего слушателя делать то, что я хочу. В этом объекте у меня есть поле, называемое статусом, и когда это поле изменяется, будет отправлено электронное письмо, уведомляющее получателя об изменении.

Юридическое лицо

У меня есть объект shipmentLine со следующими аннотациями:

<?php
namespace Acme\Bundle\ShipmentBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Expose;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\EntityListeners({"\Acme\Bundle\ShipmentBundle\Listener\ShipmentLineListener"})
 * @ExclusionPolicy("all")
 */
class ShipmentLine
{
    . . .
}

Слушатель

В ShipmentLineListener реализованы функции __construct и prePersist:

<?php
namespace Acme\Bundle\ShipmentBundle\Listener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Acme\Bundle\ShipmentBundle\Entity\ShipmentLine;

class ShipmentLineListener
{
    private $mailer;
    private $twig;

    public function __construct(\Swift_Mailer $mailer, \Twig_Environment $twig)
    {
        $this->mailer = $mailer;
        $this->twig = $twig;
    }

    public function prePersist(ShipmentLine $shipmentLine, LifecycleEventArgs $event)
    {
        /** @var \Swift_Mime_Message $message */
        $message = \Swift_Message::newInstance()
            ->setSubject('Entity Listener test')
            ->setFrom(array('[email protected]' => 'Acme'))
            ->setTo(array('[email protected]' => 'Tommy (Acme)'))
            ->setBody(json_encode($event), 'text/html');

        $this->mailer->send($message);
    }
}

services.yml

Наконец, я зарегистрировал своего слушателя в services.yml.

entity.entity_listener.shipmentline_update:
    class: Acme\Bundle\ShipmentBundle\Listener\ShipmentLineListener
    arguments: [ "@mailer", "@twig" ]
    tags:
        - { name: doctrine.orm.entity_listener, event: prePersist }

Слушатель срабатывает, и почта отправляется. Но оба аргумента $shipmentLine и $event пусты. Может ли кто-нибудь увидеть, если я делаю что-то не так? Мне трудно увидеть какие-либо ошибки из того, что я прочитал.

Спасибо за ваше время.


person pusle    schedule 13.09.2017    source источник
comment
Вам нужно вытащить сущность из события PrePersist. Я удивлен, что вы не получаете сообщения об отсутствующих аргументах. Я думаю, вы уверены, что событие срабатывает.   -  person Cerad    schedule 13.09.2017
comment
Думаю, мне следовало привести пример: symfony.com/ документ/текущая/доктрина/   -  person Cerad    schedule 13.09.2017
comment
Я не мог заставить это работать, и похоже, что речь шла о прослушивателях событий? Я действительно запутался в теме Event Listener/Entity Listener. В документации Doctrine говорится, что метод слушателя сущности получает два аргумента: экземпляр сущности и событие жизненного цикла — в чем смысл экземпляра сущности, если он недоступен. На самом деле меня смущает вся эта чепуха со слушателями и подписчиками :)   -  person pusle    schedule 13.09.2017
comment
Я подозреваю, что вы, возможно, смотрите на более старую версию документации Doctrine. Многое изменилось в 2.4. docs.doctrine-project.org/projects/doctrine-orm/en/latest/   -  person Cerad    schedule 13.09.2017
comment
Спасибо, что нашли время. Подключены ли Entity Listener и Event Listener? Нужен ли прослушиватель событий для использования Entity Listener? Я думаю, что, возможно, мне нужно прочитать об этом. Много.   -  person pusle    schedule 13.09.2017
comment
Нет, это два разных способа достижения одного и того же. Если вы будете следовать подходу прослушивателя сущностей, то сама сущность будет иметь метод prePersist. Используйте этот подход, если вам нужно иметь дело только с одним типом объекта и у вас нет зависимостей, таких как почтовая программа для внедрения. Прослушиватель событий не зависит от объекта и будет вызываться для всех событий prePersist. Это почти наверняка подход, который вы захотите использовать.   -  person Cerad    schedule 13.09.2017
comment
Хорошо, большое спасибо. Я думаю, что тогда мне нужно написать еще один вопрос, потому что у меня были проблемы с получением доступа к связанным сущностям с прослушивателем событий. Мне нужно увидеть, изменился ли статус и на что на объекте на два уровня ниже, чем объект, который сохраняется.   -  person pusle    schedule 13.09.2017
comment
Без проблем. Просто имейте в виду, что доктринальные события очень и очень ограничены. Я упоминал, что они были ограничены? Многие рабочие процессы, которые кажутся простыми в реализации с помощью событий, на самом деле невозможны из-за присущих им ограничений.   -  person Cerad    schedule 13.09.2017
comment
Я начинаю видеть это. Мне нужна помощь в поиске другого способа решения этой проблемы. Большое спасибо за уделенное время.   -  person pusle    schedule 13.09.2017