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

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\CategoryEvents;
  5. use Shopware\Core\Content\Category\Event\CategoryIndexerEvent;
  6. use Shopware\Core\Content\Product\Events\ProductIndexerEvent;
  7. use Shopware\Core\Content\Product\ProductEvents;
  8. use Shopware\Core\Content\Seo\SeoUrlUpdater;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Indexing\EntityIndexerRegistry;
  11. use Shopware\Core\Framework\Uuid\Uuid;
  12. use Shopware\Core\System\SalesChannel\SalesChannelDefinition;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. class SeoUrlUpdateListener implements EventSubscriberInterface
  15. {
  16.     /**
  17.      * @var SeoUrlUpdater
  18.      */
  19.     private $seoUrlUpdater;
  20.     /**
  21.      * @var Connection
  22.      */
  23.     private $connection;
  24.     /**
  25.      * @var EntityIndexerRegistry
  26.      */
  27.     private $indexerRegistry;
  28.     public function __construct(SeoUrlUpdater $seoUrlUpdaterConnection $connectionEntityIndexerRegistry $indexerRegistry)
  29.     {
  30.         $this->seoUrlUpdater $seoUrlUpdater;
  31.         $this->connection $connection;
  32.         $this->indexerRegistry $indexerRegistry;
  33.     }
  34.     public function detectSalesChannelEntryPoints(EntityWrittenContainerEvent $event): void
  35.     {
  36.         $properties = ['navigationCategoryId''footerCategoryId''serviceCategoryId'];
  37.         $salesChannelIds $event->getPrimaryKeysWithPropertyChange(SalesChannelDefinition::ENTITY_NAME$properties);
  38.         if (empty($salesChannelIds)) {
  39.             return;
  40.         }
  41.         $this->indexerRegistry->sendIndexingMessage(['category.indexer''product.indexer']);
  42.     }
  43.     public static function getSubscribedEvents()
  44.     {
  45.         return [
  46.             ProductEvents::PRODUCT_INDEXER_EVENT => 'updateProductUrls',
  47.             CategoryEvents::CATEGORY_INDEXER_EVENT => 'updateCategoryUrls',
  48.             EntityWrittenContainerEvent::class => 'detectSalesChannelEntryPoints',
  49.         ];
  50.     }
  51.     public function updateCategoryUrls(CategoryIndexerEvent $event): void
  52.     {
  53.         $ids array_merge($event->getIds(), $this->getCategoryChildren($event->getIds()));
  54.         $this->seoUrlUpdater->update(NavigationPageSeoUrlRoute::ROUTE_NAME$ids);
  55.     }
  56.     public function updateProductUrls(ProductIndexerEvent $event): void
  57.     {
  58.         $ids array_merge($event->getIds(), $this->getProductChildren($event->getIds()));
  59.         $this->seoUrlUpdater->update(ProductPageSeoUrlRoute::ROUTE_NAME$ids);
  60.     }
  61.     private function getProductChildren(array $ids): array
  62.     {
  63.         $childrenIds $this->connection->fetchAll(
  64.             'SELECT DISTINCT LOWER(HEX(id)) as id FROM product WHERE parent_id IN (:ids)',
  65.             ['ids' => Uuid::fromHexToBytesList($ids)],
  66.             ['ids' => Connection::PARAM_STR_ARRAY]
  67.         );
  68.         return array_column($childrenIds'id');
  69.     }
  70.     private function getCategoryChildren(array $ids): array
  71.     {
  72.         if (empty($ids)) {
  73.             return [];
  74.         }
  75.         $query $this->connection->createQueryBuilder();
  76.         $query->select('category.id');
  77.         $query->from('category');
  78.         foreach ($ids as $id) {
  79.             $key 'id' $id;
  80.             $query->orWhere('category.path LIKE :' $key);
  81.             $query->setParameter($key'%' $id '%');
  82.         }
  83.         $children $query->execute()->fetchAll(\PDO::FETCH_COLUMN);
  84.         if (!$children) {
  85.             return [];
  86.         }
  87.         return Uuid::fromBytesToHexList($children);
  88.     }
  89. }