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

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