pimcore/lib/Pimcore/Bundle/CoreBundle/EventListener/Frontend/ElementListener.php line 100

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