custom/plugins/BDLCustomThemeChanges/src/Subscriber/StorefrontSubscriber.php line 56

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace BDL\CustomThemeChanges\Subscriber;
  4. use Shopware\Core\Content\Category\CategoryCollection;
  5. use Shopware\Core\Content\Media\MediaCollection;
  6. use Shopware\Core\Content\Product\ProductCollection;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  12. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  13. use Shopware\Core\System\SalesChannel\SalesChannelEntity;
  14. use Shopware\Storefront\Event\StorefrontRenderEvent;
  15. use Symfony\Component\DependencyInjection\ContainerInterface;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  18. class StorefrontSubscriber implements EventSubscriberInterface
  19. {
  20.     /**
  21.      * @var ContainerInterface
  22.      */
  23.     protected $container;
  24.     /**
  25.      * @var EntityRepositoryInterface
  26.      */
  27.     private $productRepo;
  28.     private $categoryRepository;
  29.     private $mediaRepository;
  30.     public function __construct(
  31.         ContainerInterface $container,
  32.         EntityRepositoryInterface $categoryRepository,
  33.         EntityRepositoryInterface $productRepo,
  34.         EntityRepositoryInterface $mediaRepository
  35.     ) {
  36.         $this->container $container;
  37.         $this->categoryRepository $categoryRepository;
  38.         $this->productRepo $productRepo;
  39.         $this->mediaRepository $mediaRepository;
  40.     }
  41.     public static function getSubscribedEvents(): array
  42.     {
  43.         return [
  44.             StorefrontRenderEvent::class => 'onStorefrontRender',
  45.             ProductPageLoadedEvent::class => 'onLoadProductPage',
  46.         ];
  47.     }
  48.     public function onStorefrontRender(StorefrontRenderEvent $event)
  49.     {
  50.         $categories = [];
  51.         $salesChannelContext $event->getSalesChannelContext();
  52.         $params $event->getParameters();
  53.         $request $event->getRequest();
  54.         $context $event->getContext();
  55.         $salesChannelEntity $salesChannelContext->getSalesChannel();
  56.         $footerMenuId $salesChannelEntity->getFooterCategoryId();
  57.         $headerContactMenuId $salesChannelEntity->getFooterCategoryId();
  58.         $customFields $this->loadCustomFields($salesChannelEntity);
  59.         $bdlCustomFields $salesChannelEntity->getCustomFields();
  60.         $event->setParameter('bdlCustomThemeSettings'$customFields);
  61.         $event->setParameter('bdlFooterMenu'$this->loadFooterMenu($context$footerMenuId));
  62.         $topBarMenus = [];
  63.         if (!empty($bdlCustomFields['BDL_topbar_contact_menu']))
  64.             $topBarMenus $this->getContactMenu($context$bdlCustomFields['BDL_topbar_contact_menu']);
  65.         $event->setParameter('bdlTopbarContactMenu'$topBarMenus);
  66.         $event->setParameter('plugins'$this->getAllPlugins());
  67.         
  68.         $route $event->getRequest()->attributes->get('_route');
  69.         
  70.         if($route == 'frontend.detail.page') {
  71.             $params $event->getParameters();
  72.             $product $params['page']->getProduct();
  73.             $availableOptions = [];
  74.             if($product->getParentId()) {
  75.                 $salesChannelContext $event->getSalesChannelContext();
  76.                 $saleChannelId $salesChannelContext->getSalesChannel()->getId();
  77.                 $availableOptions $this->getAvailableOptions($product,$saleChannelId);
  78.                 $availableOptions array_reduce($availableOptions'array_merge', array());
  79.                 $event->setParameter('availableOptions'$availableOptions);
  80.             }
  81.         }
  82.     }
  83.     private function loadCustomFields(SalesChannelEntity $salesChannelEntity): array
  84.     {
  85.         $customFields $salesChannelEntity->getCustomFields() ?? [];
  86.         return $customFields;
  87.     }
  88.     private function loadFooterMenu($context$footerMenuId): CategoryCollection
  89.     {
  90.         $criteria = (new Criteria())
  91.             ->addFilter(new EqualsFilter('category.active'true))
  92.             ->addFilter(new EqualsFilter('category.parentId'$footerMenuId));
  93.         /** @var CategoryCollection $categories */
  94.         $categories $this->categoryRepository->search($criteria$context)->getEntities();
  95.         return $categories->sortByPosition();
  96.     }
  97.     private function getContactMenu($context$headerMenuId): CategoryCollection
  98.     {
  99.         $criteria = (new Criteria())
  100.             ->addFilter(new EqualsFilter('category.active'true))
  101.             ->addFilter(new EqualsAnyFilter('category.id'$headerMenuId));
  102.         /** @var CategoryCollection $categories */
  103.         $categories $this->categoryRepository->search($criteria$context)->getEntities();
  104.         return $categories->sortByPosition();
  105.     }
  106.     public function searchCategory(array $idsContext $context): CategoryCollection
  107.     {
  108.         if (empty($ids)) {
  109.             return new CategoryCollection();
  110.         }
  111.         $criteria = new Criteria($ids);
  112.         /** @var CategoryCollection $product */
  113.         $category $this->categoryRepository
  114.             ->search($criteria$context)
  115.             ->getEntities();
  116.         return $category;
  117.     }
  118.     private function getAllPlugins()
  119.     {
  120.         $pluginRepo $this->container->get('plugin.repository');
  121.         $criteria = (new Criteria());
  122.         $plugins $pluginRepo->search($criteriaContext::createDefaultContext())->getEntities();
  123.         $pluginsArray = [];
  124.         if (!empty($plugins)) {
  125.             foreach ($plugins as $plugin) {
  126.                 $pluginsArray[$plugin->getName()] = $plugin;
  127.             }
  128.         }
  129.         return ($pluginsArray) ? $pluginsArray null;
  130.     }
  131.     public function onLoadProductPage(ProductPageLoadedEvent $event)
  132.     {
  133.         $salesChannelContext $event->getSalesChannelContext();
  134.         $saleChannelId $salesChannelContext->getSalesChannel()->getId();
  135.         $product $event->getPage()->getProduct();
  136.         
  137.         $product->setExtensions([
  138.             'salesChannelId' => $saleChannelId
  139.             ]);
  140.     }
  141.     public function getAvailableOptions($product$saleChannelId) {
  142.         $productRepository $this->container->get('product.repository');
  143.         $criteria = new Criteria([]);
  144.         $criteria->addFilter(new EqualsFilter('parentId'$product->getParentId()));
  145.         $criteria->addAssociation('entities.visibilities');
  146.         /** @var ProductEntity $product */
  147.         $parentProduct $productRepository->search($criteriaContext::createDefaultContext())->getEntities();
  148.         $activeOptions = [];
  149.         foreach($parentProduct->getElements() as $prodOption) {
  150.             $activeOptions[] = $this->getVisibility($prodOption->getId(),$saleChannelId);
  151.         }
  152.         return $activeOptions;        
  153.     }
  154.     public function getVisibility($productId,$saleChannelId) {
  155.         
  156.         $productRepository $this->container->get('product.repository');
  157.         $criteria = new Criteria([$productId]);
  158.         $criteria->addAssociation('visibilities');
  159.         $criteria->addAssociation('options');
  160.         /** @var ProductEntity $product */
  161.         $productEntity $productRepository->search($criteriaContext::createDefaultContext())->first();
  162.         $prodIds= [];
  163.         foreach($productEntity->getVisibilities()->getElements() as $entity) {
  164.             if($entity->getSalesChannelId() == $saleChannelId && $productEntity->getActive()) {
  165.                 $options $productEntity->getOptions()->getElements();                
  166.                 foreach($options as $option) {
  167.                     $prodIds[] = $option->getId();
  168.                 }
  169.             }
  170.         }
  171.         return $prodIds;
  172.     }
  173. }