vendor/pimcore/pimcore/bundles/CoreBundle/EventListener/Frontend/DocumentFallbackListener.php line 109

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