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

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