vendor/pimcore/pimcore/bundles/CoreBundle/EventListener/Frontend/RoutingListener.php line 117

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\CoreBundle\EventListener\Frontend;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Config;
  17. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  18. use Pimcore\Http\Request\Resolver\SiteResolver;
  19. use Pimcore\Http\RequestHelper;
  20. use Pimcore\Model\Site;
  21. use Pimcore\Routing\RedirectHandler;
  22. use Pimcore\Tool;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  28. use Symfony\Component\HttpKernel\Event\RequestEvent;
  29. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  30. use Symfony\Component\HttpKernel\KernelEvents;
  31. /**
  32.  * Runs before dynamic routing kicks in and resolves site + handles redirects
  33.  *
  34.  * @internal
  35.  */
  36. class RoutingListener implements EventSubscriberInterface
  37. {
  38.     use PimcoreContextAwareTrait;
  39.     /**
  40.      * @param RequestHelper $requestHelper
  41.      * @param RedirectHandler $redirectHandler
  42.      * @param SiteResolver $siteResolver
  43.      * @param Config $config
  44.      */
  45.     public function __construct(
  46.         protected RequestHelper $requestHelper,
  47.         protected RedirectHandler $redirectHandler,
  48.         protected SiteResolver $siteResolver,
  49.         protected Config $config
  50.     ) {
  51.     }
  52.     /**
  53.      * {@inheritdoc}
  54.      */
  55.     public static function getSubscribedEvents()
  56.     {
  57.         return [
  58.             // run with high priority as we need to set the site early
  59.             KernelEvents::REQUEST => ['onKernelRequest'512],
  60.             // run with high priority before handling real errors
  61.             KernelEvents::EXCEPTION => ['onKernelException'64],
  62.         ];
  63.     }
  64.     public function onKernelRequest(RequestEvent $event)
  65.     {
  66.         if (!$event->isMainRequest()) {
  67.             return;
  68.         }
  69.         $request $event->getRequest();
  70.         // handle main domain redirect in admin context
  71.         if ($this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_ADMIN)) {
  72.             $this->handleMainDomainRedirect($eventtrue);
  73.             return;
  74.         }
  75.         if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)) {
  76.             return;
  77.         }
  78.         $path urldecode($request->getPathInfo());
  79.         // resolve current site from request
  80.         $this->resolveSite($request$path);
  81.         // check for override redirects
  82.         $response $this->redirectHandler->checkForRedirect($requesttrue);
  83.         if ($response) {
  84.             $event->setResponse($response);
  85.             return;
  86.         }
  87.         // check for app.php in URL and remove it for SEO puroposes
  88.         $this->handleFrontControllerRedirect($event$path);
  89.         if ($event->hasResponse()) {
  90.             return;
  91.         }
  92.         // redirect to the main domain if specified
  93.         $this->handleMainDomainRedirect($event);
  94.         if ($event->hasResponse()) {
  95.             return;
  96.         }
  97.     }
  98.     public function onKernelException(ExceptionEvent $event)
  99.     {
  100.         // in case routing didn't find a matching route, check for redirects without override
  101.         $exception $event->getThrowable();
  102.         if ($exception instanceof NotFoundHttpException) {
  103.             $response $this->redirectHandler->checkForRedirect($event->getRequest(), false);
  104.             if ($response) {
  105.                 $event->setResponse($response);
  106.             }
  107.         }
  108.     }
  109.     /**
  110.      * Initialize Site
  111.      *
  112.      * @param Request $request
  113.      * @param string $path
  114.      *
  115.      * @return string
  116.      */
  117.     protected function resolveSite(Request $request$path)
  118.     {
  119.         // check for a registered site
  120.         // do not initialize a site if it is a "special" admin request
  121.         if (!$this->requestHelper->isFrontendRequestByAdmin($request)) {
  122.             // host name without port incl. X-Forwarded-For handling for trusted proxies
  123.             $host $request->getHost();
  124.             if ($site Site::getByDomain($host)) {
  125.                 $path $site->getRootPath() . $path;
  126.                 Site::setCurrentSite($site);
  127.                 $this->siteResolver->setSite($request$site);
  128.                 $this->siteResolver->setSitePath($request$path);
  129.             }
  130.         }
  131.         return $path;
  132.     }
  133.     /**
  134.      * @param RequestEvent $event
  135.      * @param string $path
  136.      */
  137.     protected function handleFrontControllerRedirect(RequestEvent $event$path)
  138.     {
  139.         $request $event->getRequest();
  140.         // do not allow requests including /app.php/ => SEO
  141.         // this is after the first redirect check, to allow redirects in app.php?xxx
  142.         if (preg_match('@^/app\.php(.*)@'$path$matches) && $request->getMethod() === 'GET') {
  143.             $redirectUrl $matches[1];
  144.             $redirectUrl ltrim($redirectUrl'/');
  145.             $redirectUrl '/' $redirectUrl;
  146.             $event->setResponse(new RedirectResponse($redirectUrlResponse::HTTP_MOVED_PERMANENTLY));
  147.         }
  148.     }
  149.     /**
  150.      * Redirect to the main domain if specified
  151.      *
  152.      * @param RequestEvent $event
  153.      * @param bool $adminContext
  154.      */
  155.     protected function handleMainDomainRedirect(RequestEvent $eventbool $adminContext false)
  156.     {
  157.         $request $event->getRequest();
  158.         $hostRedirect null;
  159.         if ($adminContext) {
  160.             $hostRedirect $this->resolveConfigDomainRedirectHost($request);
  161.         } else {
  162.             if (Site::isSiteRequest()) {
  163.                 $site Site::getCurrentSite();
  164.                 if ($site->getRedirectToMainDomain() && $site->getMainDomain() != $request->getHost()) {
  165.                     $hostRedirect $site->getMainDomain();
  166.                 }
  167.             } else {
  168.                 if (!$this->requestHelper->isFrontendRequestByAdmin()) {
  169.                     $hostRedirect $this->resolveConfigDomainRedirectHost($request);
  170.                 }
  171.             }
  172.         }
  173.         if ($hostRedirect && !$request->query->has('pimcore_disable_host_redirect')) {
  174.             $qs '';
  175.             if (null !== $qs $request->getQueryString()) {
  176.                 $qs '?' $qs;
  177.             }
  178.             $url $request->getScheme() . '://' $hostRedirect $request->getBaseUrl() . $request->getPathInfo() . $qs;
  179.             // TODO use symfony logger service
  180.             // log all redirects to the redirect log
  181.             \Pimcore\Log\Simple::log('redirect'Tool::getAnonymizedClientIp() . " \t Host-Redirect Source: " $request->getRequestUri() . ' -> ' $url);
  182.             $event->setResponse(new RedirectResponse($urlResponse::HTTP_MOVED_PERMANENTLY));
  183.         }
  184.     }
  185.     private function resolveConfigDomainRedirectHost(Request $request)
  186.     {
  187.         $hostRedirect null;
  188.         $gc $this->config['general'];
  189.         if (isset($gc['redirect_to_maindomain']) && $gc['redirect_to_maindomain'] === true && isset($gc['domain']) && $gc['domain'] !== $request->getHost()) {
  190.             $hostRedirect $gc['domain'];
  191.         }
  192.         return $hostRedirect;
  193.     }
  194. }