简体   繁体   English

循环参考主义 - 树枝

[英]Circular reference Doctrine - Twig

I do in the application user registration, and I want to be notified by email when registering. 我在应用程序用户注册中,我想在注册时通过电子邮件通知我。 I created for this services: 我为这项服务创建了:

app.mail_service:
    class: AppBundle\Mail\MailService
    arguments: ["@mailer", "@templating"]

app.listener.user:
    class: AppBundle\EventListener\UserSubscriber
    arguments: ["@app.mail_service"]
    tags:
        - { name: doctrine.event_subscriber, connection: default }

templating - TwigEngine 模板 - TwigEngine

MailService class: MailService类:

class MailService
{
private $mailer;

private $renderer;

public function __construct(Swift_Mailer $mailer, EngineInterface $renderer)
{
    $this->mailer = $mailer;
    $this->renderer = $renderer;
}

/**
 * @return Swift_Mailer
 */
public function getMailer()
{
    return $this->mailer;
}

/**
 * @return EngineInterface
 */
public function getRenderer()
{
    return $this->renderer;
}

public function sendRegistrationMail(User $user)
{
    /** @var \Swift_Message $message */
    $message = $this->getMailer()
        ->createMessage();

    $message->setSubject('You successful register in website')
        ->addTo($user->getEmail())
        ->setBody($this->getRenderer()->render('AppBundle:Mail:register.html.twig', array(
            'user' => $user
        )), 'text/html', 'UTF-8');

    return $this->getMailer()->send($message);
}
}

And User subscriber listener: 和用户订阅者:

class UserSubscriber implements EventSubscriber
{
/**
 * @var MailService
 */
private $mailService;

public function __construct(MailService $mailService)
{
    $this->mailService = $mailService;
}

public function postPersist(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();
    if ($entity instanceof User) {
        $this->mailService->sendRegistrationMail($entity);
    }
}

/**
 * Returns an array of events this subscriber wants to listen to.
 *
 * @return array
 */
public function getSubscribedEvents()
{
    return array(
        'postPersist',
    );
}
}

When I try to add a new user, I get the exception: 当我尝试添加新用户时,我得到了异常:

Circular reference detected for service "security.authorization_checker", path: "sensio_framework_extra.security.listener -> security.authorization_checker -> security.authentication.manager -> security.user.provider.concrete.entity_provider -> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> app.listener.user -> app.mail_service -> templating -> twig -> security.context". 检测到服务“security.authorization_checker”的循环引用,路径:“sensio_framework_extra.security.listener - > security.authorization_checker - > security.authentication.manager - > security.user.provider.concrete.entity_provider - > doctrine.orm.default_entity_manager - > doctrine.dbal.default_connection - > app.listener.user - > app.mail_service - > templating - > twig - > security.context“。

As I understand it, the error occurs due to the fact that the Twig tries to EntityManager for Security checker. 据我所知,错误发生的原因是Twig尝试使用EntityManager进行安全检查。

In this article, the author uses a simple scheme, but there is also used in the Twig in Doctrine EventListener. 文章中,作者用一个简单的方案,但也被树枝在教义事件监听使用。 That is not throwing exceptions. 这不是抛出异常。

I would say the cleanest approach to avoid a circular reference would be inject the event dispatcher to your doctrine listener. 我想说避免循环引用的最干净的方法是将事件调度程序注入你的学说监听器。 Then in the doctrine listener dispatch a user registered event that would then have a Symfony kernel listener that can then send the email. 然后在doctrine listener中调度一个用户注册的事件,然后该事件将有一个Symfony内核侦听器,然后可以发送该电子邮件。

Doctrine Subscriber 学说订阅者

class UserSubscriber implements EventSubscriber
{
    /**
     * @var EventDispatcherInterface
     */
    private $dispatcher;

    public function __construct(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof User) {
            $dispatcher->dispatch('acme.user.registered', new UserEvent($user));
        }
    }

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return array(
            'postPersist',
        );
    }
}

User Event 用户事件

class UserEvent extends GenericEvent
{
    public function __construct(User $user, array $arguments = array())
    {
        parent::__construct($user, $arguments);
    }

    /**
     * @return User
     */
    public function getUser()
    {
        return $this->getSubject();
    }
}

Symfony Subscriber Symfony订阅者

class UserRegistrationMailSubscriber implements EventSubscriberInterface
{
    /**
     * @var MailService
     */
    private $mailService;

    public function __construct(MailService $mailService)
    {
        $this->mailService = $mailService;
    }

    /**
     * {@inheritdoc}
     */
    public static function getSubscribedEvents()
    {
        return array(
            'acme.user.registered'  => 'sendRegistrationMail',
        );
    }

    /**
     * @param UserEvent $event
     */
    public function sendRegistrationMail(UserEvent $event)
    {
        $this->mailService->sendRegistrationMail($event->getUser());
    }
}

Services 服务

app.mail_service:
    class: AppBundle\Mail\MailService
    arguments: ["@mailer", "@templating"]

app.doctrine.listener.user:
    class: AppBundle\EventListener\UserSubscriber
    arguments: ["@event_dispatcher"]
    tags:
        - { name: doctrine.event_subscriber, connection: default }

app.kernel.listener.user_registartion_mail:
   class: AppBundle\EventListener\UserRegistrationMailSubscriber
   arguments: ["@app.mail_service"}
   tags:
        - { name: kernel.event_subscriber }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM