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

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