custom/plugins/MegaParentProductListing/src/Components/Product/SalesChannel/Listing/ProductDetailRouteDecorator.php line 65

Open in your IDE?
  1. <?php
  2. namespace MegaParentProductListing\Components\Product\SalesChannel\Listing;
  3. use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
  4. use Shopware\Core\Content\Product\SalesChannel\Detail\ProductDetailRouteResponse;
  5. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  9. use Shopware\Core\Framework\Routing\Annotation\Entity;
  10. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  11. use Shopware\Core\Framework\Routing\Annotation\Since;
  12. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. /**
  17.  * @RouteScope(scopes={"store-api"})
  18.  */
  19. class ProductDetailRouteDecorator extends AbstractProductDetailRoute
  20. {
  21.     private AbstractProductDetailRoute $decoratedService;
  22.     private SalesChannelRepositoryInterface $productRepository;
  23.     public function __construct(
  24.         AbstractProductDetailRoute $decoratedService,
  25.         SalesChannelRepositoryInterface $productRepository
  26.     )
  27.     {
  28.         $this->decoratedService $decoratedService;
  29.         $this->productRepository $productRepository;
  30.     }
  31.     public function getDecorated(): AbstractProductDetailRoute
  32.     {
  33.         return $this->decoratedService;
  34.     }
  35.     /**
  36.      * @Since("6.3.2.0")
  37.      * @Entity("product")
  38.      * @OA\Post(
  39.      *      path="/product/{productId}",
  40.      *      summary="Fetch a single product",
  41.      *      description="This route is used to load a single product with the corresponding details. In addition to loading the data, the best variant of the product is determined when a parent id is passed.",
  42.      *      operationId="readProductDetail",
  43.      *      tags={"Store API","Product"},
  44.      *      @OA\Parameter(
  45.      *          name="productId",
  46.      *          description="Product ID",
  47.      *          @OA\Schema(type="string"),
  48.      *          in="path",
  49.      *          required=true
  50.      *      ),
  51.      *      @OA\Response(
  52.      *          response="200",
  53.      *          description="Product information along with variant groups and options",
  54.      *          @OA\JsonContent(ref="#/components/schemas/ProductDetailResponse")
  55.      *     )
  56.      * )
  57.      * @Route("/store-api/product/{productId}", name="store-api.product.detail", methods={"POST"})
  58.      */
  59.     public function load(string $productIdRequest $requestSalesChannelContext $contextCriteria $criteria): ProductDetailRouteResponse
  60.     {
  61.         $productId $this->findBestVariant($productId$context);
  62.         return $this->decoratedService->load($productId$request$context$criteria);
  63.     }
  64.     private function findBestVariant(string $productIdSalesChannelContext $context): string
  65.     {
  66.         /** @var SalesChannelProductEntity $product */
  67.         $product $this->productRepository->search(new Criteria([$productId]), $context)->first();
  68.         if($product && empty($product->getParentId()) && !empty($product->getMainVariantId())) {
  69.             return $product->getMainVariantId();
  70.         }
  71.         $criteria = (new Criteria())
  72.             ->addFilter(new EqualsFilter('parentId'$productId))
  73.             ->addSorting(new FieldSorting('available'))
  74.             ->addSorting(new FieldSorting('price'))
  75.             ->addSorting(new FieldSorting('id'))
  76.             ->setLimit(1);
  77.         $variantId $this->productRepository->searchIds($criteria$context);
  78.         return $variantId->firstId() ?? $productId;
  79.     }
  80. }