<?php declare(strict_types=1);
namespace CustomFieldAdd\Subscriber;
use Doctrine\DBAL\Connection;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerGroup\CustomerGroupEntity;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Context;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Checkout\Cart\Event\AfterLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItemFactoryRegistry;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Content\ProductStream\Service\ProductStreamBuilderInterface;
use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingLoader;
use Shopware\Core\Content\Product\SalesChannel\ProductCloseoutFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
class Category implements EventSubscriberInterface
{
private $categoryRepository;
private $systemConfigService;
private $connection;
private $productRepository;
private $requestStack;
private $factory;
public function __construct(
EntityRepositoryInterface $categoryRepository,
SystemConfigService $systemConfigService,
Connection $connection,
SalesChannelRepository $productRepository,
// EntityRepository $productRepository,
EntityRepository $productStreamRepository,
RequestStack $requestStack,
LineItemFactoryRegistry $factory,
CartService $cartService,
ProductStreamBuilderInterface $productStreamBuilder,
ProductListingLoader $listingLoader
// ProductCloseoutFilter $productCloseoutFilter
)
{
$this->categoryRepository = $categoryRepository;
$this->systemConfigService = $systemConfigService;
$this->connection = $connection;
$this->productRepository = $productRepository;
$this->productStreamRepository = $productStreamRepository;
$this->requestStack = $requestStack;
$this->factory = $factory;
$this->cartService = $cartService;
$this->productStreamBuilder = $productStreamBuilder;
$this->listingLoader = $listingLoader;
// $this->productCloseoutFilter = $productCloseoutFilter;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => "onProductPageLoadedEvent",
];
}
public function onProductPageLoadedEvent(ProductPageLoadedEvent $event)
{
$streamProductids = [];
$aProductsLoad = [];
$pArray = [];
$page = $event->getPage();
$context = $event->getContext();
if ($event->getPage()->getProduct()->getCustomFields()) {
if (isset($event->getPage()->getProduct()->getCustomFields()['product_custom_accessories_group'])) {
$sProductStrem = [];
$accessories_group = $event->getPage()->getProduct()->getCustomFields()['product_custom_accessories_group'];
foreach ($accessories_group as $streamid) {
try {
$filters = $this->productStreamBuilder->buildFilters(
$streamid,
$event->getContext()
);
$criteria = new Criteria();
$criteria->addFilter(...$filters);
$criteria = $this->handleAvailableStock($criteria, $event->getSalesChannelContext());
$searchResult = $this->listingLoader->load($criteria, $event->getSalesChannelContext());
} catch (\Exception $e) {
continue;
}
$products = $searchResult->getEntities();
$productStreamIdsFind = [];
foreach ($products->getElements() as $k => $product) {
$streamProductids[] = $product->getId();
}
$streamProducts[] = $products->getElements();
}
//~ $event->getPage()->addExtension('accessoriesProductsLoadStream', new ArrayEntity(['accessories_product_stream'=> $streamProducts]));
}
if (isset($event->getPage()->getProduct()->getCustomFields()['product_custom_accessories'])) {
$custom_accessories_product = $event->getPage()->getProduct()->getCustomFields()['product_custom_accessories'];
$aProductsLoad = $event->getPage()->getProduct()->getCustomFields()['product_custom_accessories'];
}
$stremFinal = array_unique($streamProductids);
$aProductsLoad = array_merge($aProductsLoad, $stremFinal);
$aProductsLoad = array_unique($aProductsLoad);
foreach ($aProductsLoad as $key => $val) {
$sproductId = $val;
if (in_array($val, [$event->getPage()->getProduct()->getId()])) {
continue;
}
$sCriteria = new Criteria();
$sCriteria->addFilter(new EqualsFilter('id', $val));
$sCriteria->addAssociation('cover');
$sProductDatas = $this->productRepository->search($sCriteria, $event->getSalesChannelContext())->first();
// $sProductDatas= $this->productRepository->search($sCriteria, $event->getContext())->first();
$bundleQuantity = 0;
if (empty($sProductDatas)) {
continue;
}
if (!$sProductDatas->getActive()) {
continue;
}
if ($sProductDatas->getChildCount()) {
continue;
}
if ($sProductDatas->getIsCloseout()) {
continue;
}
$pArray[] = $sProductDatas;
}
if ($pArray) {
$event->getPage()->addExtension('accessoriesProductsLoad', new ArrayEntity(['accessories_product' => $pArray]));
}
$categoryIds = $page->getProduct()->getCategoryIds();
foreach ($categoryIds as $categoryId) {
$criteria = new Criteria([$categoryId]);
$criteria->addAssociation('customFields');
$category = $this->categoryRepository->search($criteria, $event->getContext())->first();
$categoryCustomFields = $category->getCustomFields();
if (isset($categoryCustomFields['custom_spp_category_product'])) {
$page->addExtension('categoryCustomFields', new ArrayEntity($categoryCustomFields));
break;
}
}
}
}
private function handleAvailableStock(Criteria $criteria, SalesChannelContext $context): Criteria
{
$salesChannelId = $context->getSalesChannel()->getId();
$hide = $this->systemConfigService->get('core.listing.hideCloseoutProductsWhenOutOfStock', $salesChannelId);
if (!$hide) {
return $criteria;
}
$criteria->addFilter(new ProductCloseoutFilter());
return $criteria;
}
}