custom/plugins/SelfdelveCms/src/Subscriber/StorefrontSubscriber.php line 82

Open in your IDE?
  1. <?php
  2. namespace Selfdelve\Cms\Subscriber;
  3. use MoorlFormBuilder\Core\Event\FormOptionCriteriaEvent;
  4. use Shopware\Core\Checkout\Cart\Event\AfterLineItemAddedEvent;
  5. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
  6. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  7. use Shopware\Core\Content\Category\CategoryDefinition;
  8. use Shopware\Core\Content\Category\CategoryEntity;
  9. use Shopware\Core\Content\Media\MediaEntity;
  10. use Shopware\Core\Content\Product\ProductDefinition;
  11. use Shopware\Core\Content\Product\ProductEntity;
  12. use Shopware\Core\Content\Property\PropertyGroupEntity;
  13. use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\AndFilter;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  19. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  20. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\OrFilter;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  22. use Shopware\Core\Framework\Struct\ArrayEntity;
  23. use Shopware\Core\System\SystemConfig\SystemConfigService;
  24. use Shopware\Storefront\Framework\Routing\Router;
  25. use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
  26. use Shopware\Storefront\Pagelet\Header\HeaderPageletLoadedEvent;
  27. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  28. use Symfony\Component\HttpFoundation\RedirectResponse;
  29. class StorefrontSubscriber implements EventSubscriberInterface
  30. {
  31.     const PROPERTY_GROUP_NAMES = [
  32.         'COLOUR' => [
  33.             'Farbe Konfigurator',
  34.             'Colour Configurator'
  35.         ],
  36.         'CORPUS' => [
  37.             'Grundkörper',
  38.             'Base Body'
  39.         ]
  40.     ];
  41.     const FORM_ELEMENT_TO_PROPERTY_GROUP_MAPPING = [
  42.         'color_1' => 'COLOUR',
  43.         'color_2' => 'COLOUR',
  44.         'color_3' => 'COLOUR',
  45.         'base_body' => 'CORPUS'
  46.     ];
  47.     const CUSTOM_FIELD_CATEGORY_TOKEN 'selfdelve_theme_category_access_token';
  48.     const CATEGORY_NAME_TOPBAR 'Topbar';
  49.     private DefinitionInstanceRegistry $definitionInstanceRegistry;
  50.     private SystemConfigService $systemConfigService;
  51.     private ?Router $router null;
  52.     public function __construct(
  53.         DefinitionInstanceRegistry $definitionInstanceRegistry,
  54.         SystemConfigService $systemConfigService,
  55.         ?Router $router
  56.     )
  57.     {
  58.         $this->definitionInstanceRegistry $definitionInstanceRegistry;
  59.         $this->systemConfigService $systemConfigService;
  60.         $this->router $router;
  61.     }
  62.     public static function getSubscribedEvents(): array
  63.     {
  64.         return [
  65.             HeaderPageletLoadedEvent::class => 'onHeaderLoaded',
  66.             FormOptionCriteriaEvent::class => 'onProductRequest',
  67.             NavigationPageLoadedEvent::class => 'onNavigationPageLoaded',
  68.             BeforeLineItemAddedEvent::class => 'beforeLineItemAdded',
  69.         ];
  70.     }
  71.     public function onHeaderLoaded(HeaderPageletLoadedEvent $event): void
  72.     {
  73.         $repository $this->definitionInstanceRegistry->getRepository('category');
  74.         $criteria = new Criteria();
  75.         $criteria->addFilter(new EqualsFilter('name'self::CATEGORY_NAME_TOPBAR));
  76.         $criteria->addAssociation('children');
  77.         /** @var CategoryEntity $category */
  78.         $category $repository->search($criteria$event->getContext())->first();
  79.         if (!$category instanceof CategoryEntity) {
  80.             return;
  81.         }
  82.         $event->getContext()->addExtension(
  83.             'topnav',
  84.             new ArrayEntity(['categories' => $category->getChildren()])
  85.         );
  86.     }
  87.     public function onProductRequest(FormOptionCriteriaEvent $event): void
  88.     {
  89.         if (intval($event->getElement()['isEntitySelect']) !== 1) {
  90.             return;
  91.         }
  92.         if (!array_key_exists($event->getElement()['name'], self::FORM_ELEMENT_TO_PROPERTY_GROUP_MAPPING)) {
  93.             return;
  94.         }
  95.         $m self::FORM_ELEMENT_TO_PROPERTY_GROUP_MAPPING[$event->getElement()['name']];
  96.         if (!array_key_exists($mself::PROPERTY_GROUP_NAMES)) {
  97.             return;
  98.         }
  99.         $repository $this->definitionInstanceRegistry->getRepository('property_group');
  100.         $criteria = new Criteria();
  101.         $criteria->addAssociation('options');
  102.         $criteria->addFilter(new EqualsAnyFilter('name'self::PROPERTY_GROUP_NAMES[$m]));
  103.         /** @var PropertyGroupEntity $propertyGroupEntity */
  104.         $productGroup $repository->search($criteria$event->getContext())->first();
  105.         if (!$productGroup) {
  106.             return;
  107.         }
  108.         $event->setCriteria(
  109.             $event->getCriteria()
  110.                 ->addAssociation('group')
  111.                 ->addFilter(new EqualsFilter('group.id'$productGroup->getId()))
  112.                 ->resetSorting()
  113.                 ->addSorting(new FieldSorting('position'FieldSorting::ASCENDING))
  114.         );
  115.     }
  116.     public function onNavigationPageLoaded(NavigationPageLoadedEvent $event): void
  117.     {
  118.         $navigationId $event->getRequest()->get(
  119.             'navigationId',
  120.             $event->getSalesChannelContext()->getSalesChannel()->getNavigationCategoryId()
  121.         );
  122.         $repository $this->definitionInstanceRegistry->getRepository(CategoryDefinition::ENTITY_NAME);
  123.         if (!$repository) {
  124.             return;
  125.         }
  126.         /** @var CategoryEntity $category */
  127.         $category $repository->search(new Criteria([$navigationId]), $event->getContext())->first();
  128.         if (!$category instanceof CategoryEntity) {
  129.             return;
  130.         }
  131.         // Handle only pages that are not visible
  132.         if ($category->getType() !== CategoryDefinition::TYPE_PAGE || $category->getVisible() !== false) {
  133.             return;
  134.         }
  135.         // Custom fields with required token
  136.         $customFields $category->getCustomFields();
  137.         if (!isset($customFields[self::CUSTOM_FIELD_CATEGORY_TOKEN]) || $customFields[self::CUSTOM_FIELD_CATEGORY_TOKEN] === '') {
  138.             return;
  139.         }
  140.         // Check failed
  141.         if ($event->getRequest()->get('t') !== $customFields[self::CUSTOM_FIELD_CATEGORY_TOKEN]) {
  142.             $path $this->router->generate('frontend.home.page');
  143.             (new RedirectResponse($path))->send();
  144.             return;
  145.         }
  146.     }
  147.     public function beforeLineItemAdded(BeforeLineItemAddedEvent $event)
  148.     {
  149.         $lineItem $event->getLineItem();
  150.         if ($lineItem->getType() !== LineItem::PRODUCT_LINE_ITEM_TYPE) {
  151.             return;
  152.         }
  153.         $repository $this->definitionInstanceRegistry->getRepository(ProductDefinition::ENTITY_NAME);
  154.         if (!$repository instanceof EntityRepository) {
  155.             return;
  156.         }
  157.         $criteria = new Criteria();
  158.         $criteria->addAssociations([
  159.             'options',
  160.             'options.group',
  161.             'options.media'
  162.         ]);
  163.         $criteria->addFilter(new EqualsFilter('id'$lineItem->getId()));
  164.         $criteria->setLimit(1);
  165.         $product $repository->search($criteria$event->getContext())->first();
  166.         if (!$product instanceof ProductEntity) {
  167.             return;
  168.         }
  169.         if (
  170.             !isset($product->getCustomFields()['selfdelve_theme_product_is_configurator']) ||
  171.             true !== $product->getCustomFields()['selfdelve_theme_product_is_configurator'] ||
  172.             === count($product->getOptions())
  173.         ) {
  174.             return;
  175.         }
  176.         $groupId $this->systemConfigService->get('SelfdelveCms.config.colorOptionId');
  177.         if ('' === $groupId) {
  178.             return;
  179.         }
  180.         foreach ($product->getOptions() as $option) {
  181.             if ($option->getGroup()->getId() === $groupId && $option->getMedia()) {
  182.                 $lineItem->setPayloadValue('cover_url'$option->getMedia()->getUrl());
  183.                 // Setting the cover is not possible
  184.                 // $lineItem->setCover($option->getMedia());
  185.                 return;
  186.             }
  187.         }
  188.     }
  189. }