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

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