vendor/shopware/core/Checkout/Customer/Subscriber/CustomerGroupSubscriber.php line 68

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Customer\Subscriber;
  3. use Cocur\Slugify\SlugifyInterface;
  4. use Shopware\Core\Checkout\Customer\Aggregate\CustomerGroup\CustomerGroupCollection;
  5. use Shopware\Core\Checkout\Customer\Aggregate\CustomerGroupTranslation\CustomerGroupTranslationCollection;
  6. use Shopware\Core\Content\Seo\SeoUrlPersister;
  7. use Shopware\Core\Defaults;
  8. use Shopware\Core\Framework\Context;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\Log\Package;
  16. use Shopware\Core\System\Language\LanguageCollection;
  17. use Shopware\Core\System\Language\LanguageEntity;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. /**
  20.  * @internal
  21.  */
  22. #[Package('customer-order')]
  23. class CustomerGroupSubscriber implements EventSubscriberInterface
  24. {
  25.     private const ROUTE_NAME 'frontend.account.customer-group-registration.page';
  26.     /**
  27.      * @internal
  28.      */
  29.     public function __construct(
  30.         private readonly EntityRepository $customerGroupRepository,
  31.         private readonly EntityRepository $seoUrlRepository,
  32.         private readonly EntityRepository $languageRepository,
  33.         private readonly SeoUrlPersister $persister,
  34.         private readonly SlugifyInterface $slugify
  35.     ) {
  36.     }
  37.     public static function getSubscribedEvents(): array
  38.     {
  39.         return [
  40.             'customer_group_translation.written' => 'updatedCustomerGroup',
  41.             'customer_group_registration_sales_channels.written' => 'newSalesChannelAddedToCustomerGroup',
  42.             'customer_group_translation.deleted' => 'deleteCustomerGroup',
  43.         ];
  44.     }
  45.     public function newSalesChannelAddedToCustomerGroup(EntityWrittenEvent $event): void
  46.     {
  47.         $ids = [];
  48.         foreach ($event->getWriteResults() as $writeResult) {
  49.             /** @var array<string, string> $pk */
  50.             $pk $writeResult->getPrimaryKey();
  51.             $ids[] = $pk['customerGroupId'];
  52.         }
  53.         if (\count($ids) === 0) {
  54.             return;
  55.         }
  56.         $this->createUrls($ids$event->getContext());
  57.     }
  58.     public function updatedCustomerGroup(EntityWrittenEvent $event): void
  59.     {
  60.         $ids = [];
  61.         foreach ($event->getWriteResults() as $writeResult) {
  62.             if ($writeResult->hasPayload('registrationTitle')) {
  63.                 /** @var array<string, string> $pk */
  64.                 $pk $writeResult->getPrimaryKey();
  65.                 $ids[] = $pk['customerGroupId'];
  66.             }
  67.         }
  68.         if (\count($ids) === 0) {
  69.             return;
  70.         }
  71.         $this->createUrls($ids$event->getContext());
  72.     }
  73.     public function deleteCustomerGroup(EntityDeletedEvent $event): void
  74.     {
  75.         $ids = [];
  76.         foreach ($event->getWriteResults() as $writeResult) {
  77.             /** @var array<string, string> $pk */
  78.             $pk $writeResult->getPrimaryKey();
  79.             $ids[] = $pk['customerGroupId'];
  80.         }
  81.         if (\count($ids) === 0) {
  82.             return;
  83.         }
  84.         $criteria = new Criteria();
  85.         $criteria->addFilter(new EqualsAnyFilter('foreignKey'$ids));
  86.         $criteria->addFilter(new EqualsFilter('routeName'self::ROUTE_NAME));
  87.         /** @var array<string> $ids */
  88.         $ids array_values($this->seoUrlRepository->searchIds($criteria$event->getContext())->getIds());
  89.         if (\count($ids) === 0) {
  90.             return;
  91.         }
  92.         $this->seoUrlRepository->delete(array_map(fn (string $id) => ['id' => $id], $ids), $event->getContext());
  93.     }
  94.     /**
  95.      * @param list<string> $ids
  96.      */
  97.     private function createUrls(array $idsContext $context): void
  98.     {
  99.         $criteria = new Criteria($ids);
  100.         $criteria->addFilter(new EqualsFilter('registrationActive'true));
  101.         $criteria->addAssociation('registrationSalesChannels.languages');
  102.         $criteria->addAssociation('translations');
  103.         /** @var CustomerGroupCollection $groups */
  104.         $groups $this->customerGroupRepository->search($criteria$context)->getEntities();
  105.         $buildUrls = [];
  106.         foreach ($groups as $group) {
  107.             if ($group->getRegistrationSalesChannels() === null) {
  108.                 continue;
  109.             }
  110.             foreach ($group->getRegistrationSalesChannels() as $registrationSalesChannel) {
  111.                 if ($registrationSalesChannel->getLanguages() === null) {
  112.                     continue;
  113.                 }
  114.                 /** @var array<string> $languageIds */
  115.                 $languageIds $registrationSalesChannel->getLanguages()->getIds();
  116.                 $criteria = new Criteria($languageIds);
  117.                 /** @var LanguageCollection $languageCollection */
  118.                 $languageCollection $this->languageRepository->search($criteria$context)->getEntities();
  119.                 foreach ($languageIds as $languageId) {
  120.                     /** @var LanguageEntity $language */
  121.                     $language $languageCollection->get($languageId);
  122.                     $title $this->getTranslatedTitle($group->getTranslations(), $language);
  123.                     if (!isset($buildUrls[$languageId])) {
  124.                         $buildUrls[$languageId] = [
  125.                             'urls' => [],
  126.                             'salesChannel' => $registrationSalesChannel,
  127.                         ];
  128.                     }
  129.                     $buildUrls[$languageId]['urls'][] = [
  130.                         'salesChannelId' => $registrationSalesChannel->getId(),
  131.                         'foreignKey' => $group->getId(),
  132.                         'routeName' => self::ROUTE_NAME,
  133.                         'pathInfo' => '/customer-group-registration/' $group->getId(),
  134.                         'isCanonical' => true,
  135.                         'seoPathInfo' => '/' $this->slugify->slugify($title),
  136.                     ];
  137.                 }
  138.             }
  139.         }
  140.         foreach ($buildUrls as $languageId => $config) {
  141.             $context = new Context(
  142.                 $context->getSource(),
  143.                 $context->getRuleIds(),
  144.                 $context->getCurrencyId(),
  145.                 [$languageId]
  146.             );
  147.             $this->persister->updateSeoUrls(
  148.                 $context,
  149.                 self::ROUTE_NAME,
  150.                 array_column($config['urls'], 'foreignKey'),
  151.                 $config['urls'],
  152.                 $config['salesChannel']
  153.             );
  154.         }
  155.     }
  156.     private function getTranslatedTitle(?CustomerGroupTranslationCollection $translationsLanguageEntity $language): string
  157.     {
  158.         if ($translations === null) {
  159.             return '';
  160.         }
  161.         // Requested translation
  162.         foreach ($translations as $translation) {
  163.             if ($translation->getLanguageId() === $language->getId() && $translation->getRegistrationTitle() !== null) {
  164.                 return $translation->getRegistrationTitle();
  165.             }
  166.         }
  167.         // Inherited translation
  168.         foreach ($translations as $translation) {
  169.             if ($translation->getLanguageId() === $language->getParentId() && $translation->getRegistrationTitle() !== null) {
  170.                 return $translation->getRegistrationTitle();
  171.             }
  172.         }
  173.         // System Language
  174.         foreach ($translations as $translation) {
  175.             if ($translation->getLanguageId() === Defaults::LANGUAGE_SYSTEM && $translation->getRegistrationTitle() !== null) {
  176.                 return $translation->getRegistrationTitle();
  177.             }
  178.         }
  179.         return '';
  180.     }
  181. }