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

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.     /**
  35.      * @internal
  36.      */
  37.     public function __construct(SeoUrlUpdater $seoUrlUpdaterConnection $connectionEntityIndexerRegistry $indexerRegistry)
  38.     {
  39.         $this->seoUrlUpdater $seoUrlUpdater;
  40.         $this->connection $connection;
  41.         $this->indexerRegistry $indexerRegistry;
  42.     }
  43.     public function detectSalesChannelEntryPoints(EntityWrittenContainerEvent $event): void
  44.     {
  45.         $properties = ['navigationCategoryId''footerCategoryId''serviceCategoryId'];
  46.         $salesChannelIds $event->getPrimaryKeysWithPropertyChange(SalesChannelDefinition::ENTITY_NAME$properties);
  47.         if (empty($salesChannelIds)) {
  48.             return;
  49.         }
  50.         $this->indexerRegistry->sendIndexingMessage(['category.indexer''product.indexer']);
  51.     }
  52.     /**
  53.      * @return array<string, string|array{0: string, 1: int}|list<array{0: string, 1?: int}>>
  54.      */
  55.     public static function getSubscribedEvents()
  56.     {
  57.         return [
  58.             ProductEvents::PRODUCT_INDEXER_EVENT => 'updateProductUrls',
  59.             CategoryEvents::CATEGORY_INDEXER_EVENT => 'updateCategoryUrls',
  60.             LandingPageEvents::LANDING_PAGE_INDEXER_EVENT => 'updateLandingPageUrls',
  61.             EntityWrittenContainerEvent::class => 'detectSalesChannelEntryPoints',
  62.         ];
  63.     }
  64.     public function updateCategoryUrls(CategoryIndexerEvent $event): void
  65.     {
  66.         if (\in_array(self::CATEGORY_SEO_URL_UPDATER$event->getSkip(), true)) {
  67.             return;
  68.         }
  69.         $ids array_merge($event->getIds(), $this->getCategoryChildren($event->getIds()));
  70.         $this->seoUrlUpdater->update(NavigationPageSeoUrlRoute::ROUTE_NAME$ids);
  71.     }
  72.     public function updateProductUrls(ProductIndexerEvent $event): void
  73.     {
  74.         if (\in_array(self::PRODUCT_SEO_URL_UPDATER$event->getSkip(), true)) {
  75.             return;
  76.         }
  77.         $this->seoUrlUpdater->update(ProductPageSeoUrlRoute::ROUTE_NAME$event->getIds());
  78.     }
  79.     public function updateLandingPageUrls(LandingPageIndexerEvent $event): void
  80.     {
  81.         if (\in_array(self::LANDING_PAGE_SEO_URL_UPDATER$event->getSkip(), true)) {
  82.             return;
  83.         }
  84.         $this->seoUrlUpdater->update(LandingPageSeoUrlRoute::ROUTE_NAME$event->getIds());
  85.     }
  86.     private function getCategoryChildren(array $ids): array
  87.     {
  88.         if (empty($ids)) {
  89.             return [];
  90.         }
  91.         $query $this->connection->createQueryBuilder();
  92.         $query->select('category.id, category.type');
  93.         $query->from('category');
  94.         foreach ($ids as $id) {
  95.             $key 'id' $id;
  96.             $query->orWhere('category.type != :type AND category.path LIKE :' $key);
  97.             $query->setParameter($key'%' $id '%');
  98.         }
  99.         $query->setParameter('type'CategoryDefinition::TYPE_LINK);
  100.         $children $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
  101.         if (!$children) {
  102.             return [];
  103.         }
  104.         return Uuid::fromBytesToHexList($children);
  105.     }
  106. }