<?php
declare(strict_types=1);
namespace Sisi\Blog6\Storefront\Page\Blog\Products;
use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
use Shopware\Core\Content\Product\ProductCollection;
use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class ProductsLoader
{
/**
* @var SalesChannelRepositoryInterface
*/
private $productRepository;
/**
* @var SystemConfigService
*/
private $systemConfigService;
public function __construct(
SalesChannelRepositoryInterface $productRepository,
SystemConfigService $systemConfigService
) {
$this->productRepository = $productRepository;
$this->systemConfigService = $systemConfigService;
}
/**
* @param ProductCollection<\Shopware\Core\Content\Product\ProductEntity>|null $products
* @return ProductCollection<\Shopware\Core\Content\Product\ProductEntity>|null
*/
public function load(?ProductCollection $products, SalesChannelContext $context): ?ProductCollection
{
$productsList = new ProductCollection();
if ($products) {
$assignedProductsIds = $products->getIds();
$filter = new ProductAvailableFilter(
$context->getSalesChannel()->getId(),
ProductVisibilityDefinition::VISIBILITY_LINK
);
$criteria = new Criteria($assignedProductsIds);
$criteria->addAssociation('visibilities');
$criteria->addFilter($filter);
if (!count($assignedProductsIds)) {
return null;
}
$criteria = $this->handleAvailableStock($criteria, $context);
/**
* @var ProductCollection<\Shopware\Core\Content\Product\ProductEntity>|null $searchResult
*/
$searchResult = $this->productRepository->search($criteria, $context);
foreach ($products->getElements() as $element) {
if ($searchResult->has($element->getId())) {
$productsList->add($searchResult->get($element->getId()));
}
}
}
return $productsList;
}
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 NotFilter(
NotFilter::CONNECTION_AND,
[
new EqualsFilter('product.isCloseout', true),
new EqualsFilter('product.available', false),
]
)
);
return $criteria;
}
}