custom/plugins/WbfkBundles/src/Subscriber/AddBundleDataToProductPage.php line 59

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Wbfk\Bundles\Subscriber;
  3. use Shopware\Core\Content\Product\ProductCollection;
  4. use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
  5. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductCollection;
  6. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductDefinition;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  11. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  12. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  13. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  16. use Wbfk\Bundles\Entity\Bundle\BundleProductCollection;
  17. use Wbfk\Bundles\Entity\Bundle\BundleProductEntity;
  18. use Wbfk\Bundles\Struct\ProductBundlesStruct;
  19. class AddBundleDataToProductPage implements EventSubscriberInterface
  20. {
  21.     public function __construct(
  22.         private EntityRepository               $bundleProductRepository,
  23.         private AbstractProductPriceCalculator $calculator,
  24.         private EventDispatcherInterface       $eventDispatcher,
  25.         private SalesChannelProductDefinition  $salesChannelProductDefinition
  26.     )
  27.     {
  28.     }
  29.     public static function getSubscribedEvents(): array
  30.     {
  31.         return [
  32.             ProductPageLoadedEvent::class => 'addBundleDataToProductPage'
  33.         ];
  34.     }
  35.     public function addBundleDataToProductPage(ProductPageLoadedEvent $event): void
  36.     {
  37.         $salesChannelContext $event->getSalesChannelContext();
  38.         /** @var ProductBundlesStruct $struct */
  39.         $struct = new ProductBundlesStruct();
  40.         $product $event->getPage()->getProduct();
  41.         if (!$product) {
  42.             return;
  43.         }
  44.         $struct->setBundleChildren($this->getBundleChildren($product->getId(), $salesChannelContext));
  45.         $struct->setBundleParents($this->setBundleParents($product->getId(), $salesChannelContext));
  46.         $event->getPage()->addExtension('wbfkBundlesData'$struct);
  47.     }
  48.     public function getBundleChildren(string $productIdSalesChannelContext $salesChannelContext): BundleProductCollection
  49.     {
  50.         $context $salesChannelContext->getContext();
  51.         $criteria = new Criteria();
  52.         $criteria->setTitle("Getting bundle products child products data");
  53.         $criteria->addAssociation('salesChannelChildProduct');
  54.         $criteria->addAssociation('salesChannelChildProduct.cover.media');
  55.         $criteria->addSorting(new FieldSorting('salesChannelChildProduct.price.first.gross''DESC'));
  56.         $criteria->addFilter(new EqualsFilter('productId'$productId));
  57.         $criteria->addFilter(new EqualsFilter('childProduct.active'true));
  58.         /** @var BundleProductCollection $bundleChildren */
  59.         $bundleChildren $this->bundleProductRepository->search($criteria$context)->getEntities();
  60.         $products = new SalesChannelProductCollection([]);
  61.         /** @var BundleProductEntity $bundleChild */
  62.         foreach ($bundleChildren as $bundleChild) {
  63.             $products->add($bundleChild->getSalesChannelChildProduct());
  64.         }
  65.         $this->calculator->calculate($products$salesChannelContext);
  66.         $this->eventDispatcher->dispatch(new SalesChannelEntityLoadedEvent(
  67.             $this->salesChannelProductDefinition,
  68.             $products->getElements(),
  69.             $salesChannelContext
  70.         ), 'sales_channel.product.loaded');
  71.         return $bundleChildren;
  72.     }
  73.     public function setBundleParents(string $productIdSalesChannelContext $salesChannelContext): BundleProductCollection
  74.     {
  75.         $context $salesChannelContext->getContext();
  76.         $criteria = new Criteria();
  77.         $criteria->setTitle("Getting bundle products parent products data");
  78.         $criteria->addAssociation('salesChannelProduct');
  79.         $criteria->addAssociation('salesChannelChildProduct');
  80.         $criteria->addSorting(new FieldSorting('salesChannelProduct.price.first.gross''ASC'));
  81.         $criteria->addFilter(new EqualsFilter('childProduct.id'$productId));
  82.         $criteria->addFilter(new EqualsFilter('product.active'true));
  83.         /** @var BundleProductCollection $bundleParents */
  84.         $bundleParents $this->bundleProductRepository->search($criteria$context)->getEntities();
  85.         /** @var BundleProductEntity $bundleParent */
  86.         foreach ($bundleParents as $bundleParent) {
  87.             $bundleParent->setChildBundleProducts($this->getBundleChildren($bundleParent->getProductId(), $salesChannelContext));
  88.         }
  89.         $products = new ProductCollection([]);
  90.         /** @var BundleProductEntity $bundleParent */
  91.         foreach ($bundleParents as $bundleParent) {
  92.             $products->add($bundleParent->getSalesChannelProduct());
  93.         }
  94.         $this->calculator->calculate($products$salesChannelContext);
  95.         return $bundleParents;
  96.     }
  97. }