custom/plugins/WynCustomerTheme/src/Decorator/ProductControllerDecorator.php line 83

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Wyn\CustomerTheme\Decorator;
  3. use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
  4. use Shopware\Core\Content\Product\Exception\ReviewNotActiveExeption;
  5. use Shopware\Core\Content\Product\Exception\VariantNotFoundException;
  6. use Shopware\Core\Content\Product\SalesChannel\FindVariant\AbstractFindProductVariantRoute;
  7. use Shopware\Core\Content\Product\SalesChannel\Review\AbstractProductReviewSaveRoute;
  8. use Shopware\Core\Content\Seo\SeoUrlPlaceholderHandlerInterface;
  9. use Shopware\Core\Framework\Feature;
  10. use Shopware\Core\Framework\Routing\Annotation\Since;
  11. use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
  12. use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Shopware\Storefront\Controller\ProductController;
  16. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  17. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  18. use Shopware\Storefront\Page\Product\Configurator\ProductCombinationFinder;
  19. use Shopware\Storefront\Page\Product\ProductPageLoadedHook;
  20. use Shopware\Storefront\Page\Product\ProductPageLoader;
  21. use Shopware\Storefront\Page\Product\QuickView\MinimalQuickViewPageLoader;
  22. use Shopware\Storefront\Page\Product\QuickView\ProductQuickViewWidgetLoadedHook;
  23. use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;
  24. use Shopware\Storefront\Page\Product\Review\ProductReviewsWidgetLoadedHook;
  25. use Symfony\Component\HttpFoundation\JsonResponse;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  29. use Symfony\Component\Routing\Annotation\Route;
  30. class ProductControllerDecorator extends ProductController
  31. {
  32.   private ProductPageLoader $productPageLoader;
  33.   private AbstractFindProductVariantRoute $findVariantRoute;
  34.   private MinimalQuickViewPageLoader $minimalQuickViewPageLoader;
  35.   private SeoUrlPlaceholderHandlerInterface $seoUrlPlaceholderHandler;
  36.   private ProductReviewLoader $productReviewLoader;
  37.   private SystemConfigService $systemConfigService;
  38.   private AbstractProductReviewSaveRoute $productReviewSaveRoute;
  39.   /**
  40.    * @deprecated tag:v6.5.0 - will be removed
  41.    */
  42.   private ProductCombinationFinder $productCombinationFinder;
  43.   /**
  44.    * @internal
  45.    */
  46.   public function __construct(
  47.     ProductPageLoader                 $productPageLoader,
  48.     ProductCombinationFinder          $productCombinationFinder,
  49.     AbstractFindProductVariantRoute   $findVariantRoute,
  50.     MinimalQuickViewPageLoader        $minimalQuickViewPageLoader,
  51.     AbstractProductReviewSaveRoute    $productReviewSaveRoute,
  52.     SeoUrlPlaceholderHandlerInterface $seoUrlPlaceholderHandler,
  53.     ProductReviewLoader               $productReviewLoader,
  54.     SystemConfigService               $systemConfigService
  55.   )
  56.   {
  57.     $this->productPageLoader $productPageLoader;
  58.     $this->findVariantRoute $findVariantRoute;
  59.     $this->minimalQuickViewPageLoader $minimalQuickViewPageLoader;
  60.     $this->seoUrlPlaceholderHandler $seoUrlPlaceholderHandler;
  61.     $this->productReviewLoader $productReviewLoader;
  62.     $this->systemConfigService $systemConfigService;
  63.     $this->productReviewSaveRoute $productReviewSaveRoute;
  64.     $this->productCombinationFinder $productCombinationFinder;
  65.   }
  66.   /**
  67.    * @Since("6.3.3.0")
  68.    * @HttpCache()
  69.    * @Route("/detail/{productId}", name="frontend.detail.page", methods={"GET"})
  70.    */
  71.   public function index(SalesChannelContext $contextRequest $request): Response
  72.   {
  73.     $page $this->productPageLoader->load($request$context);
  74.     $this->hook(new ProductPageLoadedHook($page$context));
  75.     $ratingSuccess $request->get('success');
  76.     /**
  77.      * @deprecated tag:v6.5.0 - remove complete if statement, cms page id is always set
  78.      *
  79.      * Fallback layout for non-assigned product layout
  80.      */
  81.     if (!$page->getCmsPage()) {
  82.       Feature::throwException('v6.5.0.0''Fallback will be removed because cms page is always set in subscriber.');
  83.       return $this->renderStorefront('@Storefront/storefront/page/product-detail/index.html.twig', ['page' => $page'ratingSuccess' => $ratingSuccess]);
  84.     }
  85.     return $this->renderStorefront('@Storefront/storefront/page/content/product-detail.html.twig', ['page' => $page]);
  86.   }
  87.   /**
  88.    * @Since("6.0.0.0")
  89.    * @HttpCache()
  90.    * @Route("/detail/{productId}/switch", name="frontend.detail.switch", methods={"GET"}, defaults={"XmlHttpRequest": true})
  91.    */
  92.   public function switch(string $productIdRequest $requestSalesChannelContext $salesChannelContext): JsonResponse
  93.   {
  94.     $switchedGroup $request->query->has('switched') ? (string)$request->query->get('switched') : null;
  95.     /** @var array<mixed>|null $options */
  96.     $options json_decode($request->query->get('options'''), true);
  97.     try {
  98.       if (Feature::isActive('v6.5.0.0')) {
  99.         $variantResponse $this->findVariantRoute->load(
  100.           $productId,
  101.           new Request(
  102.             [
  103.               'switchedGroup' => $switchedGroup,
  104.               'options' => $options ?? [],
  105.             ]
  106.           ),
  107.           $salesChannelContext
  108.         );
  109.         $productId $variantResponse->getFoundCombination()->getVariantId();
  110.       } else {
  111.         $finderResponse $this->productCombinationFinder->find(
  112.           $productId,
  113.           $switchedGroup,
  114.           $options ?? [],
  115.           $salesChannelContext
  116.         );
  117.         $productId $finderResponse->getVariantId();
  118.       }
  119.     } catch (VariantNotFoundException|ProductNotFoundException $productNotFoundException) {
  120.       //nth
  121.     }
  122.     $host $request->attributes->get(RequestTransformer::SALES_CHANNEL_ABSOLUTE_BASE_URL)
  123.       . $request->attributes->get(RequestTransformer::SALES_CHANNEL_BASE_URL);
  124.     $url $this->seoUrlPlaceholderHandler->replace(
  125.       $this->seoUrlPlaceholderHandler->generate(
  126.         'frontend.detail.page',
  127.         ['productId' => $productId]
  128.       ),
  129.       $host,
  130.       $salesChannelContext
  131.     );
  132.     $response = new JsonResponse([
  133.       'url' => $url '#product-detail-buy-box',
  134.       'productId' => $productId,
  135.     ]);
  136.     $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER'1');
  137.     return $response;
  138.   }
  139. }