vendor/shopware/storefront/Framework/Seo/SeoUrlRoute/SeoUrlUpdateListener.php line 48

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Framework\Seo\SeoUrlRoute;
  3. use Doctrine\DBAL\Connection;
  4. use Shopware\Core\Content\Category\CategoryDefinition;
  5. use Shopware\Core\Content\Category\CategoryEvents;
  6. use Shopware\Core\Content\Category\Event\CategoryIndexerEvent;
  7. use Shopware\Core\Content\LandingPage\Event\LandingPageIndexerEvent;
  8. use Shopware\Core\Content\LandingPage\LandingPageEvents;
  9. use Shopware\Core\Content\Product\Events\ProductIndexerEvent;
  10. use Shopware\Core\Content\Product\ProductEvents;
  11. use Shopware\Core\Content\Seo\SeoUrlUpdater;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Indexing\EntityIndexerRegistry;
  14. use Shopware\Core\Framework\Uuid\Uuid;
  15. use Shopware\Core\System\SalesChannel\SalesChannelDefinition;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class SeoUrlUpdateListener implements EventSubscriberInterface
  18. {
  19.     public const CATEGORY_SEO_URL_UPDATER 'category.seo-url';
  20.     public const PRODUCT_SEO_URL_UPDATER 'product.seo-url';
  21.     public const LANDING_PAGE_SEO_URL_UPDATER 'landing_page.seo-url';
  22.     /**
  23.      * @var SeoUrlUpdater
  24.      */
  25.     private $seoUrlUpdater;
  26.     /**
  27.      * @var Connection
  28.      */
  29.     private $connection;
  30.     /**
  31.      * @var EntityIndexerRegistry
  32.      */
  33.     private $indexerRegistry;
  34.     public function __construct(SeoUrlUpdater $seoUrlUpdaterConnection $connectionEntityIndexerRegistry $indexerRegistry)
  35.     {
  36.         $this->seoUrlUpdater $seoUrlUpdater;
  37.         $this->connection $connection;
  38.         $this->indexerRegistry $indexerRegistry;
  39.     }
  40.     public function detectSalesChannelEntryPoints(EntityWrittenContainerEvent $event): void
  41.     {
  42.         $properties = ['navigationCategoryId''footerCategoryId''serviceCategoryId'];
  43.         $salesChannelIds $event->getPrimaryKeysWithPropertyChange(SalesChannelDefinition::ENTITY_NAME$properties);
  44.         if (empty($salesChannelIds)) {
  45.             return;
  46.         }
  47.         $this->indexerRegistry->sendIndexingMessage(['category.indexer''product.indexer']);
  48.     }
  49.     /**
  50.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  51.      */
  52.     public static function getSubscribedEvents()
  53.     {
  54.         return [
  55.             ProductEvents::PRODUCT_INDEXER_EVENT => 'updateProductUrls',
  56.             CategoryEvents::CATEGORY_INDEXER_EVENT => 'updateCategoryUrls',
  57.             LandingPageEvents::LANDING_PAGE_INDEXER_EVENT => 'updateLandingPageUrls',
  58.             EntityWrittenContainerEvent::class => 'detectSalesChannelEntryPoints',
  59.         ];
  60.     }
  61.     public function updateCategoryUrls(CategoryIndexerEvent $event): void
  62.     {
  63.         if (\in_array(self::CATEGORY_SEO_URL_UPDATER$event->getSkip(), true)) {
  64.             return;
  65.         }
  66.         $ids array_merge($event->getIds(), $this->getCategoryChildren($event->getIds()));
  67.         $this->seoUrlUpdater->update(NavigationPageSeoUrlRoute::ROUTE_NAME$ids);
  68.     }
  69.     public function updateProductUrls(ProductIndexerEvent $event): void
  70.     {
  71.         if (\in_array(self::PRODUCT_SEO_URL_UPDATER$event->getSkip(), true)) {
  72.             return;
  73.         }
  74.         $this->seoUrlUpdater->update(ProductPageSeoUrlRoute::ROUTE_NAME$event->getIds());
  75.     }
  76.     public function updateLandingPageUrls(LandingPageIndexerEvent $event): void
  77.     {
  78.         if (\in_array(self::LANDING_PAGE_SEO_URL_UPDATER$event->getSkip(), true)) {
  79.             return;
  80.         }
  81.         $this->seoUrlUpdater->update(LandingPageSeoUrlRoute::ROUTE_NAME$event->getIds());
  82.     }
  83.     private function getCategoryChildren(array $ids): array
  84.     {
  85.         if (empty($ids)) {
  86.             return [];
  87.         }
  88.         $query $this->connection->createQueryBuilder();
  89.         $query->select('category.id, category.type');
  90.         $query->from('category');
  91.         foreach ($ids as $id) {
  92.             $key 'id' $id;
  93.             $query->orWhere('category.type != :type AND category.path LIKE :' $key);
  94.             $query->setParameter($key'%' $id '%');
  95.         }
  96.         $query->setParameter('type'CategoryDefinition::TYPE_LINK);
  97.         $children $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
  98.         if (!$children) {
  99.             return [];
  100.         }
  101.         return Uuid::fromBytesToHexList($children);
  102.     }
  103. }