custom/plugins/MageWorxSeoCrosslinks/src/Subscriber/ProductSubscriber.php line 53

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace MageWorx\SeoCrosslinks\Subscriber;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  10. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  11. use Shopware\Core\Content\Product\ProductEvents;
  12. use Symfony\Component\HttpFoundation\RequestStack;
  13. use Shopware\Core\System\SystemConfig\SystemConfigService;
  14. use MageWorx\SeoCrosslinks\Core\Content\Crosslink\Service\CrosslinkReplacer;
  15. use MageWorx\SeoCrosslinks\Core\Content\Crosslink\Service\SalesChannelContextProvider;
  16. class ProductSubscriber implements EventSubscriberInterface
  17. {
  18.     protected RequestStack $requestStack;
  19.     protected SystemConfigService $systemConfig;
  20.     protected EntityRepositoryInterface $crosslinkRepository;
  21.     protected CrosslinkReplacer $replacer;
  22.     protected SalesChannelContextProvider $salesChannelContextProvider;
  23.     public function __construct(
  24.         EntityRepositoryInterface $crosslinkRepository,
  25.         SystemConfigService $systemConfigService,
  26.         RequestStack $requestStack,
  27.         CrosslinkReplacer $replacer,
  28.         SalesChannelContextProvider $salesChannelContextProvider
  29.     ) {
  30.         $this->crosslinkRepository $crosslinkRepository;
  31.         $this->requestStack $requestStack;
  32.         $this->systemConfig $systemConfigService;
  33.         $this->replacer $replacer;
  34.         $this->salesChannelContextProvider $salesChannelContextProvider;
  35.     }
  36.     public static function getSubscribedEvents(): array
  37.     {
  38.         return [
  39.             ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded'
  40.         ];
  41.     }
  42.     public function onProductsLoaded(EntityLoadedEvent $event)
  43.     {
  44.         if ($this->isAllow()) {
  45.             $id $this->requestStack->getMainRequest()->attributes->get('productId');
  46.             $maxReplaceCount = (int)$this->systemConfig->get('MageWorxSeoCrosslinks.config.productMaxReplacementCount');
  47.             if ($maxReplaceCount) {
  48.                 $product current($event->getEntities());
  49.                 if ($product && $product->getId() === $id) {
  50.                     $translated $product->getTranslated();
  51.                     if ($translated) {
  52.                         $description $translated['description'];
  53.                         $modifiedDescription $this->getModifiedContent(
  54.                             $description,
  55.                             $product->getId(),
  56.                             $event->getContext(),
  57.                             $maxReplaceCount
  58.                         );
  59.                         if ($modifiedDescription) {
  60.                             $translated['description'] = $modifiedDescription;
  61.                             $product->setTranslated($translated);
  62.                         }
  63.                     }
  64.                 }
  65.             }
  66.         }
  67.     }
  68.     protected function isAllow(): bool
  69.     {
  70.         if ($this->systemConfig->getBool('MageWorxSeoCrosslinks.config.enable')) {
  71.             $request $this->requestStack->getMainRequest();
  72.             if ($request) {
  73.                 $route $request->attributes->get('_route');
  74.                 $productId $request->attributes->get('productId');
  75.                 if ($route === 'frontend.detail.page' && $productId) {
  76.                     return true;
  77.                 }
  78.             }
  79.         }
  80.         return false;
  81.     }
  82.     /**
  83.      * @param string|null $content
  84.      * @param string $entityId
  85.      * @param Context $context
  86.      * @param int $maxCount
  87.      * @return false|string
  88.      */
  89.     protected function getModifiedContent(
  90.         ?string $content,
  91.         string $entityId,
  92.         Context $context,
  93.         int $maxCount
  94.     ) {
  95.         if ($content === null) {
  96.             return $content;
  97.         }
  98.         $criteria = new Criteria();
  99.         $criteria->addFilter(
  100.             new EqualsFilter('isActive'true),
  101.             new EqualsFilter('inProduct'true),
  102.             new EqualsFilter('languageId'$context->getLanguageId()),
  103.             new EqualsFilter(
  104.                 'salesChannels.salesChannelId',
  105.                 $this->salesChannelContextProvider->getSalesChannelContext($context)->getSalesChannelId()
  106.             ),
  107.             new NotFilter('AND', [
  108.                 new EqualsFilter('internalLink'$entityId),
  109.             ])
  110.         );
  111.         $criteria->addSorting(new FieldSorting('priority''DESC'));
  112.         $crosslinkCollection $this->crosslinkRepository->search($criteria$context)->getEntities();
  113.         return $this->replacer->replace($context$crosslinkCollection$content$maxCount);
  114.     }
  115. }