src/Bundles/UserBundle/EventListener/UserModifierListener.php line 36

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Bundles\UserBundle\EventListener;
  4. use App\Bundles\OrganizationBundle\Service\UserOrganization\UserOrganizationBinder;
  5. use App\Bundles\UserBundle\Entity\UserInterface;
  6. use App\Bundles\UserBundle\Entity\UserTrial;
  7. use App\Bundles\UserBundle\Service\UserTrial\TrialPeriodProvider;
  8. use App\Platform\Service\AuthenticationTokenProvider;
  9. use App\Platform\Service\SessionProvider;
  10. use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\Routing\RouterInterface;
  15. #[AsEventListener(eventRequestEvent::class, method'onKernelRequest')]
  16. class UserModifierListener
  17. {
  18.     public const CHANGE_PASSWORD_PATH_NAME 'app_password';
  19.     public const EMAIL_CONFIRM_PATH 'app_email_confirm_form';
  20.     public const SELECT_ORGANIZATION_PATH 'app_select_organization';
  21.     public const LOGIN_LINK_REDIRECT_PATH_INFO '/login/redirect';
  22.     public function __construct(
  23.         private readonly RouterInterface $router,
  24.         private readonly SessionProvider $sessionProvider,
  25.         private readonly AuthenticationTokenProvider $tokenProvider,
  26.         private readonly TrialPeriodProvider $trialPeriodProvider,
  27.     ) {
  28.     }
  29.     public function onKernelRequest(RequestEvent $event): void
  30.     {
  31.         if (!$token $this->tokenProvider->getToken()) {
  32.             return;
  33.         }
  34.         if (!$user $token->getUser()) {
  35.             return;
  36.         }
  37.         if ($this->checkLoginLinkRedirect($event->getRequest())) {
  38.             return;
  39.         }
  40.         /** @var UserInterface $user */
  41.         if ($user->hasExpiredPassword()) {
  42.             $this->changePassword($event);
  43.             return;
  44.         }
  45.         $trial $this->trialPeriodProvider->provideByUserEmail($user->getEmail());
  46.         if (
  47.             $this->userHasNotTrialPeriodAndNotVerifiedEmail($user$trial) ||
  48.             $this->isTrialPeriodExpiredAndNotVerifiedEmail($user$trial)
  49.         ) {
  50.             $this->confirmEmail($event$trial);
  51.             return;
  52.         }
  53.         $this->bindOrganization($event);
  54.     }
  55.     private function userHasNotTrialPeriodAndNotVerifiedEmail(UserInterface $user, ?UserTrial $userTrial): bool
  56.     {
  57.         return !$userTrial && !$user->isVerifiedEmail();
  58.     }
  59.     private function isTrialPeriodExpiredAndNotVerifiedEmail(UserInterface $user, ?UserTrial $userTrial): bool
  60.     {
  61.         return ($userTrial && $userTrial->isExpired()) && !$user->isVerifiedEmail();
  62.     }
  63.     private function checkLoginLinkRedirect(Request $request): bool
  64.     {
  65.         return $request->getPathInfo() === self::LOGIN_LINK_REDIRECT_PATH_INFO;
  66.     }
  67.     private function bindOrganization(RequestEvent $event): void
  68.     {
  69.         $session $this->sessionProvider->provide($event->getRequest());
  70.         if ($session->has(UserOrganizationBinder::SESSION_USER_ORGANIZATION_KEY)) {
  71.             return;
  72.         }
  73.         if ($this->validatePath($event->getRequest(), self::SELECT_ORGANIZATION_PATH)) {
  74.             return;
  75.         }
  76.         $this->setResponse($eventself::SELECT_ORGANIZATION_PATH);
  77.     }
  78.     private function confirmEmail(RequestEvent $event, ?UserTrial $trial): void
  79.     {
  80.         if ($this->validatePath($event->getRequest(), self::EMAIL_CONFIRM_PATH)) {
  81.             return;
  82.         }
  83.         if ($trial && !$trial->isExpired()) {
  84.             return;
  85.         }
  86.         $this->setResponse($eventself::EMAIL_CONFIRM_PATH);
  87.     }
  88.     private function changePassword(RequestEvent $event): void
  89.     {
  90.         if ($this->validatePath($event->getRequest(), self::CHANGE_PASSWORD_PATH_NAME)) {
  91.             return;
  92.         }
  93.         $this->setResponse($eventself::CHANGE_PASSWORD_PATH_NAME);
  94.     }
  95.     private function validatePath(Request $requeststring $path): bool
  96.     {
  97.         return (
  98.             $path === $request->attributes->get('_route') || !$request->isMethod('GET')
  99.         );
  100.     }
  101.     private function setResponse(RequestEvent $eventstring $path): void
  102.     {
  103.         $url $this->router->generate($path);
  104.         $event->setResponse(new RedirectResponse($url));
  105.     }
  106. }