custom/static-plugins/NdFashion/src/Overwrite/ProductListingRoute.php line 97

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Nd\Fashion\Overwrite;
  3. use OpenApi\Annotations as OA;
  4. use Shopware\Core\Content\Category\CategoryDefinition;
  5. use Shopware\Core\Content\Category\CategoryEntity;
  6. use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
  7. use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
  8. use Shopware\Core\Content\Product\SalesChannel\Listing\AbstractProductListingRoute;
  9. use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingLoader;
  10. use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingResult;
  11. use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingRouteResponse;
  12. use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
  13. use Shopware\Core\Content\ProductStream\Service\ProductStreamBuilderInterface;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  17. use Shopware\Core\Framework\Plugin\Exception\DecorationPatternException;
  18. use Shopware\Core\Framework\Routing\Annotation\Entity;
  19. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  20. use Shopware\Core\Framework\Routing\Annotation\Since;
  21. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\Routing\Annotation\Route;
  24. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  25. /**
  26.  * @Route(defaults={"_routeScope"={"store-api"}})
  27.  */
  28. class ProductListingRoute extends AbstractProductListingRoute
  29. {
  30.     /**
  31.      * @var ProductListingLoader
  32.      */
  33.     private $listingLoader;
  34.     /**
  35.      * @var EventDispatcherInterface
  36.      */
  37.     private $eventDispatcher;
  38.     /**
  39.      * @var EntityRepositoryInterface
  40.      */
  41.     private $categoryRepository;
  42.     /**
  43.      * @var ProductStreamBuilderInterface
  44.      */
  45.     private $productStreamBuilder;
  46.     /**
  47.      * @internal
  48.      */
  49.     public function __construct(
  50.         ProductListingLoader $listingLoader,
  51.         EventDispatcherInterface $eventDispatcher,
  52.         EntityRepositoryInterface $categoryRepository,
  53.         ProductStreamBuilderInterface $productStreamBuilder
  54.     ) {
  55.         $this->eventDispatcher $eventDispatcher;
  56.         $this->listingLoader $listingLoader;
  57.         $this->categoryRepository $categoryRepository;
  58.         $this->productStreamBuilder $productStreamBuilder;
  59.     }
  60.     public function getDecorated(): AbstractProductListingRoute
  61.     {
  62.         throw new DecorationPatternException(self::class);
  63.     }
  64.     /**
  65.      * @Since("6.2.0.0")
  66.      * @Entity("product")
  67.      * @OA\Post(
  68.      *      path="/product-listing/{categoryId}",
  69.      *      summary="Fetch a product listing by category",
  70.      *      description="Fetches a product listing for a specific category. It also provides filters, sortings and property aggregations, analogous to the /search endpoint.",
  71.      *      operationId="readProductListing",
  72.      *      tags={"Store API","Product"},
  73.      *      @OA\Parameter(
  74.      *          name="categoryId",
  75.      *          description="Identifier of a category.",
  76.      *          @OA\Schema(type="string"),
  77.      *          in="path",
  78.      *          required=true
  79.      *      ),
  80.      *      @OA\Response(
  81.      *          response="200",
  82.      *          description="Returns a product listing containing all products and additional fields to display a listing.",
  83.      *          @OA\JsonContent(ref="#/components/schemas/ProductListingResult")
  84.      *     )
  85.      * )
  86.      * @Route("/store-api/product-listing/{categoryId}", name="store-api.product.listing", methods={"POST"})
  87.      */
  88.     public function load(string $categoryIdRequest $requestSalesChannelContext $contextCriteria $criteria): ProductListingRouteResponse
  89.     {
  90.         $criteria->addFilter(
  91.             new ProductAvailableFilter($context->getSalesChannel()->getId(), ProductVisibilityDefinition::VISIBILITY_ALL)
  92.         );
  93.         $criteria->setTitle('product-listing-route::loading');
  94.         $categoryCriteria = new Criteria([$categoryId]);
  95.         $categoryCriteria->setTitle('product-listing-route::category-loading');
  96.         /** @var CategoryEntity $category */
  97.         $category $this->categoryRepository->search($categoryCriteria$context->getContext())->first();
  98.         if($request->get('productManufacturerId') && strlen($request->get('productManufacturerId')) > 0){
  99.             $criteria->addFilter(new EqualsFilter("manufacturerId"$request->get('productManufacturerId')));
  100.             $streamId null;
  101.         }else {
  102.             $streamId $this->extendCriteria($context$criteria$category);
  103.         }
  104.         $entities $this->listingLoader->load($criteria$context);
  105.         /** @var ProductListingResult $result */
  106.         $result ProductListingResult::createFrom($entities);
  107.         $result->addState(...$entities->getStates());
  108.         $result->addCurrentFilter('navigationId'$categoryId);
  109.         $this->eventDispatcher->dispatch(
  110.             new ProductListingResultEvent($request$result$context)
  111.         );
  112.         $result->setStreamId($streamId);
  113.         return new ProductListingRouteResponse($result);
  114.     }
  115.     private function extendCriteria(SalesChannelContext $salesChannelContextCriteria $criteriaCategoryEntity $category): ?string
  116.     {
  117.         if ($category->getProductAssignmentType() === CategoryDefinition::PRODUCT_ASSIGNMENT_TYPE_PRODUCT_STREAM && $category->getProductStreamId() !== null) {
  118.             $filters $this->productStreamBuilder->buildFilters(
  119.                 $category->getProductStreamId(),
  120.                 $salesChannelContext->getContext()
  121.             );
  122.             $criteria->addFilter(...$filters);
  123.             return $category->getProductStreamId();
  124.         }
  125.         $criteria->addFilter(
  126.             new EqualsFilter('product.categoriesRo.id'$category->getId())
  127.         );
  128.         return null;
  129.     }
  130. }