custom/plugins/WbfkExtensions/src/Subscriber/ProductPageSubscriber.php line 52

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace WbfkExtensions\Subscriber;
  4. use Exception;
  5. use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
  6. use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;
  7. use Shopware\Core\Content\Product\Events\ProductCrossSellingStreamCriteriaEvent;
  8. use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
  9. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  10. use Shopware\Core\Framework\Context;
  11. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\OrFilter;
  15. use Shopware\Core\Framework\Struct\ArrayEntity;
  16. use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
  17. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  18. use Symfony\Component\DependencyInjection\Container;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  21. use WbfkExtensions\Core\Content\ProductAdditionalService\SalesChannel\AdditionalServiceRoute;
  22. class ProductPageSubscriber implements EventSubscriberInterface
  23. {
  24. /** @var EntityRepositoryInterface */
  25. private $customFieldSetRepository;
  26. public function __construct(private readonly AdditionalServiceRoute $additionalServiceRoute, Container $container)
  27. {
  28. try {
  29. $this->customFieldSetRepository = $container->get('custom_field_set.repository');
  30. } catch (Exception) {
  31. }
  32. }
  33. public static function getSubscribedEvents(): array
  34. {
  35. return [
  36. ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
  37. ProductPageCriteriaEvent::class => 'onProductPageCriteriaEvent',
  38. ProductCrossSellingIdsCriteriaEvent::class => 'onProductCrossSellingIdsCriteriaEvent',
  39. ProductCrossSellingStreamCriteriaEvent::class => 'onProductCrossSellingStreamCriteriaEvent',
  40. ];
  41. }
  42. public function onProductPageLoadedEvent(ProductPageLoadedEvent $event): void
  43. {
  44. $product = $event->getPage()->getProduct();
  45. $this->loadAdditionalServiceToPage($product, $event);
  46. $this->loadCustomFieldSet($product, $event->getContext());
  47. }
  48. public function loadAdditionalServiceToPage(SalesChannelProductEntity $product, ProductPageLoadedEvent $event): void
  49. {
  50. try {
  51. $additionalService = $this->additionalServiceRoute->load(
  52. $product->getId(),
  53. $event->getRequest(),
  54. $event->getSalesChannelContext(),
  55. new Criteria()
  56. )->getAdditionalService();
  57. /** @noinspection PhpDeprecationInspection */
  58. $event->getPage()->addExtension('additionalService', $additionalService);
  59. } catch (NotFoundHttpException) {
  60. // No additional services found
  61. }
  62. }
  63. private function loadCustomFieldSet(SalesChannelProductEntity $product, Context $context): void
  64. {
  65. $criteria = new Criteria();
  66. $criteria->addFilter(new EqualsFilter('name', 'wbfk_further_technical_data'));
  67. $criteria->addAssociation('customFields');
  68. $customFieldSet = $this->customFieldSetRepository->search($criteria, $context)->first();
  69. $customFieldSetFields = $customFieldSet->getCustomFields()->getElements();
  70. $filledCustomFieldSetFields = $product->getCustomFields();
  71. $matchingCustomFieldSetFields = [];
  72. foreach ($customFieldSetFields as $key => $customFieldSetField) {
  73. $customFieldSetFields[$key] = $customFieldSetField;
  74. $customFieldSetName = $customFieldSetField->getName();
  75. if (isset($filledCustomFieldSetFields["$customFieldSetName"]) ?? null) {
  76. $object = new \stdClass();
  77. $object->label = $customFieldSetField->getConfig()['label'];
  78. $object->position = $customFieldSetField->getConfig()['customFieldPosition'];
  79. $object->type = $customFieldSetField->getType();
  80. $object->value = $filledCustomFieldSetFields["$customFieldSetName"];
  81. $matchingCustomFieldSetFields[] = $object;
  82. }
  83. }
  84. usort($matchingCustomFieldSetFields, function ($a, $b) {
  85. return $a->position > $b->position;
  86. });
  87. if ($matchingCustomFieldSetFields) {
  88. $product->addExtension('wbfk_additional_data_customFieldset', new ArrayEntity($matchingCustomFieldSetFields));
  89. }
  90. }
  91. public function onProductPageCriteriaEvent(ProductPageCriteriaEvent $event): void
  92. {
  93. $event->getCriteria()->addFilter(
  94. new OrFilter(
  95. [
  96. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_ALL),
  97. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_SEARCH),
  98. ]
  99. )
  100. );
  101. }
  102. public function onProductCrossSellingIdsCriteriaEvent(ProductCrossSellingIdsCriteriaEvent $event): void
  103. {
  104. $event->getCriteria()->addFilter(
  105. new OrFilter(
  106. [
  107. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_ALL),
  108. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_SEARCH),
  109. ]
  110. )
  111. );
  112. }
  113. public function onProductCrossSellingStreamCriteriaEvent(ProductCrossSellingStreamCriteriaEvent $event): void
  114. {
  115. $event->getCriteria()->addFilter(
  116. new OrFilter(
  117. [
  118. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_ALL),
  119. new ProductAvailableFilter($event->getSalesChannelContext()->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_SEARCH),
  120. ]
  121. )
  122. );
  123. }
  124. }