<?php
namespace App\EventListener;
use App\Entity\BuyersGroup;
use App\Entity\PrivateUser;
use App\Entity\ProUser;
use App\Entity\User;
use App\Live\SocketNotifier;
use App\Mailer\UserMailer;
use Doctrine\ORM\EntityManagerInterface;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
class UserSubscriber implements EventSubscriberInterface
{
protected $mailer;
protected $userManager;
protected $session;
protected $router;
protected $tokenStorage;
public function __construct(
UserMailer $mailer,
UserManagerInterface $userManager,
private readonly EntityManagerInterface $em,
SessionInterface $session,
RouterInterface $router,
TokenStorageInterface $tokenStorage,
private readonly SocketNotifier $notifier
) {
$this->mailer = $mailer;
$this->userManager = $userManager;
$this->session = $session;
$this->router = $router;
$this->tokenStorage = $tokenStorage;
}
public static function getSubscribedEvents()
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'onSecurityInteractiveLogin',
FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationCompleted',
KernelEvents::RESPONSE => 'onKernelResponse',
];
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event): void
{
$this->notifier->disable();
$user = $event->getAuthenticationToken()->getUser();
$selections = $this->session->get('selections', []);
if (is_array($selections) && count($selections) > 0) {
$selectionVehicleIds = $this->em->getRepository(\App\Entity\Selection::class)->findActiveVehicleIdsByUser($user);
$vehicles = $this->em->getRepository(\App\Entity\Vehicle::class)->findById($selections);
foreach ($vehicles as $vehicle) {
if (!in_array($vehicle->getId(), $selectionVehicleIds)) {
$user->addSelection($vehicle);
}
}
}
if ($user instanceof ProUser && !in_array(BuyersGroup::ONLINE_GROUP, $user->getBuyersGroups()->toArray())) {
$proBuyersGroup = $this->em->getRepository(BuyersGroup::class)->findOneByName(BuyersGroup::ONLINE_GROUP);
if (null !== $proBuyersGroup) {
$proBuyersGroup->addUser($user);
}
}
if ($user instanceof PrivateUser && in_array(BuyersGroup::ONLINE_GROUP, $user->getBuyersGroups()->toArray())) {
$proBuyersGroup = $this->em->getRepository(BuyersGroup::class)->findOneByName(BuyersGroup::ONLINE_GROUP);
if (null !== $proBuyersGroup) {
$proBuyersGroup->removeUser($user);
}
}
$this->em->flush();
}
public function onRegistrationCompleted(FilterUserResponseEvent $event): void
{
$user = $event->getUser();
if (!$user instanceof ProUser) {
return;
}
$this->mailer->sendNewProRegistrationAlert($user);
}
public function onKernelResponse(ResponseEvent $event): void
{
if (null === $this->tokenStorage->getToken()) {
return;
}
/** @var User|null $user */
$user = $this->tokenStorage->getToken()->getUser();
if (null === $user || 'anon.' === $user) {
return;
}
if (false === $user->isEnabled()) {
if (User::ORIGIN_SHOWVROOM === $user->getOrigin()) {
$request = $event->getRequest();
// User has no confirmation token until they send documents on step 3 of registration form
if ($event->isMainRequest()
&& (!$user->getConfirmationToken())
&& !in_array($request->get('_route'), [
'fos_user_registration_register_pro',
'fos_user_registration_register_pro_step',
'frontend_cgv_validation',
], true)) {
$event->setResponse(new RedirectResponse($this->router->generate('fos_user_registration_register_pro')));
}
return;
}
$event->setResponse(new RedirectResponse($this->router->generate('fos_user_security_logout')));
}
}
}