【问题标题】:Circular reference Doctrine - Twig循环参考学说 - Twig
【发布时间】:2015-07-20 05:13:12
【问题描述】:

我在应用程序用户注册,并希望在注册时通过电子邮件通知。我为此服务创建:

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 }

模板 - TwigEngine

邮件服务类:

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);
}
}

和用户订阅者监听器:

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',
    );
}
}

当我尝试添加新用户时,出现异常:

检测到服务“security.authorization_checker”的循环引用,路径:“sensio_framework_extra.security.listener -> security.authorization_checker -> security.authentication.manager -> security.user.provider.concrete.entity_provider -> dictionary.orm .default_entity_manager -> 学说.dbal.default_connection -> app.listener.user -> app.mail_service -> 模板 -> twig -> security.context”。

据我了解,发生错误是因为 Twig 尝试使用 EntityManager 进行安全检查。

this的文章中,作者使用了一个简单的方案,但是在Doctrine EventListener的Twig中也有使用。那不是抛出异常。

【问题讨论】:

    标签: php security symfony doctrine-orm twig


    【解决方案1】:

    我想说避免循环引用的最简洁的方法是将事件调度程序注入到您的原则侦听器中。然后在学说监听器中调度一个用户注册的事件,该事件将有一个 Symfony 内核监听器,然后可以发送电子邮件。

    教义订阅者

    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',
            );
        }
    }
    

    用户事件

    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 订阅者

    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());
        }
    }
    

    服务

    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 }
    

    【讨论】:

    • 感谢您的回答。一切正常,我没有类 UserRegistrationMailSubscriber,在 MailService 中实现 EventSubscriberInterface
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多