custom/plugins/TritumNoindex/src/Core/KernelResponseSubscriber.php line 39

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace TRITUM\Noindex\Core;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  7. use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
  8. use Shopware\Core\System\SystemConfig\SystemConfigService;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpFoundation\Response;
  11. class KernelResponseSubscriber implements EventSubscriberInterface
  12. {
  13.     /**
  14.      * @var SystemConfigService
  15.      */
  16.     private $systemConfigService;
  17.     /**
  18.      * @var EntityRepositoryInterface
  19.      */
  20.     private $seoUrlRepository;
  21.     public function __construct(SystemConfigService $systemConfigServiceEntityRepositoryInterface $seoUrlRepository)
  22.     {
  23.         $this->systemConfigService $systemConfigService;
  24.         $this->seoUrlRepository $seoUrlRepository;
  25.     }
  26.     public static function getSubscribedEvents(): array
  27.     {
  28.         return [
  29.             BeforeSendResponseEvent::class => 'addNoindex',
  30.         ];
  31.     }
  32.     public function addNoindex(BeforeSendResponseEvent $event): void
  33.     {
  34.         $requestUri $event->getRequest()->getRequestUri();
  35.         if(!empty($requestUri)) {
  36.             $salesChannel $event->getRequest()->attributes->get('sw-sales-channel-id');
  37.             $noIndexPages explode("\n"$this->systemConfigService->get('TritumNoindex.config.pages'$salesChannel) ?? '');
  38.             $noIndexPagesWithSubpages explode("\n"$this->systemConfigService->get('TritumNoindex.config.pagesSub'$salesChannel) ?? '');
  39.             if (!empty($noIndexPages) && !empty($noIndexPages[0])) {
  40.                 foreach ($noIndexPages as $page) {
  41.                     if (!empty($page)) {
  42.                         $requestUri $this->transformToSeoUrl($requestUri) ?? '';
  43.                         $page trim($page);
  44.                         $page $this->removeSlashesFromString($page);
  45.                         if (preg_match("#\A/?$page/?\z#"$requestUri)) {
  46.                             $response $this->setNoindex($event->getResponse());
  47.                             $event->setResponse($response);
  48.                         }
  49.                     }
  50.                 }
  51.             }
  52.             if (!empty($noIndexPagesWithSubpages) && !empty($noIndexPagesWithSubpages[0])) {
  53.                 foreach ($noIndexPagesWithSubpages as $pageWithSub) {
  54.                     if (!empty($pageWithSub)) {
  55.                         $requestUri $this->transformToSeoUrl($requestUri);
  56.                         $pageWithSub trim($pageWithSub);
  57.                         $pageWithSub $this->addSlashesToString($pageWithSub);
  58.                         if (preg_match("#\A$pageWithSub.*\z#"$requestUri)) {
  59.                             $response $this->setNoindex($event->getResponse());
  60.                             $event->setResponse($response);
  61.                         }
  62.                     }
  63.                 }
  64.             }
  65.         }
  66.     }
  67.     private function transformToSeoUrl($requestUri): string
  68.     {
  69.         if(preg_match'#(.*)(\/\w+\/[0-9a-f]{32})$#'$requestUri$matches)) {
  70.             $result $this->seoUrlRepository->search(
  71.                 (new Criteria())->addFilter(new EqualsFilter('pathInfo'$matches[2])), Context::createDefaultContext()
  72.             );
  73.             $resultCount $result->count();
  74.             if ($resultCount === 1) {
  75.                 $transformedURL $result->getEntities()->first()->getSeoPathInfo();
  76.             } elseif ($resultCount === 0) {
  77.                 return $requestUri;
  78.             }
  79.             $canonicalURL $result->getEntities()->filterByProperty('isCanonical'true);
  80.             if ($canonicalURL->count() === 1) {
  81.                 $transformedURL $canonicalURL->first()->getSeoPathInfo();
  82.             }
  83.             if (empty($transformedURL)) $transformedURL $result->getEntities()->last()->getSeoPathInfo();
  84.             if (substr($transformedURL0,1) !== '/'$transformedURL '/' $transformedURL;
  85.             return $matches[1] . $transformedURL;
  86.         } else {
  87.             return $requestUri;
  88.         }
  89.     }
  90.     private function setNoindex(Response $response): Response
  91.     {
  92.         $content $response->getContent();
  93.         if (preg_match('#<meta\s+name="robots"\s+content="(.+)"\s*/>#'$content$matches)) {
  94.             // noindex already set ?
  95.             if (strpos($matches[0], 'noindex') === false) {
  96.                 if (strpos($matches[0], 'index') !== false) {
  97.                     $replacement str_replace('index''noindex'$matches[0]);
  98.                 } else {
  99.                     $replacement '<meta name="robots" content="' $matches[1] . ', noindex"/>';
  100.                 }
  101.                 $content preg_replace('#<meta\s+name="robots"\s+content=".+"\s*/>#'$replacement$content);
  102.                 $response->setContent($content);
  103.             }
  104.         }
  105.         if ($response->headers->contains('x-robots-tag''noindex') === false) {
  106.             $response->headers->add(['x-robots-tag' => ['noindex']]);
  107.         }
  108.         return $response;
  109.     }
  110.     private function addSlashesToString($string): string
  111.     {
  112.         if (substr($string0,1) !== '/')
  113.             $string '/' $string;
  114.         if (substr($stringstrlen($string) - 1) !== '/')
  115.             $string .= '/';
  116.         return $string;
  117.     }
  118.     private function removeSlashesFromString($string): string
  119.     {
  120.         if (substr($string0,1) === '/')
  121.             $string rtrim($string'/');
  122.         if (substr($stringstrlen($string) - 1) !== '/')
  123.             $string ltrim($string'/');
  124.         return $string;
  125.     }
  126. }