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

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