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

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