pimcore/lib/Pimcore/Bundle/CoreBundle/EventListener/Frontend/DocumentFallbackListener.php line 88

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 Enterprise License (PEL)
  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 PEL
  13.  */
  14. namespace Pimcore\Bundle\CoreBundle\EventListener\Frontend;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Http\Request\Resolver\DocumentResolver;
  17. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  18. use Pimcore\Http\Request\Resolver\SiteResolver;
  19. use Pimcore\Model\Document;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\HttpFoundation\RequestStack;
  22. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  23. use Symfony\Component\HttpKernel\KernelEvents;
  24. /**
  25.  * If no document was found on the active request (not set by router or by initiator of a sub-request), try to find and
  26.  * set a fallback document:
  27.  *
  28.  *  - if request is a sub-request, try to read document from master request
  29.  *  - if all fails, try to find the nearest document by path
  30.  */
  31. class DocumentFallbackListener implements EventSubscriberInterface
  32. {
  33.     use PimcoreContextAwareTrait;
  34.     /**
  35.      * @var RequestStack
  36.      */
  37.     protected $requestStack;
  38.     /**
  39.      * @var DocumentResolver
  40.      */
  41.     protected $documentResolver;
  42.     /**
  43.      * @var SiteResolver
  44.      */
  45.     protected $siteResolver;
  46.     /**
  47.      * @var Document\Service
  48.      */
  49.     protected $documentService;
  50.     public function __construct(
  51.         RequestStack $requestStack,
  52.         DocumentResolver $documentResolver,
  53.         SiteResolver $siteResolver,
  54.         Document\Service $documentService
  55.     ) {
  56.         $this->requestStack     $requestStack;
  57.         $this->documentResolver $documentResolver;
  58.         $this->siteResolver     $siteResolver;
  59.         $this->documentService  $documentService;
  60.     }
  61.     /**
  62.      * {@inheritdoc}
  63.      */
  64.     public static function getSubscribedEvents()
  65.     {
  66.         return [
  67.             // priority must be before
  68.             // -> Symfony\Component\HttpKernel\EventListener\LocaleListener::onKernelRequest()
  69.             // -> Pimcore\Bundle\CoreBundle\EventListener\Frontend\EditmodeListener::onKernelRequest()
  70.             KernelEvents::REQUEST => ['onKernelRequest'20],
  71.         ];
  72.     }
  73.     /**
  74.      * Finds the nearest document for the current request if the routing/document router didn't find one (e.g. static routes)
  75.      *
  76.      * @param GetResponseEvent $event
  77.      */
  78.     public function onKernelRequest(GetResponseEvent $event)
  79.     {
  80.         $request $event->getRequest();
  81.         if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)) {
  82.             return;
  83.         }
  84.         if ($this->documentResolver->getDocument($request)) {
  85.             // we already have a document (e.g. set through the document router)
  86.             return;
  87.         } else {
  88.             // if we're in a sub request and no explicit document is set - try to load document from
  89.             // parent and/or master request and set it on our sub-request
  90.             if (!$event->isMasterRequest()) {
  91.                 $parentRequest $this->requestStack->getParentRequest();
  92.                 $masterRequest $this->requestStack->getMasterRequest();
  93.                 $eligibleRequests = [];
  94.                 if (null !== $parentRequest) {
  95.                     $eligibleRequests[] = $parentRequest;
  96.                 }
  97.                 if ($masterRequest !== $parentRequest) {
  98.                     $eligibleRequests[] = $masterRequest;
  99.                 }
  100.                 foreach ($eligibleRequests as $eligibleRequest) {
  101.                     if ($document $this->documentResolver->getDocument($eligibleRequest)) {
  102.                         $this->documentResolver->setDocument($request$document);
  103.                         return;
  104.                     }
  105.                 }
  106.             }
  107.         }
  108.         // no document found yet - try to find the nearest document by request path
  109.         // this is only done on the master request as a sub-request's pathInfo is _fragment when
  110.         // rendered via actions helper
  111.         if ($event->isMasterRequest()) {
  112.             $path null;
  113.             if ($this->siteResolver->isSiteRequest($request)) {
  114.                 $path $this->siteResolver->getSitePath($request);
  115.             } else {
  116.                 $path urldecode($request->getPathInfo());
  117.             }
  118.             $document $this->documentService->getNearestDocumentByPath($pathfalse, ['page''snippet''hardlink']);
  119.             if ($document) {
  120.                 $this->documentResolver->setDocument($request$document);
  121.             }
  122.         }
  123.     }
  124. }