custom/plugins/CioRedirectWriter/src/Subscriber/RedirectSubscriber.php line 40

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace CioRedirectWriter\Subscriber;
  3. use Shopware\Core\Content\Product\ProductEntity;
  4. use Shopware\Core\Framework\Context;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  8. use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpFoundation\RedirectResponse;
  11. class RedirectSubscriber implements EventSubscriberInterface
  12. {
  13.     private EntityRepositoryInterface $productRepository;
  14.     private EntityRepositoryInterface $scopRedirectRepository;
  15.     private Context $context;
  16.     public function __construct
  17.     (
  18.         EntityRepositoryInterface $productRepository,
  19.         EntityRepositoryInterface $scopRedirectRepository
  20.     )
  21.     {
  22.         $this->productRepository = $productRepository;
  23.         $this->scopRedirectRepository = $scopRedirectRepository;
  24.         $this->context = Context::createDefaultContext();
  25.     }
  26.     public static function getSubscribedEvents(): array
  27.     {
  28.         return [
  29.             BeforeSendResponseEvent::class => 'onCmsPageLoaded'
  30.         ];
  31.     }
  32.     public function onCmsPageLoaded(BeforeSendResponseEvent $event): void
  33.     {
  34.         if ($event->getResponse()->getStatusCode() != 404) {
  35.             return;
  36.         }
  37.         $requestUrl = $event->getRequest()->attributes->get('sw-original-request-uri');
  38.         $storefrontUrl = $event->getRequest()->attributes->get('sw-storefront-uri');
  39.         $urlParts = explode('/', trim($requestUrl, '/'));
  40.         $locale = $urlParts[0];
  41.         $productNumber = end($urlParts);
  42.         $product = $this->getProductByProductNumber($productNumber);
  43.         if ($locale == 'en') {
  44.             $language = 'English';
  45.         } else {
  46.             $language = 'Deutsch';
  47.         }
  48.         $newUrl = null;
  49.         if ($product) {
  50.             $seoUrls = $product->getSeoUrls();
  51.             foreach ($seoUrls as $seoUrl) {
  52.                 if ($seoUrl->getLanguage()->getName() == $language) {
  53.                     $newUrl = $seoUrl->getSeoPathInfo();
  54.                 }
  55.             }
  56.         } else {
  57.             return;
  58.         }
  59.         if (is_null($newUrl)) {
  60.             return;
  61.         }
  62.         if ($locale == 'en') {
  63.             $newUrl = "/en/$newUrl";
  64.         }
  65.         if ($requestUrl === $newUrl) {
  66.             return;
  67.         }
  68.         $this->handleRedirect($requestUrl, $newUrl, $storefrontUrl, $event);
  69.     }
  70.     public function handleRedirect($requestUrl, $newUrl, $host, $event)
  71.     {
  72.         $this->saveNewRedirect($requestUrl, $newUrl);
  73.         $redirectUrl = $host . $newUrl;
  74.         $event->setResponse(new RedirectResponse($redirectUrl, 301));
  75.     }
  76.     /**
  77.      * @param string $productNumber
  78.      * @return ProductEntity|null
  79.      */
  80.     private function getProductByProductNumber(string $productNumber): ?ProductEntity
  81.     {
  82.         $criteria = new Criteria();
  83.         $criteria->addFilter(new EqualsFilter('productNumber', $productNumber));
  84.         $criteria->addAssociation('seoUrls');
  85.         $criteria->addAssociation('seoUrls.language');
  86.         $res = $this->productRepository->search($criteria, $this->context);
  87.         return $res->first() instanceof ProductEntity ?
  88.             $res->first() :
  89.             null;
  90.     }
  91.     private function saveNewRedirect(string $requestUrl, string $newUrl): void
  92.     {
  93.         $data = [];
  94.         $data[] = [
  95.             'sourceURL' => $requestUrl,
  96.             'targetURL' => $newUrl,
  97.             'httpCode' => 301,
  98.             'enabled' => true,
  99.             'ignoreQueryParams' => true
  100.         ];
  101.         $this->scopRedirectRepository->create($data, $this->context);
  102.     }
  103. }