custom/plugins/ScopPlatformRedirecter/src/Decorator/CanonicalRedirectServiceDecorator.php line 97

  1. <?php
  2. namespace Scop\PlatformRedirecter\Decorator;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\OrFilter;
  9. use Shopware\Core\Framework\Routing\CanonicalRedirectService;
  10. use Shopware\Core\System\SystemConfig\SystemConfigService;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. class CanonicalRedirectServiceDecorator extends CanonicalRedirectService
  15. {
  16.     /**
  17.      * @var CanonicalRedirectService
  18.      */
  19.     private $inner;
  20.     /**
  21.      * @var EntityRepository
  22.      */
  23.     private $repository;
  24.     /**
  25.      * @var SystemConfigService
  26.      */
  27.     private SystemConfigService $configService;
  28.     public function __construct(CanonicalRedirectService $innerSystemConfigService $configServiceEntityRepository $redirectRepository)
  29.     {
  30.         parent::__construct($configService);
  31.         $this->configService $configService;
  32.         $this->repository $redirectRepository;
  33.         $this->inner $inner;
  34.     }
  35.     /**
  36.      * Redirect to the new url if found in redirects
  37.      * Otherwise do nothing
  38.      * Modules like admin, api or widgets are excluded from redirects
  39.      *
  40.      * @param Request $request
  41.      * @return Response|null
  42.      */
  43.     public function getRedirect(Request $request): ?Response
  44.     {
  45.         $requestUri = (string)$request->get("sw-original-request-uri");
  46.         $storefrontUri $request->get('sw-sales-channel-absolute-base-url');
  47.         $requestBase $request->getPathInfo();
  48.         $requestBaseUrl $request->getBaseUrl();
  49.         $salesChannelId $request->get('sw-sales-channel-id');
  50.         // Block overriding /admin and /api and widgets, so you can't lock out of the administration.
  51.         if (\strpos($requestBase"/admin") === 0) {
  52.             return $this->inner->getRedirect($request);
  53.         }
  54.         if (\strpos($requestBase"/api") === 0) {
  55.             return $this->inner->getRedirect($request);
  56.         }
  57.         if (\strpos($requestBase"/widgets") === 0) {
  58.             return $this->inner->getRedirect($request);
  59.         }
  60.         if (\strpos($requestBase"/store-api") === 0) {
  61.             return $this->inner->getRedirect($request);
  62.         }
  63.         if (\strpos($requestBase"/_profiler") === 0) {
  64.             return $this->inner->getRedirect($request);
  65.         }
  66.         if ($this->configService->getBool('ScopPlatformRedirecter.config.specialCharSupport') ?? false) {
  67.             $requestUri urldecode($requestUri);
  68.             $storefrontUri urldecode($storefrontUri);
  69.             $requestBaseUrl urldecode($requestBaseUrl);
  70.         }
  71.         $context Context::createDefaultContext();
  72.         $search = [
  73.             $requestBaseUrl '/' $requestUri// relative url with shopware 6 in sub folder: /public/Ergonomic-Concrete-Cough-Machine/48314803f1244f609a2ce907bfb48f53
  74.             $requestBaseUrl $requestUri// relative url with shopware 6 in sub folder url is not shopware seo url: /public/test
  75.             $storefrontUri $requestUri// absolute url with shopware 6 in sub folder, full url with host: http://shopware-platform.local/public/test1
  76.             $storefrontUri '/' $requestUri// absolute url with shopware 6 in sub folder, full url with host and slash at the end: http://shopware-platform.local/public/Freizeit-Elektro/Telefone/
  77.             $requestUri// relative url domain configured in public folder: /Ergonomic-Concrete-Cough-Machine/48314803f1244f609a2ce907bfb48f53 or /test4
  78.             '/' $requestUri// absolute url domain configured in public folder: http://shopware-platform.local/Shoes-Baby/
  79.             \substr($requestUri1), // e.g. "test"
  80.         ];
  81.         // search for the redirect in the database
  82.         $redirects $this->repository->search((new Criteria())->addFilter(new EqualsAnyFilter('sourceURL'$search))->addFilter(new EqualsFilter('enabled'true))->addFilter(new OrFilter([new EqualsFilter('salesChannelId'$salesChannelId), new EqualsFilter('salesChannelId'null)]))
  83.             ->setLimit(1), $context);
  84.         if ($redirects->count() === 0) {
  85.             // Checks if the requested URL contains Query parameters, and if so, checks if a redirect can be found with the ignoreQueryParams option
  86.             if (str_contains($requestUri'?')) {
  87.                 $searchWithoutQuery = [];
  88.                 foreach ($search as $string)
  89.                     $searchWithoutQuery[] = explode('?'$string)[0];
  90.                 $redirects $this->repository->search((new Criteria())->addFilter(new EqualsAnyFilter('sourceURL'$searchWithoutQuery))->addFilter(new EqualsFilter('enabled'true))->addFilter(new EqualsAnyFilter('queryParamsHandling', [12]))
  91.                     ->setLimit(1), $context);
  92.                 // No Redirect found for this URL, do nothing
  93.                 if ($redirects->count() === 0) {
  94.                     return $this->inner->getRedirect($request);
  95.                 }
  96.             } else {
  97.                 // No Redirect found for this URL, do nothing
  98.                 return $this->inner->getRedirect($request);
  99.             }
  100.         }
  101.         $redirect $redirects->first();
  102.         $targetURL $redirect->getTargetURL();
  103.         $code $redirect->getHttpCode();
  104.         // If configured in the redirect, adds the query parameters from the requested URL to the target URL
  105.         if ($redirect->getQueryParamsHandling() === && str_contains($requestUri'?')) {
  106.             $targetURL .= '?' explode('?'$requestUri2)[1];
  107.         }
  108.         // Prevent endless redirecting when target url and source url have only different capitalisation
  109.         if (in_array($targetURL$searchtrue)) {
  110.             return $this->inner->getRedirect($request);
  111.         }
  112.         /*
  113.          *  checks if $targetURL is a full url or path and redirects accordingly
  114.          */
  115.         if (!(\strpos($targetURL"http:") === || \strpos($targetURL"https:") === 0)) {
  116.             if (\strpos($targetURL"www.") === 0) {
  117.                 $targetURL "http://" $targetURL;
  118.             } else {
  119.                 if (\strpos($targetURL"/") !== 0) {
  120.                     $targetURL "/" $targetURL;
  121.                 }
  122.             }
  123.         }
  124.         return new RedirectResponse($targetURL$code);
  125.     }
  126. }