vendor/shopware/storefront/Controller/CmsController.php line 97

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Controller;
  3. use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
  4. use Shopware\Core\Content\Category\SalesChannel\AbstractCategoryRoute;
  5. use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
  6. use Shopware\Core\Content\Cms\SalesChannel\AbstractCmsRoute;
  7. use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
  8. use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
  9. use Shopware\Core\Content\Product\SalesChannel\Listing\AbstractProductListingRoute;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  13. use Shopware\Core\Framework\Routing\Annotation\Since;
  14. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  15. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  16. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  17. use Shopware\Storefront\Page\Product\Configurator\ProductCombinationFinder;
  18. use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;
  19. use Symfony\Component\HttpFoundation\JsonResponse;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  23. use Symfony\Component\Routing\Annotation\Route;
  24. /**
  25.  * @RouteScope(scopes={"storefront"})
  26.  */
  27. class CmsController extends StorefrontController
  28. {
  29.     /**
  30.      * @var AbstractCmsRoute
  31.      */
  32.     private $cmsRoute;
  33.     /**
  34.      * @var AbstractCategoryRoute
  35.      */
  36.     private $categoryRoute;
  37.     /**
  38.      * @var AbstractProductListingRoute
  39.      */
  40.     private $listingRoute;
  41.     /**
  42.      * @var AbstractProductDetailRoute
  43.      */
  44.     private $productRoute;
  45.     /**
  46.      * @var ProductReviewLoader
  47.      */
  48.     private $productReviewLoader;
  49.     /**
  50.      * @var ProductCombinationFinder
  51.      */
  52.     private $combinationFinder;
  53.     public function __construct(
  54.         AbstractCmsRoute $cmsRoute,
  55.         AbstractCategoryRoute $categoryRoute,
  56.         AbstractProductListingRoute $listingRoute,
  57.         AbstractProductDetailRoute $productRoute,
  58.         ProductReviewLoader $productReviewLoader,
  59.         ProductCombinationFinder $combinationFinder
  60.     ) {
  61.         $this->cmsRoute $cmsRoute;
  62.         $this->categoryRoute $categoryRoute;
  63.         $this->listingRoute $listingRoute;
  64.         $this->productRoute $productRoute;
  65.         $this->productReviewLoader $productReviewLoader;
  66.         $this->combinationFinder $combinationFinder;
  67.     }
  68.     /**
  69.      * @Since("6.0.0.0")
  70.      * Route for cms data (used in XmlHttpRequest)
  71.      *
  72.      * @HttpCache()
  73.      * @Route("/widgets/cms/{id}", name="frontend.cms.page", methods={"GET", "POST"}, defaults={"id"=null, "XmlHttpRequest"=true})
  74.      *
  75.      * @throws InconsistentCriteriaIdsException
  76.      * @throws MissingRequestParameterException
  77.      * @throws PageNotFoundException
  78.      */
  79.     public function page(?string $idRequest $requestSalesChannelContext $salesChannelContext): Response
  80.     {
  81.         if (!$id) {
  82.             throw new MissingRequestParameterException('Parameter id missing');
  83.         }
  84.         $cmsPage $this->cmsRoute->load($id$request$salesChannelContext)->getCmsPage();
  85.         return $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $cmsPage]);
  86.     }
  87.     /**
  88.      * @Since("6.0.0.0")
  89.      * Route to load a cms page which assigned to the provided navigation id.
  90.      * Navigation id is required to load the slot config for the navigation
  91.      *
  92.      * @Route("/widgets/cms/navigation/{navigationId}", name="frontend.cms.navigation.page", methods={"GET", "POST"}, defaults={"navigationId"=null, "XmlHttpRequest"=true})
  93.      *
  94.      * @throws CategoryNotFoundException
  95.      * @throws MissingRequestParameterException
  96.      * @throws PageNotFoundException
  97.      * @throws InconsistentCriteriaIdsException
  98.      */
  99.     public function category(?string $navigationIdRequest $requestSalesChannelContext $salesChannelContext): Response
  100.     {
  101.         if (!$navigationId) {
  102.             throw new MissingRequestParameterException('Parameter navigationId missing');
  103.         }
  104.         $category $this->categoryRoute->load($navigationId$request$salesChannelContext)->getCategory();
  105.         if (!$category->getCmsPage()) {
  106.             throw new PageNotFoundException('');
  107.         }
  108.         return $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $category->getCmsPage()]);
  109.     }
  110.     /**
  111.      * @Since("6.0.0.0")
  112.      * @HttpCache()
  113.      *
  114.      * Route to load the listing filters
  115.      *
  116.      * @RouteScope(scopes={"storefront"})
  117.      * @Route("/widgets/cms/navigation/{navigationId}/filter", name="frontend.cms.navigation.filter", methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true})
  118.      *
  119.      * @throws MissingRequestParameterException
  120.      */
  121.     public function filter(string $navigationIdRequest $requestSalesChannelContext $context): Response
  122.     {
  123.         if (!$navigationId) {
  124.             throw new MissingRequestParameterException('Parameter navigationId missing');
  125.         }
  126.         // Allows to fetch only aggregations over the gateway.
  127.         $request->request->set('only-aggregations'true);
  128.         // Allows to convert all post-filters to filters. This leads to the fact that only aggregation values are returned, which are combinable with the previous applied filters.
  129.         $request->request->set('reduce-aggregations'true);
  130.         $listing $this->listingRoute
  131.             ->load($navigationId$request$context, new Criteria())
  132.             ->getResult();
  133.         $mapped = [];
  134.         foreach ($listing->getAggregations() as $aggregation) {
  135.             $mapped[$aggregation->getName()] = $aggregation;
  136.         }
  137.         $response = new JsonResponse($mapped);
  138.         $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER'1');
  139.         return $response;
  140.     }
  141.     /**
  142.      * @Since("6.4.0.0")
  143.      * @HttpCache()
  144.      *
  145.      * Route to load the cms element buy box product config which assigned to the provided product id.
  146.      * Product id is required to load the slot config for the buy box
  147.      *
  148.      * @RouteScope(scopes={"storefront"})
  149.      * @Route("/widgets/cms/buybox/{productId}/switch", name="frontend.cms.buybox.switch", methods={"GET"}, defaults={"productId"=null, "XmlHttpRequest"=true})
  150.      *
  151.      * @throws MissingRequestParameterException
  152.      * @throws ProductNotFoundException
  153.      */
  154.     public function switchBuyBoxVariant(string $productIdRequest $requestSalesChannelContext $context): Response
  155.     {
  156.         if (!$productId) {
  157.             throw new MissingRequestParameterException('Parameter productId missing');
  158.         }
  159.         /** @var string $switchedOption */
  160.         $switchedOption $request->query->get('switched');
  161.         /** @var string $elementId */
  162.         $elementId $request->query->get('elementId');
  163.         $options $request->query->get('options');
  164.         /** @var array $newOptions */
  165.         $newOptions $options !== null json_decode($optionstrue) : [];
  166.         $redirect $this->combinationFinder->find($productId$switchedOption$newOptions$context);
  167.         $newProductId $redirect->getVariantId();
  168.         $result $this->productRoute->load($newProductId$request$context, new Criteria());
  169.         $product $result->getProduct();
  170.         $configurator $result->getConfigurator();
  171.         $request->request->set('parentId'$product->getParentId());
  172.         $request->request->set('productId'$product->getId());
  173.         $reviews $this->productReviewLoader->load($request$context);
  174.         $reviews->setParentId($product->getParentId() ?? $product->getId());
  175.         return $this->renderStorefront('@Storefront/storefront/component/buy-widget/buy-widget.html.twig', [
  176.             'product' => $product,
  177.             'configuratorSettings' => $configurator,
  178.             'totalReviews' => $reviews->getTotalReviews(),
  179.             'elementId' => $elementId,
  180.         ]);
  181.     }
  182. }