src/Core/Content/Product/SalesChannel/Listing/ProductListingRoute.php line 49
<?php declare(strict_types=1);
namespace Shopware\Core\Content\Product\SalesChannel\Listing;
use Shopware\Core\Content\Category\CategoryDefinition;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
use Shopware\Core\Content\ProductStream\Service\ProductStreamBuilderInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Log\Package;
use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
#[Route(defaults: ['_routeScope' => ['store-api']])]
#[Package('inventory')]
class ProductListingRoute extends AbstractProductListingRoute
{
/**
* @internal
*/
public function __construct(private readonly ProductListingLoader $listingLoader, private readonly EventDispatcherInterface $eventDispatcher, private readonly EntityRepository $categoryRepository, private readonly ProductStreamBuilderInterface $productStreamBuilder)
{
}
public function getDecorated(): AbstractProductListingRoute
{
throw new DecorationPatternException(self::class);
}
#[Route(path: '/store-api/product-listing/{categoryId}', name: 'store-api.product.listing', methods: ['POST'], defaults: ['_entity' => 'product'])]
public function load(string $categoryId, Request $request, SalesChannelContext $context, Criteria $criteria): ProductListingRouteResponse
{
$criteria->addFilter(
new ProductAvailableFilter($context->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_ALL)
);
$criteria->setTitle('product-listing-route::loading');
$categoryCriteria = new Criteria([$categoryId]);
$categoryCriteria->setTitle('product-listing-route::category-loading');
/** @var CategoryEntity $category */
$category = $this->categoryRepository->search($categoryCriteria, $context->getContext())->first();
$streamId = $this->extendCriteria($context, $criteria, $category);
$entities = $this->listingLoader->load($criteria, $context);
$result = ProductListingResult::createFrom($entities);
$result->addState(...$entities->getStates());
$result->addCurrentFilter('navigationId', $categoryId);
$this->eventDispatcher->dispatch(
new ProductListingResultEvent($request, $result, $context)
);
$result->setStreamId($streamId);
return new ProductListingRouteResponse($result);
}
private function extendCriteria(SalesChannelContext $salesChannelContext, Criteria $criteria, CategoryEntity $category): ?string
{
if ($category->getProductAssignmentType() === CategoryDefinition::PRODUCT_ASSIGNMENT_TYPE_PRODUCT_STREAM && $category->getProductStreamId() !== null) {
$filters = $this->productStreamBuilder->buildFilters(
$category->getProductStreamId(),
$salesChannelContext->getContext()
);
$criteria->addFilter(...$filters);
return $category->getProductStreamId();
}
$criteria->addFilter(
new EqualsFilter('product.categoriesRo.id', $category->getId())
);
return null;
}
}