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

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