custom/plugins/MaxiaLazyLoader6/src/Subscriber/Storefront.php line 72

Open in your IDE?
  1. <?php
  2. declare (strict_types=1);
  3. namespace Maxia\MaxiaLazyLoader6\Subscriber;
  4. use Maxia\MaxiaLazyLoader6\Components\Config;
  5. use Maxia\MaxiaLazyLoader6\Components\Dom\DomFilter;
  6. use Maxia\MaxiaLazyLoader6\Components\Dom\Filter\ImgTagFilter;
  7. use Maxia\MaxiaLazyLoader6\Components\Dom\Filter\PictureTagFilter;
  8. use Maxia\MaxiaLazyLoader6\Components\Dom\Filter\StyleAttributeFilter;
  9. use Monolog\Logger;
  10. use Shopware\Core\Content\Seo\SeoResolverInterface;
  11. use Shopware\Core\Framework\Struct\ArrayEntity;
  12. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Shopware\Storefront\Event\StorefrontRenderEvent;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use _PhpScoperb223feda8720\voku\helper\HtmlMin;
  19. /**
  20.  * @package Maxia\LazyLoader6\Subscriber
  21.  */
  22. class Storefront implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
  23. {
  24.     public static function getSubscribedEvents() : array
  25.     {
  26.         return [\Symfony\Component\HttpKernel\KernelEvents::RESPONSE => 'onResponse', \Shopware\Storefront\Event\StorefrontRenderEvent::class => 'onRenderStorefront'];
  27.     }
  28.     /**
  29.      * @var SeoResolverInterface
  30.      */
  31.     private $seoResolver;
  32.     /**
  33.      * @var SalesChannelContext
  34.      */
  35.     private $salesChannelContext;
  36.     /**
  37.      * @var Logger
  38.      */
  39.     private $logger;
  40.     /**
  41.      * @var Config
  42.      */
  43.     private $configService;
  44.     /**
  45.      * @var array
  46.      */
  47.     private $config;
  48.     /**
  49.      * @var DomFilter
  50.      */
  51.     private $domFilter;
  52.     /**
  53.      * @param SeoResolverInterface $seoResolver
  54.      * @param Logger $logger
  55.      * @param Config $configService
  56.      * @param DomFilter $domFilter
  57.      */
  58.     public function __construct(\Shopware\Core\Content\Seo\SeoResolverInterface $seoResolver, \Monolog\Logger $logger, \Maxia\MaxiaLazyLoader6\Components\Config $configService, \Maxia\MaxiaLazyLoader6\Components\Dom\DomFilter $domFilter)
  59.     {
  60.         $this->seoResolver $seoResolver;
  61.         $this->logger $logger;
  62.         $this->configService $configService;
  63.         $this->domFilter $domFilter;
  64.     }
  65.     /**
  66.      * Add plugin config to twig view.
  67.      *
  68.      * @param StorefrontRenderEvent $event
  69.      */
  70.     public function onRenderStorefront(\Shopware\Storefront\Event\StorefrontRenderEvent $event) : void
  71.     {
  72.         $this->salesChannelContext $event->getSalesChannelContext();
  73.         $this->config $this->configService->getConfig();
  74.         // exclude some URLs
  75.         $url $this->getSeoUrl($event->getRequest(), $this->salesChannelContext);
  76.         foreach ($this->config['blacklistUrls'] as $pattern) {
  77.             if (\preg_match('#' $pattern '$#'$url)) {
  78.                 if ($this->config['debugLogging']) {
  79.                     $this->logger->addInfo('Blacklist pattern \'' $pattern '\' matches on ' $url);
  80.                 }
  81.                 $this->config['active'] = \false;
  82.                 break;
  83.             }
  84.         }
  85.         $this->salesChannelContext->addExtension('maxiaLazyLoader', new \Shopware\Core\Framework\Struct\ArrayEntity($this->config));
  86.     }
  87.     /**
  88.      * Update storefront response.
  89.      *
  90.      * @param ResponseEvent $event
  91.      */
  92.     public function onResponse(\Symfony\Component\HttpKernel\Event\ResponseEvent $event) : void
  93.     {
  94.         if (!$this->salesChannelContext) {
  95.             return;
  96.         }
  97.         if (!$event->isMasterRequest()) {
  98.             return;
  99.         }
  100.         $headers $event->getResponse()->headers;
  101.         // exclude non-html responses
  102.         if (!$headers || !$headers->get('content-type')) {
  103.             return;
  104.         }
  105.         if ($headers->get('content-type') != 'text/html') {
  106.             return;
  107.         }
  108.         if (!\preg_match('/^\\s*<.*?>$/ism'$event->getResponse()->getContent())) {
  109.             return;
  110.         }
  111.         if ($event->getRequest()->attributes->get('disable-maxia-lazyload') === \true) {
  112.             return;
  113.         }
  114.         if ($this->config['debugLogging']) {
  115.             $stopwatch = new \Symfony\Component\Stopwatch\Stopwatch();
  116.         }
  117.         if ($this->config['active']) {
  118.             try {
  119.                 if ($this->config['debugLogging']) {
  120.                     $this->logger->addInfo('Start lazify ' $event->getRequest()->getUri());
  121.                 }
  122.                 // lazify html
  123.                 $this->domFilter->setBlacklist($this->config['blacklistSelectors']);
  124.                 $this->domFilter->setFilters($this->getFilters($this->config));
  125.                 if (isset($stopwatch)) {
  126.                     $stopwatch->start('lazify');
  127.                 }
  128.                 $html $this->domFilter->process($event->getResponse()->getContent());
  129.                 if ($this->config['debugLogging']) {
  130.                     if (isset($stopwatch)) {
  131.                         /** @var \Symfony\Component\Stopwatch\StopwatchEvent $event */
  132.                         $watch $stopwatch->stop('lazify');
  133.                         $this->logger->addInfo('Lazify duration: ' $watch->getDuration() . 'ms');
  134.                     }
  135.                     if ($this->domFilter->getErrors()) {
  136.                         $this->logger->addError('Errors occurred when parsing HTML:');
  137.                         foreach ($this->domFilter->getErrors() as $error) {
  138.                             $this->logger->addError($error);
  139.                         }
  140.                     }
  141.                 }
  142.                 if ($html) {
  143.                     $event->getResponse()->setContent($html);
  144.                 }
  145.             } catch (\Exception $e) {
  146.                 $this->logger->addError((string) $e);
  147.             }
  148.             // minify html
  149.             if ($this->config['minifyHtml']) {
  150.                 if ($this->config['debugLogging']) {
  151.                     $this->logger->addInfo('Start html minify ' $event->getRequest()->getUri());
  152.                 }
  153.                 if (isset($stopwatch)) {
  154.                     $stopwatch->start('minifyHtml');
  155.                 }
  156.                 $htmlMin = new \_PhpScoperb223feda8720\voku\helper\HtmlMin();
  157.                 $htmlMin->doSortHtmlAttributes(\false);
  158.                 $htmlMin->doSortCssClassNames(\false);
  159.                 $html $htmlMin->minify($event->getResponse()->getContent());
  160.                 $event->getResponse()->setContent($html);
  161.                 if (isset($stopwatch)) {
  162.                     $watch $stopwatch->stop('minifyHtml');
  163.                     $this->logger->addInfo('Minify duration: ' $watch->getDuration() . 'ms');
  164.                 }
  165.             }
  166.         }
  167.     }
  168.     /**
  169.      * @param Request $request
  170.      * @param SalesChannelContext $context
  171.      * @return string
  172.      */
  173.     protected function getSeoUrl(\Symfony\Component\HttpFoundation\Request $request, \Shopware\Core\System\SalesChannel\SalesChannelContext $context)
  174.     {
  175.         $url $this->seoResolver->resolveSeoPath($context->getSalesChannel()->getLanguageId(), $context->getSalesChannel()->getId(), $request->getPathInfo());
  176.         if ($url && !empty($url['canonicalPathInfo'])) {
  177.             $url $url['canonicalPathInfo'];
  178.         } else {
  179.             $url $request->getUri();
  180.         }
  181.         $url = \parse_url($url);
  182.         $path $url['path'];
  183.         if (isset($url['query']) && $url['query']) {
  184.             $path .= '?' $url['query'];
  185.         }
  186.         return $path;
  187.     }
  188.     /**
  189.      * @param array $config
  190.      * @return array
  191.      */
  192.     protected function getFilters(array $config)
  193.     {
  194.         $options = ['lazyClass' => 'maxia-lazy-image''noscriptFallback' => $config['outputFallback'], 'placeholder' => "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="];
  195.         $filters = [new \Maxia\MaxiaLazyLoader6\Components\Dom\Filter\PictureTagFilter($options), new \Maxia\MaxiaLazyLoader6\Components\Dom\Filter\ImgTagFilter($options), new \Maxia\MaxiaLazyLoader6\Components\Dom\Filter\StyleAttributeFilter($options)];
  196.         return $filters;
  197.     }
  198. }