vendor/pimcore/pimcore/bundles/CoreBundle/EventListener/Frontend/StaticPageGeneratorListener.php line 66

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\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Bundle\CoreBundle\EventListener\Traits\StaticPageContextAwareTrait;
  17. use Pimcore\Config;
  18. use Pimcore\Document\StaticPageGenerator;
  19. use Pimcore\Event\DocumentEvents;
  20. use Pimcore\Event\Model\DocumentEvent;
  21. use Pimcore\Http\Request\Resolver\DocumentResolver;
  22. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  23. use Pimcore\Http\RequestHelper;
  24. use Pimcore\Logger;
  25. use Pimcore\Model\Document\Page;
  26. use Pimcore\Model\Document\PageSnippet;
  27. use Pimcore\Model\Site;
  28. use Pimcore\Tool\Storage;
  29. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\HttpFoundation\Response;
  32. use Symfony\Component\HttpKernel\Event\RequestEvent;
  33. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  34. use Symfony\Component\HttpKernel\KernelEvents;
  35. /**
  36.  * @internal
  37.  */
  38. class StaticPageGeneratorListener implements EventSubscriberInterface
  39. {
  40.     use PimcoreContextAwareTrait;
  41.     use StaticPageContextAwareTrait;
  42.     public function __construct(
  43.         protected StaticPageGenerator $staticPageGenerator,
  44.         protected DocumentResolver $documentResolver,
  45.         protected RequestHelper $requestHelper,
  46.         private Config $config
  47.     ) {
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         return [
  52.             DocumentEvents::POST_ADD => 'onPostAddUpdateDeleteDocument',
  53.             DocumentEvents::POST_DELETE => 'onPostAddUpdateDeleteDocument',
  54.             DocumentEvents::POST_UPDATE => 'onPostAddUpdateDeleteDocument',
  55.             KernelEvents::REQUEST => ['onKernelRequest'510], //this must run before targeting listener
  56.             KernelEvents::RESPONSE => ['onKernelResponse', -120], //this must run after code injection listeners
  57.         ];
  58.     }
  59.     public function onKernelRequest(RequestEvent $event)
  60.     {
  61.         if (!$event->isMainRequest()) {
  62.             return;
  63.         }
  64.         $request $event->getRequest();
  65.         if (!$this->checkValidRequest($request)) {
  66.             return;
  67.         }
  68.         $config $this->config['documents'];
  69.         if (!$config['static_page_router']['enabled']) {
  70.             return;
  71.         }
  72.         $routePattern $config['static_page_router']['route_pattern'];
  73.         if (!empty($routePattern) && !@preg_match($routePattern$request->getPathInfo())) {
  74.             return;
  75.         }
  76.         $storage Storage::get('document_static');
  77.         try {
  78.             $path '';
  79.             $filename urldecode($request->getPathInfo());
  80.             if (Site::isSiteRequest()) {
  81.                 if ($request->getPathInfo() === '/') {
  82.                     $filename '/' Site::getCurrentSite()->getRootDocument()->getKey();
  83.                 } else {
  84.                     $path Site::getCurrentSite()->getRootPath();
  85.                 }
  86.             }
  87.             $filename $path .  $filename  '.html';
  88.             if ($storage->fileExists($filename)) {
  89.                 $content $storage->read($filename);
  90.                 $date date(\DateTimeInterface::ISO8601$storage->lastModified($filename));
  91.                 $reponse = new Response(
  92.                     $contentResponse::HTTP_OK, [
  93.                     'Content-Type' => 'text/html',
  94.                     'X-Pimcore-Static-Page-Last-Modified' => $date,
  95.                 ]
  96.                 );
  97.                 $event->setResponse($reponse);
  98.             }
  99.         } catch (\Exception $e) {
  100.             Logger::error($e->getMessage());
  101.         }
  102.     }
  103.     public function onKernelResponse(ResponseEvent $event)
  104.     {
  105.         if (!$event->isMainRequest()) {
  106.             return;
  107.         }
  108.         $request $event->getRequest();
  109.         if (!$this->checkValidRequest($request)) {
  110.             return;
  111.         }
  112.         //return if request is from StaticPageGenerator
  113.         if ($request->attributes->has('pimcore_static_page_generator')) {
  114.             return;
  115.         }
  116.         // only inject analytics code on non-admin requests
  117.         if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_DEFAULT)
  118.             && !$this->matchesStaticPageContext($request)) {
  119.             return;
  120.         }
  121.         $document $this->documentResolver->getDocument();
  122.         if ($document instanceof Page && $document->getStaticGeneratorEnabled()) {
  123.             $response $event->getResponse()->getContent();
  124.             $this->staticPageGenerator->generate($document, ['response' => $response]);
  125.         }
  126.     }
  127.     public function onPostAddUpdateDeleteDocument(DocumentEvent $e)
  128.     {
  129.         $document $e->getDocument();
  130.         if ($e->hasArgument('saveVersionOnly') || $e->hasArgument('autoSave')) {
  131.             return;
  132.         }
  133.         if ($document instanceof PageSnippet) {
  134.             try {
  135.                 if ($document->getStaticGeneratorEnabled()
  136.                     || $this->staticPageGenerator->pageExists($document)) {
  137.                     $this->staticPageGenerator->remove($document);
  138.                 }
  139.             } catch (\Exception $e) {
  140.                 Logger::error((string) $e);
  141.                 return;
  142.             }
  143.         }
  144.     }
  145.     private function checkValidRequest(Request $request): bool
  146.     {
  147.         if ($this->requestHelper->isFrontendRequestByAdmin($request)
  148.             || $request->isXmlHttpRequest()
  149.             || $request->getMethod() !== 'GET'
  150.             || !in_array('text/html'$request->getAcceptableContentTypes())) {
  151.             return false;
  152.         }
  153.         return true;
  154.     }
  155. }