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

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