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

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Storefront\Controller;
  3. use Shopware\Core\Content\Category\SalesChannel\AbstractCategoryRoute;
  4. use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
  5. use Shopware\Core\Content\Cms\SalesChannel\AbstractCmsRoute;
  6. use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
  7. use Shopware\Core\Content\Product\SalesChannel\Listing\AbstractProductListingRoute;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  10. use Shopware\Core\Framework\Routing\Annotation\Since;
  11. use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
  12. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  13. use Shopware\Storefront\Event\SwitchBuyBoxVariantEvent;
  14. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  15. use Shopware\Storefront\Page\Cms\CmsPageLoadedHook;
  16. use Shopware\Storefront\Page\Product\Configurator\ProductCombinationFinder;
  17. use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;
  18. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  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.  * @Route(defaults={"_routeScope"={"storefront"}})
  26.  *
  27.  * @deprecated tag:v6.5.0 - reason:becomes-internal - Will be internal
  28.  */
  29. class CmsController extends StorefrontController
  30. {
  31.     /**
  32.      * @var AbstractCmsRoute
  33.      */
  34.     private $cmsRoute;
  35.     /**
  36.      * @var AbstractCategoryRoute
  37.      */
  38.     private $categoryRoute;
  39.     /**
  40.      * @var AbstractProductListingRoute
  41.      */
  42.     private $listingRoute;
  43.     /**
  44.      * @var AbstractProductDetailRoute
  45.      */
  46.     private $productRoute;
  47.     /**
  48.      * @var ProductReviewLoader
  49.      */
  50.     private $productReviewLoader;
  51.     /**
  52.      * @var ProductCombinationFinder
  53.      */
  54.     private $combinationFinder;
  55.     private EventDispatcherInterface $eventDispatcher;
  56.     /**
  57.      * @internal
  58.      */
  59.     public function __construct(
  60.         AbstractCmsRoute $cmsRoute,
  61.         AbstractCategoryRoute $categoryRoute,
  62.         AbstractProductListingRoute $listingRoute,
  63.         AbstractProductDetailRoute $productRoute,
  64.         ProductReviewLoader $productReviewLoader,
  65.         ProductCombinationFinder $combinationFinder,
  66.         EventDispatcherInterface $eventDispatcher
  67.     ) {
  68.         $this->cmsRoute = $cmsRoute;
  69.         $this->categoryRoute = $categoryRoute;
  70.         $this->listingRoute = $listingRoute;
  71.         $this->productRoute = $productRoute;
  72.         $this->productReviewLoader = $productReviewLoader;
  73.         $this->combinationFinder = $combinationFinder;
  74.         $this->eventDispatcher = $eventDispatcher;
  75.     }
  76.     /**
  77.      * @Since("6.0.0.0")
  78.      * Route for cms data (used in XmlHttpRequest)
  79.      *
  80.      * @HttpCache()
  81.      * @Route("/widgets/cms/{id}", name="frontend.cms.page", methods={"GET", "POST"}, defaults={"id"=null, "XmlHttpRequest"=true})
  82.      */
  83.     public function page(?string $id, Request $request, SalesChannelContext $salesChannelContext): Response
  84.     {
  85.         if (!$id) {
  86.             throw new MissingRequestParameterException('Parameter id missing');
  87.         }
  88.         $page = $this->cmsRoute->load($id, $request, $salesChannelContext)->getCmsPage();
  89.         $this->hook(new CmsPageLoadedHook($page, $salesChannelContext));
  90.         $response = $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $page]);
  91.         $response->headers->set('x-robots-tag', 'noindex');
  92.         return $response;
  93.     }
  94.     /**
  95.      * @Since("6.0.0.0")
  96.      * Route to load a cms page which assigned to the provided navigation id.
  97.      * Navigation id is required to load the slot config for the navigation
  98.      *
  99.      * @Route("/widgets/cms/navigation/{navigationId}", name="frontend.cms.navigation.page", methods={"GET", "POST"}, defaults={"navigationId"=null, "XmlHttpRequest"=true})
  100.      */
  101.     public function category(?string $navigationId, Request $request, SalesChannelContext $salesChannelContext): Response
  102.     {
  103.         if (!$navigationId) {
  104.             throw new MissingRequestParameterException('Parameter navigationId missing');
  105.         }
  106.         $category = $this->categoryRoute->load($navigationId, $request, $salesChannelContext)->getCategory();
  107.         $page = $category->getCmsPage();
  108.         if (!$page) {
  109.             throw new PageNotFoundException('');
  110.         }
  111.         $this->hook(new CmsPageLoadedHook($page, $salesChannelContext));
  112.         $response = $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $page]);
  113.         $response->headers->set('x-robots-tag', 'noindex');
  114.         return $response;
  115.     }
  116.     /**
  117.      * @Since("6.0.0.0")
  118.      * @HttpCache()
  119.      *
  120.      * Route to load the listing filters
  121.      *
  122.      * @Route("/widgets/cms/navigation/{navigationId}/filter", name="frontend.cms.navigation.filter", methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true, "_routeScope"={"storefront"}})
  123.      */
  124.     public function filter(string $navigationId, Request $request, SalesChannelContext $context): Response
  125.     {
  126.         if (!$navigationId) {
  127.             throw new MissingRequestParameterException('Parameter navigationId missing');
  128.         }
  129.         // Allows to fetch only aggregations over the gateway.
  130.         $request->request->set('only-aggregations', true);
  131.         // 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.
  132.         $request->request->set('reduce-aggregations', true);
  133.         $listing = $this->listingRoute
  134.             ->load($navigationId, $request, $context, new Criteria())
  135.             ->getResult();
  136.         $mapped = [];
  137.         foreach ($listing->getAggregations() as $aggregation) {
  138.             $mapped[$aggregation->getName()] = $aggregation;
  139.         }
  140.         $response = new JsonResponse($mapped);
  141.         $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, '1');
  142.         $response->headers->set('x-robots-tag', 'noindex');
  143.         return $response;
  144.     }
  145.     /**
  146.      * @Since("6.4.0.0")
  147.      * @HttpCache()
  148.      *
  149.      * Route to load the cms element buy box product config which assigned to the provided product id.
  150.      * Product id is required to load the slot config for the buy box
  151.      *
  152.      * @Route("/widgets/cms/buybox/{productId}/switch", name="frontend.cms.buybox.switch", methods={"GET"}, defaults={"productId"=null, "XmlHttpRequest"=true, "_routeScope"={"storefront"}})
  153.      */
  154.     public function switchBuyBoxVariant(string $productId, Request $request, SalesChannelContext $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 = (string) $request->query->get('options');
  164.         /** @var array $newOptions */
  165.         $newOptions = \strlen($options) ? json_decode($options, true) : [];
  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.         $event = new SwitchBuyBoxVariantEvent($elementId, $product, $configurator, $request, $context);
  176.         $this->eventDispatcher->dispatch($event);
  177.         $response = $this->renderStorefront('@Storefront/storefront/component/buy-widget/buy-widget.html.twig', [
  178.             'product' => $product,
  179.             'configuratorSettings' => $configurator,
  180.             'totalReviews' => $reviews->getTotalReviews(),
  181.             'elementId' => $elementId,
  182.         ]);
  183.         $response->headers->set('x-robots-tag', 'noindex');
  184.         return $response;
  185.     }
  186. }