vendor/pimcore/pimcore/bundles/CoreBundle/EventListener/Frontend/ElementListener.php line 97

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\AdminBundle\Security\User\UserLoader;
  16. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  17. use Pimcore\Http\Request\Resolver\DocumentResolver;
  18. use Pimcore\Http\Request\Resolver\EditmodeResolver;
  19. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  20. use Pimcore\Http\RequestHelper;
  21. use Pimcore\Model\DataObject\Service;
  22. use Pimcore\Model\Document;
  23. use Pimcore\Model\Staticroute;
  24. use Pimcore\Model\Version;
  25. use Pimcore\Targeting\Document\DocumentTargetingConfigurator;
  26. use Psr\Log\LoggerAwareInterface;
  27. use Psr\Log\LoggerAwareTrait;
  28. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  31. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  32. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  33. use Symfony\Component\HttpKernel\KernelEvents;
  34. /**
  35.  * Handles element setup logic from request. Basically this does what the init() method
  36.  * on the ZF frontend controller did.
  37.  */
  38. class ElementListener implements EventSubscriberInterfaceLoggerAwareInterface
  39. {
  40.     use LoggerAwareTrait;
  41.     use PimcoreContextAwareTrait;
  42.     const FORCE_ALLOW_PROCESSING_UNPUBLISHED_ELEMENTS '_force_allow_processing_unpublished_elements';
  43.     /**
  44.      * @var DocumentResolver
  45.      */
  46.     protected $documentResolver;
  47.     /**
  48.      * @var EditmodeResolver
  49.      */
  50.     protected $editmodeResolver;
  51.     /**
  52.      * @var RequestHelper
  53.      */
  54.     protected $requestHelper;
  55.     /**
  56.      * @var UserLoader
  57.      */
  58.     protected $userLoader;
  59.     /**
  60.      * @var DocumentTargetingConfigurator
  61.      */
  62.     private $targetingConfigurator;
  63.     public function __construct(
  64.         DocumentResolver $documentResolver,
  65.         EditmodeResolver $editmodeResolver,
  66.         RequestHelper $requestHelper,
  67.         UserLoader $userLoader,
  68.         DocumentTargetingConfigurator $targetingConfigurator
  69.     ) {
  70.         $this->documentResolver $documentResolver;
  71.         $this->editmodeResolver $editmodeResolver;
  72.         $this->requestHelper $requestHelper;
  73.         $this->userLoader $userLoader;
  74.         $this->targetingConfigurator $targetingConfigurator;
  75.     }
  76.     /**
  77.      * @inheritDoc
  78.      */
  79.     public static function getSubscribedEvents()
  80.     {
  81.         return [
  82.             KernelEvents::CONTROLLER => ['onKernelController'3], // has to be after DocumentFallbackListener
  83.         ];
  84.     }
  85.     public function onKernelController(FilterControllerEvent $event)
  86.     {
  87.         if ($event->isMasterRequest()) {
  88.             $request $event->getRequest();
  89.             if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)) {
  90.                 return;
  91.             }
  92.             $document $this->documentResolver->getDocument($request);
  93.             $adminRequest =
  94.                 $this->requestHelper->isFrontendRequestByAdmin($request) ||
  95.                 $this->requestHelper->isFrontendRequestByAdmin($this->requestHelper->getMasterRequest());
  96.             $user null;
  97.             if ($adminRequest) {
  98.                 $user $this->userLoader->getUser();
  99.             }
  100.             if ($document && !$document->isPublished() && !$user && !$request->attributes->get(self::FORCE_ALLOW_PROCESSING_UNPUBLISHED_ELEMENTS)) {
  101.                 $this->logger->warning('Denying access to document {document} as it is unpublished and there is no user in the session.', [
  102.                     $document->getFullPath()
  103.                 ]);
  104.                 throw new AccessDeniedHttpException(sprintf('Access denied for %s'$document->getFullPath()));
  105.             }
  106.             // editmode, pimcore_preview & pimcore_version
  107.             if ($user) {
  108.                 $document $this->handleAdminUserDocumentParams($request$document);
  109.                 $this->handleObjectParams($request);
  110.             }
  111.             if ($document) {
  112.                 // for public versions
  113.                 $document $this->handleVersion($request$document);
  114.                 // apply target group configuration
  115.                 $this->applyTargetGroups($request$document);
  116.                 $this->documentResolver->setDocument($request$document);
  117.             }
  118.         }
  119.     }
  120.     /**
  121.      * @param Request $request
  122.      * @param Document $document
  123.      *
  124.      * @return Document
  125.      */
  126.     protected function handleVersion(Request $requestDocument $document)
  127.     {
  128.         if ($request->get('v')) {
  129.             if ($version Version::getById($request->get('v'))) {
  130.                 if ($version->getPublic()) {
  131.                     $this->logger->info('Setting version to {version} for document {document}', [
  132.                         'version' => $version->getId(),
  133.                         'document' => $document->getFullPath()
  134.                     ]);
  135.                     $document $version->getData();
  136.                 }
  137.             } else {
  138.                 $this->logger->notice('Failed to load {version} for document {document}', [
  139.                     'version' => $request->get('v'),
  140.                     'document' => $document->getFullPath()
  141.                 ]);
  142.             }
  143.         }
  144.         return $document;
  145.     }
  146.     protected function applyTargetGroups(Request $requestDocument $document)
  147.     {
  148.         if (!$document instanceof Document\Targeting\TargetingDocumentInterface || null !== Staticroute::getCurrentRoute()) {
  149.             return;
  150.         }
  151.         // reset because of preview and editmode (saved in session)
  152.         $document->setUseTargetGroup(null);
  153.         $this->targetingConfigurator->configureTargetGroup($document);
  154.         if ($document->getUseTargetGroup()) {
  155.             $this->logger->info('Setting target group to {targetGroup} for document {document}', [
  156.                 'targetGroup' => $document->getUseTargetGroup(),
  157.                 'document' => $document->getFullPath()
  158.             ]);
  159.         }
  160.     }
  161.     /**
  162.      * @param Request $request
  163.      * @param Document|null $document
  164.      *
  165.      * @return Document|null
  166.      */
  167.     protected function handleAdminUserDocumentParams(Request $request, ?Document $document)
  168.     {
  169.         if (!$document) {
  170.             return null;
  171.         }
  172.         // editmode document
  173.         if ($this->editmodeResolver->isEditmode($request)) {
  174.             $document $this->handleEditmode($document);
  175.         }
  176.         // document preview
  177.         if ($request->get('pimcore_preview')) {
  178.             // get document from session
  179.             // TODO originally, this was the following call. What was in this->getParam('document') and
  180.             // why was it an object?
  181.             // $docKey = "document_" . $this->getParam("document")->getId();
  182.             if ($documentFromSession Document\Service::getElementFromSession('document'$document->getId())) {
  183.                 // if there is a document in the session use it
  184.                 $this->logger->debug('Loading preview document {document} from session', [
  185.                     'document' => $document->getFullPath()
  186.                 ]);
  187.                 $document $documentFromSession;
  188.             }
  189.         }
  190.         // for version preview
  191.         if ($request->get('pimcore_version')) {
  192.             // TODO there was a check with a registry flag here - check if the master request handling is sufficient
  193.             if ($version Version::getById($request->get('pimcore_version'))) {
  194.                 $document $version->getData();
  195.                 $this->logger->debug('Loading version {version} for document {document} from pimcore_version parameter', [
  196.                     'version' => $version->getId(),
  197.                     'document' => $document->getFullPath()
  198.                 ]);
  199.             } else {
  200.                 $this->logger->warning('Failed to load {version} for document {document} from pimcore_version parameter', [
  201.                     'version' => $request->get('pimcore_version'),
  202.                     'document' => $document->getFullPath()
  203.                 ]);
  204.                 throw new NotFoundHttpException(
  205.                     sprintf('Failed to load %s for document %s from pimcore_version parameter',
  206.                         $request->get('pimcore_version'), $document->getFullPath()));
  207.             }
  208.         }
  209.         return $document;
  210.     }
  211.     /**
  212.      * @param Document $document
  213.      *
  214.      * @return mixed|Document|Document\PageSnippet
  215.      */
  216.     protected function handleEditmode(Document $document)
  217.     {
  218.         // check if there is the document in the session
  219.         if ($documentFromSession Document\Service::getElementFromSession('document'$document->getId())) {
  220.             // if there is a document in the session use it
  221.             $this->logger->debug('Loading editmode document {document} from session', [
  222.                 'document' => $document->getFullPath()
  223.             ]);
  224.             $document $documentFromSession;
  225.         } else {
  226.             $this->logger->debug('Loading editmode document {document} from latest version', [
  227.                 'document' => $document->getFullPath()
  228.             ]);
  229.             // set the latest available version for editmode if there is no doc in the session
  230.             $latestVersion $document->getLatestVersion();
  231.             if ($latestVersion) {
  232.                 $latestDoc $latestVersion->loadData();
  233.                 if ($latestDoc instanceof Document\PageSnippet) {
  234.                     $document $latestDoc;
  235.                 }
  236.             }
  237.         }
  238.         return $document;
  239.     }
  240.     /**
  241.      * @param Request $request
  242.      */
  243.     protected function handleObjectParams(Request $request)
  244.     {
  245.         // object preview
  246.         if ($objectId $request->get('pimcore_object_preview')) {
  247.             if ($object Service::getElementFromSession('object'$objectId)) {
  248.                 $this->logger->debug('Loading object {object} ({objectId}) from session', [
  249.                     'object' => $object->getFullPath(),
  250.                     'objectId' => $object->getId()
  251.                 ]);
  252.                 // TODO remove \Pimcore\Cache\Runtime
  253.                 // add the object to the registry so every call to DataObject::getById() will return this object instead of the real one
  254.                 \Pimcore\Cache\Runtime::set('object_' $object->getId(), $object);
  255.             }
  256.         }
  257.     }
  258. }