custom/plugins/DreiscSeoPro/src/Core/Routing/RequestTransformer.php line 115

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace DreiscSeoPro\Core\Routing;
  3. use DreiscSeoPro\Core\Content\DreiscSeoRedirect\DreiscSeoRedirectEntity;
  4. use DreiscSeoPro\Core\Content\DreiscSeoRedirect\DreiscSeoRedirectRepository;
  5. use DreiscSeoPro\Core\Routing\Category\CategoryRedirectSearcher;
  6. use DreiscSeoPro\Core\Routing\Product\ProductRedirectSearcher;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  8. use Shopware\Core\SalesChannelRequest;
  9. use Symfony\Component\HttpFoundation\Request;
  10. class RequestTransformer
  11. {
  12.     public const SALES_CHANNEL_BASE_URL 'sw-sales-channel-base-url';
  13.     /**
  14.      * @var DreiscSeoRedirectRepository
  15.      */
  16.     private $dreiscSeoRedirectRepository;
  17.     /**
  18.      * @var RedirectExecutor
  19.      */
  20.     private $redirectExecutor;
  21.     /**
  22.      * @var ProductRedirectSearcher
  23.      */
  24.     private $productRedirectSearcher;
  25.     /**
  26.      * @var CategoryRedirectSearcher
  27.      */
  28.     private $categoryRedirectSearcher;
  29.     /**
  30.      * @param DreiscSeoRedirectRepository $dreiscSeoRedirectRepository
  31.      * @param RedirectExecutor $redirectExecutor
  32.      * @param ProductRedirectSearcher $productRedirectSearcher
  33.      * @param CategoryRedirectSearcher $categoryRedirectSearcher
  34.      */
  35.     public function __construct(DreiscSeoRedirectRepository $dreiscSeoRedirectRepositoryRedirectExecutor $redirectExecutorProductRedirectSearcher $productRedirectSearcherCategoryRedirectSearcher $categoryRedirectSearcher)
  36.     {
  37.         $this->dreiscSeoRedirectRepository $dreiscSeoRedirectRepository;
  38.         $this->redirectExecutor $redirectExecutor;
  39.         $this->productRedirectSearcher $productRedirectSearcher;
  40.         $this->categoryRedirectSearcher $categoryRedirectSearcher;
  41.     }
  42.     /**
  43.      * This method will be run after the sales channel and the seo url information was fetched
  44.      * by the decorated class
  45.      *
  46.      * @param Request $shopwareRequest
  47.      * @param Request $request
  48.      * @return Request
  49.      * @throws InconsistentCriteriaIdsException
  50.      */
  51.     public function transform(Request $shopwareRequestRequest $request): Request
  52.     {
  53.         /** Abort, if it's not a sales channel url */
  54.         if(true !== $shopwareRequest->attributes->has(SalesChannelRequest::ATTRIBUTE_IS_SALES_CHANNEL_REQUEST)) {
  55.             return $shopwareRequest;
  56.         }
  57.         /** Check for entity redirects */
  58.         $this->checkForEntityRedirects($shopwareRequest);
  59.         /** Fetch the path info */
  60.         $pathInfo $this->getAdjustedRequestUri($request$shopwareRequest);
  61.         /** Try to fetch a redirect for this path */
  62.         $dreiscSeoRedirectEntity $this->dreiscSeoRedirectRepository->getSourceTypeUrlByDomainIdAndSourcePath(
  63.             $shopwareRequest->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID),
  64.             $pathInfo
  65.         );
  66.         /** Abort, if there is no redirect */
  67.         if (!$dreiscSeoRedirectEntity instanceof DreiscSeoRedirectEntity) {
  68.             return $shopwareRequest;
  69.         }
  70.         /** Check, if this is a test run for PHPUnit */
  71.         $isPhpUnitTest = !empty($request->server->get('IS_PHP_UNIT_TEST'));
  72.         /** Execute the redirect */
  73.         $this->redirectExecutor->redirect(
  74.             $dreiscSeoRedirectEntity,
  75.             $shopwareRequest->attributes->get(SalesChannelRequest::ATTRIBUTE_DOMAIN_ID),
  76.             $isPhpUnitTest
  77.         );
  78.         return $shopwareRequest;
  79.     }
  80.     /**
  81.      * @param Request $shopwareRequest
  82.      * @return bool
  83.      * @throws InconsistentCriteriaIdsException
  84.      */
  85.     private function checkForEntityRedirects(Request $shopwareRequest): bool
  86.     {
  87.         $pathInfoExplode explode('/'$shopwareRequest->getPathInfo());
  88.         /** Abort, if path info has more or less than three parts */
  89.         if (empty($pathInfoExplode) || !== count($pathInfoExplode)) {
  90.             return false;
  91.         }
  92.         if (empty($pathInfoExplode[0]) && 'detail' === $pathInfoExplode[1] && !empty($pathInfoExplode[2])) {
  93.             /** Check if there is redirect for the product */
  94.             $this->productRedirectSearcher->search(
  95.                 $shopwareRequest,
  96.                 $pathInfoExplode[2]
  97.             );
  98.             return true;
  99.         }
  100.         if (empty($pathInfoExplode[0]) && 'navigation' === $pathInfoExplode[1] && !empty($pathInfoExplode[2])) {
  101.             /** Check if there is redirect for the product */
  102.             $this->categoryRedirectSearcher->search(
  103.                 $shopwareRequest,
  104.                 $pathInfoExplode[2]
  105.             );
  106.             return true;
  107.         }
  108.         return false;
  109.     }
  110.     /**
  111.      * @param Request $request
  112.      * @param Request $shopwareRequest
  113.      * @return bool|string
  114.      */
  115.     private function getAdjustedRequestUri(Request $requestRequest $shopwareRequest)
  116.     {
  117.         $adjustedRequestUri $request->getRequestUri();
  118.         /**
  119.          * Remove the base url from the beginning if available
  120.          */
  121.         $baseUrl $shopwareRequest->attributes->get(self::SALES_CHANNEL_BASE_URL);
  122.         if(!empty($baseUrl)) {
  123.             /** Make sure, that there is a slash at the end of the base url */
  124.             $baseUrl rtrim($baseUrl'/') . '/';
  125.             /** Remove the base url from the request uri */
  126.             $adjustedRequestUri substr($adjustedRequestUristrlen($baseUrl));
  127.             /**
  128.              * There are some special cases. For example, when $adjustedRequestUri is "/en"
  129.              * and $baseUrl is "/en/". In this case $baseUrl is longer then $adjustedRequestUri
  130.              * and substr will return false. In this case we set "/" as the new value
  131.              */
  132.             if(false === $adjustedRequestUri) {
  133.                 $adjustedRequestUri '/';
  134.             }
  135.         }
  136.         /** Make sure that there is no slash at the beginning */
  137.         $adjustedRequestUri ltrim($adjustedRequestUri'/');
  138.         return $adjustedRequestUri;
  139.     }
  140. }