<?php
namespace Wabs\IgmTheme\Subscriber;
use Acris\CustomerGroupAvailableProduct\Components\DisplayAllowedProductService;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Content\Category\Event\NavigationLoadedEvent;
use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NavigationSubscriber implements EventSubscriberInterface
{
/** @var string[] */
protected $productCmsPageIds = [
'25b0681b674947948e62aad06eec6088',
'a5b1ecdd1e954364945534ec0b76af20',
'13c0e49bf179431895577ab23f07133b',
'e77093ea0970488696be0d8f0f86f858',
'bf7d1778b16f4576b92fd461025cfb8b',
];
/** @var EntityRepositoryInterface */
protected $productRepository;
/** @var DisplayAllowedProductService */
protected $displayProductService;
/** @var SystemConfigService */
protected $configService;
public function __construct(
EntityRepositoryInterface $productRepository,
DisplayAllowedProductService $displayProductService,
SystemConfigService $configService
) {
$this->productRepository = $productRepository;
$this->displayProductService = $displayProductService;
$this->configService = $configService;
}
public static function getSubscribedEvents()
{
return [
NavigationLoadedEvent::class => 'onNavigationLoaded',
];
}
public function onNavigationLoaded(NavigationLoadedEvent $event)
{
$tree = $event->getNavigation()->getTree();
foreach ($tree as $key => $item) {
$hasAvailableChildProductListings = false;
$children = $item->getChildren();
foreach ($children as $_key => $child) {
$category = $child->getCategory();
$isProductPage = in_array($category->getCmsPageId(), $this->productCmsPageIds);
if ($isProductPage && $this->hasAvailableProductListings($category, $event->getSalesChannelContext(),
$event->getContext())) {
$hasAvailableChildProductListings = true;
} else {
unset($children[$_key]);
}
}
$item->setChildren($children);
$category = $item->getCategory();
$isProductPage = in_array($category->getCmsPageId(), $this->productCmsPageIds);
if ($isProductPage && !$hasAvailableChildProductListings &&
!$this->hasAvailableProductListings($category, $event->getSalesChannelContext(),
$event->getContext())) {
unset($tree[$key]);
} else {
$tree[$key] = $item;
}
}
$event->getNavigation()->setTree($tree);
}
protected function hasAvailableProductListings(
CategoryEntity $category,
SalesChannelContext $salesChannelContext,
Context $context
) {
$criteria = new Criteria();
if ($category->getProductAssignmentType() == 'product_stream') {
$criteria->addAssociation('streams');
$criteria->addFilter(new EqualsFilter('streams.id', $category->getProductStreamId()));
} else {
$criteria->addFilter(new EqualsFilter('categories.id', $category->getId()));
}
$criteria->addFilter(new ProductAvailableFilter($salesChannelContext->getSalesChannel()->getId(),
ProductVisibilityDefinition::VISIBILITY_ALL));
$criteria->setLimit(1);
$this->addDisplayProductIdsForCriteria($criteria, $salesChannelContext);
$productsCount = $this->productRepository->search($criteria, $context)->count();
return $productsCount > 0;
}
private function addDisplayProductIdsForCriteria(Criteria $criteria, SalesChannelContext $salesChannelContext)
{
$displayProductIds = $this->displayProductService->getDisplayProductIdsForCustomerGroupId(
$salesChannelContext->getCurrentCustomerGroup()->getId(),
$salesChannelContext->getContext());
if (empty($displayProductIds) === true) {
if ($this->configService->get('AcrisCustomerGroupAvailableProductCS.config.releaseProductsIfNoCustomerGroupAssigned',
$salesChannelContext->getSalesChannel()->getId()) === DisplayAllowedProductService::DEFAULT_PLUGIN_CONFIG_RELEASE_PRODUCT_IF_NO_CUSTOMER_GROUPS_ASSIGNED) {
$criteria->addAssociation('product.customerGroup');
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
new EqualsFilter('id', Uuid::randomHex()),
new EqualsFilter('product.customerGroup.id', null),
]));
return;
}
$criteria->addFilter(new EqualsFilter('id', Uuid::randomHex()));
} else {
$criteria->addFilter(new EqualsAnyFilter('id', $displayProductIds));
}
}
}