src/EventSubscriber/HotelRequestSubscriber.php line 48

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Doctrine\HotelFilter;
  4. use App\Entity\Hotel;
  5. use App\Entity\User;
  6. use App\Repository\ComplexRepository;
  7. use App\Repository\HotelRepository;
  8. use App\Service\HotelHelper;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  17. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  18. use Symfony\Component\Security\Core\Security;
  19. use function Symfony\Component\String\u;
  20. class HotelRequestSubscriber implements EventSubscriberInterface
  21. {
  22.     private Security $security;
  23.     private ParameterBagInterface $parameterBag;
  24.     private UrlGeneratorInterface $router;
  25.     private EntityManagerInterface $em;
  26.     private ComplexRepository $complexRepository;
  27.     private HotelRepository $hotelRepository;
  28.     private HotelHelper $hotelHelper;
  29.     private string $baseHost;
  30.     private bool $saasCustomInstall;
  31.     public function __construct(Security $securityParameterBagInterface $parameterBagUrlGeneratorInterface $routerEntityManagerInterface $emComplexRepository $complexRepositoryHotelRepository $hotelRepositoryHotelHelper $hotelHelperstring $baseHostbool $saasCustomInstall)
  32.     {
  33.         $this->security $security;
  34.         $this->parameterBag $parameterBag;
  35.         $this->router $router;
  36.         $this->em $em;
  37.         $this->complexRepository $complexRepository;
  38.         $this->hotelRepository $hotelRepository;
  39.         $this->hotelHelper $hotelHelper;
  40.         $this->baseHost $baseHost;
  41.         $this->saasCustomInstall $saasCustomInstall;
  42.     }
  43.     public function onKernelRequest(RequestEvent $event)
  44.     {
  45.         $request $event->getRequest();
  46.         $route $request->attributes->get('_route');
  47.         // Go ahead if it's a profiler route in dev mode
  48.         $route u($route);
  49.         $isDev $this->parameterBag->get('kernel.environment') === 'dev';
  50.         $isProfilerRoute $route->startsWith('_wdt') || $route->startsWith('_profiler') || $request->getPathInfo() === '/_fragment';
  51.         $isErrorRoute $route->startsWith('_error');
  52.         if ($isDev && ($isProfilerRoute || $isErrorRoute)) {
  53.             return;
  54.         }
  55.         /** @var HotelFilter $filter */
  56.         $filter $this->em->getFilters()->getFilter('hotelfilter');
  57.         // We have to disable filter to allow get hotel without interferences
  58.         $filter->disableForEntity(Hotel::class);
  59.         /** @var User $user */
  60.         $user $this->security->getUser();
  61.         $host $request->getHttpHost();
  62.         $isAdminRoute $route->startsWith('admin_') && !$route->containsAny(['login''logout']);
  63.         $isGuestRoute $route->startsWith('app_') && !$route->containsAny(['login''logout']);
  64.         $isAdminLoginOrLogoutRoute $route->startsWith('admin_') && $route->containsAny(['login''logout']);
  65.         $isGuestLoginOrLogoutRoute $route->startsWith('app_') && $route->containsAny(['login''logout']);
  66.         $subdomain str_replace('.' $this->baseHost''$host);
  67.         $complex $this->complexRepository->findOneBy(['subdomain' => $subdomain]);
  68.         $hotel $this->hotelRepository->findOneBy(['subdomain' => $subdomain]);
  69.         // Avoid infinite redirect loops
  70.         if ($isAdminLoginOrLogoutRoute) {
  71.             return;
  72.         }
  73.         // Redirect base route to admin if using complex subdomain
  74.         if ($isGuestLoginOrLogoutRoute && $complex) {
  75.             $event->setResponse(new RedirectResponse($this->router->generate('admin_login', [], UrlGeneratorInterface::ABSOLUTE_URL)));
  76.             return;
  77.         }
  78.         // Admin domain
  79.         if ($host === 'admin.' $this->baseHost) {
  80.             if (!$this->saasCustomInstall && $isGuestRoute) {
  81.                 throw new AccessDeniedException();
  82.             }
  83.             if (!$user || !$isAdminRoute) {
  84.                 return;
  85.             }
  86.             if (!$this->security->isGranted('ROLE_SUPER_ADMIN')) {
  87.                 throw new AccessDeniedException();
  88.             }
  89.             return;
  90.         }
  91.         // SaaS domain
  92.         if ($host === $this->baseHost) {
  93.             if (!$this->saasCustomInstall && $isGuestRoute) {
  94.                 throw new AccessDeniedException();
  95.             }
  96.             if (!$user || !$isAdminRoute) {
  97.                 return;
  98.             }
  99.             if (!$this->security->isGranted('ROLE_ADMIN')) {
  100.                 throw new AccessDeniedException();
  101.             }
  102.             return;
  103.         }
  104.         // Complex and hotel subdomains
  105.         if ($complex) {
  106.             $hotel $this->hotelHelper->getCurrentHotel($user$complex);
  107.             if (!$complex->getHotels()->contains($hotel)) {
  108.                 throw new AccessDeniedException();
  109.             }
  110.             if (!$hotel) {
  111.                 $hotel $complex->getHotels()->first();
  112.                 if (!$hotel) {
  113.                     throw new AccessDeniedException();
  114.                 }
  115.             }
  116.         }
  117.         if (!$hotel) {
  118.             throw new NotFoundHttpException(sprintf('Subdomain %s does not exist in %s.'$subdomain$this->baseHost));
  119.         }
  120.         if ($user && $isAdminRoute && !$this->hotelHelper->userCanAccessToHotel($user$hotel)) {
  121.             throw new AccessDeniedException();
  122.         }
  123.         $this->hotelHelper->setCurrentHotel($hotel);
  124.         $filter->enableForEntity(Hotel::class);
  125.     }
  126.     public static function getSubscribedEvents(): array
  127.     {
  128.         return [
  129.             // Priority default is 0. This must be lower than 8 because this is the priority for get user in security service.
  130.             KernelEvents::REQUEST => [['onKernelRequest'0]],
  131.         ];
  132.     }
  133. }