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
MailService class:
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".
As I understand it, the error occurs due to the fact that the Twig tries to EntityManager for Security checker.
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 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
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With