<?php
namespace Twigel\SportPlugin\Subscriber;
use Shopware\Core\Checkout\Promotion\PromotionEntity;
use Shopware\Core\Content\ProductStream\ProductStreamEntity;
use Shopware\Core\Content\ProductStream\Service\ProductStreamBuilderInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductPageSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $productStreamRepository;
/**
* @var SalesChannelRepositoryInterface
*/
private SalesChannelRepositoryInterface $productRepository;
/**
* @var ProductStreamBuilderInterface
*/
private ProductStreamBuilderInterface $productStreamBuilder;
/**
* @var SystemConfigService
*/
private SystemConfigService $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $promotionRepository;
/**
* @var SalesChannelRepositoryInterface
*/
private SalesChannelRepositoryInterface $categoryRepository;
/**
* @var EntityRepositoryInterface $manufacturerRepository ;
*/
private EntityRepositoryInterface $manufacturerRepository;
/**
* @var EntityRepositoryInterface $mediaRepository ;
*/
private EntityRepositoryInterface $mediaRepository;
/**
* @param EntityRepositoryInterface $productStreamRepository
* @param SalesChannelRepositoryInterface $productRepository
* @param ProductStreamBuilderInterface $productStreamBuilder
* @param SystemConfigService $systemConfigService
* @param EntityRepositoryInterface $promotionRepository
* @param SalesChannelRepositoryInterface $categoryRepository
*/
public function __construct(
EntityRepositoryInterface $productStreamRepository,
SalesChannelRepositoryInterface $productRepository,
ProductStreamBuilderInterface $productStreamBuilder,
SystemConfigService $systemConfigService,
EntityRepositoryInterface $promotionRepository,
SalesChannelRepositoryInterface $categoryRepository,
EntityRepositoryInterface $manufacturerRepository,
EntityRepositoryInterface $mediaRepository
)
{
$this->productStreamRepository = $productStreamRepository;
$this->productRepository = $productRepository;
$this->productStreamBuilder = $productStreamBuilder;
$this->systemConfigService = $systemConfigService;
$this->promotionRepository = $promotionRepository;
$this->categoryRepository = $categoryRepository;
$this->manufacturerRepository = $manufacturerRepository;
$this->mediaRepository = $mediaRepository;
}
public static function getSubscribedEvents()
{
return [
ProductPageLoadedEvent::class => 'onLoad'
];
}
public function onLoad(ProductPageLoadedEvent $event)
{
$pluginConfig = $this->systemConfigService->get('TwigelSportPlugin.config');
if (array_key_exists("twigel_product_instruction_pdf", $event->getPage()->getProduct()->getCustomFields())) {
$documentId = $event->getPage()->getProduct()->getCustomFields()['twigel_product_instruction_pdf'];
$criteria = new Criteria([$documentId]);
$document = $this->mediaRepository->search($criteria, $event->getContext())->first();
if ($document) {
$event->getPage()->assign(["pdf" => $document]);
}
}
if ($event->getPage()->getCrossSellings()) {
$crossSellings = $event->getPage()->getCrossSellings()->getElements();
if (!empty($crossSellings)) {
$crossSellings = $event->getPage()->getCrossSellings()->getElements()[0];
$products = $crossSellings->getProducts();
foreach ($products as $product) {
$manufacturerId = $product->getManufacturerId();
$criteria = new Criteria([$manufacturerId]);
$manufacturer = $this->manufacturerRepository->search($criteria, $event->getContext())->first();
$product->setManufacturer($manufacturer);
}
}
}
if (array_key_exists('setCategory', $pluginConfig) && $pluginConfig['setCategory']) {
$setCategory = $pluginConfig['setCategory'];
if (in_array($setCategory, $event->getPage()->getProduct()->getCategoryTree())) {
$productCustomFields = $event->getPage()->getProduct()->getCustomFields();
if (array_key_exists('productSet', $event->getPage()->getProduct()->getCustomFields())) {
$productSet = $productCustomFields['productSet'];
$productsSet = $this->productRepository->search((new Criteria($productSet))->addAssociation('media'), $event->getSalesChannelContext())->getEntities();
if (!empty($productSet)) {
$event->getPage()->assign(['productSet' => $productsSet]);
}
}
}
}
if (array_key_exists('bundleCategory', $pluginConfig) && array_key_exists('bundelEnable', $pluginConfig) && $pluginConfig['bundelEnable']) {
$productDetailBundle = [
'enable' => $pluginConfig['bundelEnable'],
'groups' => [],
'promotion' => ''
];
$productGroupKeys = [
'productGroupFirst',
'productGroupSecond',
'productGroupThird'
];
foreach ($productGroupKeys as $productGroupKey) {
$category = null;
if (!empty($pluginConfig[$productGroupKey])) {
$filters = $this->productStreamBuilder->buildFilters(
$pluginConfig[$productGroupKey],
$event->getContext()
);
$criteria = (new Criteria())
->addFilter(...$filters);
$criteria->addFilter(new EqualsFilter('parentId', null));
$criteria->addAssociations(['children', 'children.options', 'categories']);
$products = $this->productRepository->search($criteria, $event->getSalesChannelContext())->getEntities();
$criteria = new Criteria([$pluginConfig[$productGroupKey]]);
/** @var ProductStreamEntity $productStream */
$productStream = $this->productStreamRepository->search($criteria, $event->getContext())->first();
foreach ($products as $newProduct) {
foreach ($newProduct->getCategoryIds() as $value) {
$category[] = $value;
}
}
if ($category) {
$category = array_unique($category);
if (!empty($category)) {
$salesChannellCategory = $this->categoryRepository->search(new Criteria($category), $event->getSalesChannelContext())->getEntities();
$productStream->addExtension('category', $salesChannellCategory);
}
}
$productStream->addExtension('products', $products);
$productDetailBundle['groups'][] = $productStream;
}
if (!empty($pluginConfig['bundlePromotion'])) {
$criteria = new Criteria([$pluginConfig['bundlePromotion']]);
$criteria->addAssociation('discounts');
/** @var PromotionEntity $promotion */
$promotion = $this->promotionRepository->search($criteria, $event->getContext())->first();
$promotion->addExtension('discount', $promotion->getDiscounts()->first());
$productDetailBundle['promotion'] = $promotion;
}
}
$event->getPage()->assign(['productDetailBundle' => $productDetailBundle]);
}
}
}