vendor/shopware/core/Content/Seo/SeoUrlPlaceholderHandler.php line 49

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Seo;
  3. use Shopware\Core\Content\Seo\SeoUrl\SeoUrlCollection;
  4. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  8. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  9. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  10. use Symfony\Component\HttpFoundation\RequestStack;
  11. use Symfony\Component\Routing\RouterInterface;
  12. class SeoUrlPlaceholderHandler implements SeoUrlPlaceholderHandlerInterface
  13. {
  14.     public const DOMAIN_PLACEHOLDER '124c71d524604ccbad6042edce3ac799';
  15.     /**
  16.      * @var RouterInterface
  17.      */
  18.     private $router;
  19.     /**
  20.      * @var SalesChannelRepositoryInterface
  21.      */
  22.     private $seoUrlRepository;
  23.     /**
  24.      * @var RequestStack
  25.      */
  26.     private $requestStack;
  27.     public function __construct(
  28.         RequestStack $requestStack,
  29.         RouterInterface $router,
  30.         SalesChannelRepositoryInterface $seoUrlRepository
  31.     ) {
  32.         $this->router $router;
  33.         $this->seoUrlRepository $seoUrlRepository;
  34.         $this->requestStack $requestStack;
  35.     }
  36.     /**
  37.      * @param string $name
  38.      */
  39.     public function generate($name, array $parameters = []): string
  40.     {
  41.         $path $this->router->generate($name$parametersRouterInterface::ABSOLUTE_PATH);
  42.         $request $this->requestStack->getMasterRequest();
  43.         $basePath $request $request->getBasePath() : '';
  44.         $path $this->removePrefix($path$basePath);
  45.         return self::DOMAIN_PLACEHOLDER $path '#';
  46.     }
  47.     public function replace(string $contentstring $hostSalesChannelContext $salesChannelContext): string
  48.     {
  49.         $matches = [];
  50.         if (preg_match_all('/' self::DOMAIN_PLACEHOLDER '[^#]*#/'$content$matches)) {
  51.             $mapping $this->createDefaultMapping($matches[0]);
  52.             $seoMapping $this->createSeoMapping($salesChannelContext$mapping);
  53.             foreach ($seoMapping as $key => $value) {
  54.                 $seoMapping[$key] = $host '/' ltrim($value'/');
  55.             }
  56.             $content str_replace(array_keys($seoMapping), array_values($seoMapping), $content);
  57.         }
  58.         return $content;
  59.     }
  60.     private function createDefaultMapping(array $matches): array
  61.     {
  62.         $mapping = [];
  63.         foreach ($matches as $match) {
  64.             $mapping[$match] = str_replace(self::DOMAIN_PLACEHOLDER''rtrim($match'#'));
  65.         }
  66.         return $mapping;
  67.     }
  68.     private function createSeoMapping(SalesChannelContext $context, array $mapping): array
  69.     {
  70.         if (empty($mapping)) {
  71.             return [];
  72.         }
  73.         $criteria = new Criteria();
  74.         $criteria->addFilter(new EqualsFilter('isCanonical'true));
  75.         $criteria->addFilter(new EqualsAnyFilter('pathInfo'$mapping));
  76.         $criteria->addSorting(new FieldSorting('salesChannelId'));
  77.         $criteria->setTitle('seo-url::replacement');
  78.         /** @var SeoUrlCollection $seoUrls */
  79.         $seoUrls $this->seoUrlRepository->search($criteria$context)->getEntities();
  80.         foreach ($seoUrls as $seoUrl) {
  81.             $seoPathInfo trim($seoUrl->getSeoPathInfo());
  82.             if ($seoPathInfo === '') {
  83.                 continue;
  84.             }
  85.             $key self::DOMAIN_PLACEHOLDER $seoUrl->getPathInfo() . '#';
  86.             $mapping[$key] = $seoPathInfo;
  87.         }
  88.         return $mapping;
  89.     }
  90.     private function removePrefix(string $subjectstring $prefix): string
  91.     {
  92.         if (!$prefix || mb_strpos($subject$prefix) !== 0) {
  93.             return $subject;
  94.         }
  95.         return mb_substr($subjectmb_strlen($prefix));
  96.     }
  97. }