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

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