Mik*_*lka 6 php security symfony doctrine-orm twig
我在应用程序用户注册中,我想在注册时通过电子邮件通知我.我为这项服务创建了:
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 }
Run Code Online (Sandbox Code Playgroud)
模板 - TwigEngine
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);
}
}
Run Code Online (Sandbox Code Playgroud)
和用户订阅者:
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',
);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试添加新用户时,我得到了异常:
检测到服务"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".
据我所知,错误发生的原因是Twig尝试使用EntityManager进行安全检查.
在此文章中,作者用一个简单的方案,但也被树枝在教义事件监听使用.这不是抛出异常.
我想说避免循环引用的最干净的方法是将事件调度程序注入你的学说监听器.然后在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',
);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
Symfony Subscriber
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());
}
}
Run Code Online (Sandbox Code Playgroud)
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 }
Run Code Online (Sandbox Code Playgroud)