vendor/shopware/storefront/Controller/CmsController.php line 57
<?php declare(strict_types=1);namespace Shopware\Storefront\Controller;use Shopware\Core\Content\Category\SalesChannel\AbstractCategoryRoute;use Shopware\Core\Content\Cms\Exception\PageNotFoundException;use Shopware\Core\Content\Cms\SalesChannel\AbstractCmsRoute;use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;use Shopware\Core\Content\Product\SalesChannel\FindVariant\AbstractFindProductVariantRoute;use Shopware\Core\Content\Product\SalesChannel\Listing\AbstractProductListingRoute;use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;use Shopware\Core\Framework\Log\Package;use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;use Shopware\Core\System\SalesChannel\SalesChannelContext;use Shopware\Storefront\Event\SwitchBuyBoxVariantEvent;use Shopware\Storefront\Page\Cms\CmsPageLoadedHook;use Shopware\Storefront\Page\Product\Review\ProductReviewLoader;use Symfony\Component\EventDispatcher\EventDispatcherInterface;use Symfony\Component\HttpFoundation\JsonResponse;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Annotation\Route;/*** @internal* Do not use direct or indirect repository calls in a controller. Always use a store-api route to get or put data*/#[Route(defaults: ['_routeScope' => ['storefront']])]#[Package('content')]class CmsController extends StorefrontController{/*** @internal*/public function __construct(private readonly AbstractCmsRoute $cmsRoute,private readonly AbstractCategoryRoute $categoryRoute,private readonly AbstractProductListingRoute $listingRoute,private readonly AbstractProductDetailRoute $productRoute,private readonly ProductReviewLoader $productReviewLoader,private readonly AbstractFindProductVariantRoute $findVariantRoute,private readonly EventDispatcherInterface $eventDispatcher) {}#[Route(path: '/widgets/cms/{id}', name: 'frontend.cms.page', defaults: ['id' => null, 'XmlHttpRequest' => true, '_httpCache' => true], methods: ['GET', 'POST'])]public function page(?string $id, Request $request, SalesChannelContext $salesChannelContext): Response{if (!$id) {throw new MissingRequestParameterException('id');}$page = $this->cmsRoute->load($id, $request, $salesChannelContext)->getCmsPage();$this->hook(new CmsPageLoadedHook($page, $salesChannelContext));$response = $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $page]);$response->headers->set('x-robots-tag', 'noindex');return $response;}/*** Navigation id is required to load the slot config for the navigation*/#[Route(path: '/widgets/cms/navigation/{navigationId}', name: 'frontend.cms.navigation.page', defaults: ['navigationId' => null, 'XmlHttpRequest' => true], methods: ['GET', 'POST'])]public function category(?string $navigationId, Request $request, SalesChannelContext $salesChannelContext): Response{if (!$navigationId) {throw new MissingRequestParameterException('navigationId');}$category = $this->categoryRoute->load($navigationId, $request, $salesChannelContext)->getCategory();$page = $category->getCmsPage();if (!$page) {throw new PageNotFoundException('');}$this->hook(new CmsPageLoadedHook($page, $salesChannelContext));$response = $this->renderStorefront('@Storefront/storefront/page/content/detail.html.twig', ['cmsPage' => $page]);$response->headers->set('x-robots-tag', 'noindex');return $response;}/*** Route to load the listing filters*/#[Route(path: '/widgets/cms/navigation/{navigationId}/filter', name: 'frontend.cms.navigation.filter', defaults: ['XmlHttpRequest' => true, '_routeScope' => ['storefront'], '_httpCache' => true], methods: ['GET', 'POST'])]public function filter(string $navigationId, Request $request, SalesChannelContext $context): Response{// Allows to fetch only aggregations over the gateway.$request->request->set('only-aggregations', true);// 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.$request->request->set('reduce-aggregations', true);$listing = $this->listingRoute->load($navigationId, $request, $context, new Criteria())->getResult();$mapped = [];foreach ($listing->getAggregations() as $aggregation) {$mapped[$aggregation->getName()] = $aggregation;}$response = new JsonResponse($mapped);$response->headers->set('x-robots-tag', 'noindex');return $response;}/*** Route to load the cms element buy box product config which assigned to the provided product id.* Product id is required to load the slot config for the buy box*/#[Route(path: '/widgets/cms/buybox/{productId}/switch', name: 'frontend.cms.buybox.switch', defaults: ['productId' => null, 'XmlHttpRequest' => true, '_routeScope' => ['storefront'], '_httpCache' => true], methods: ['GET'])]public function switchBuyBoxVariant(string $productId, Request $request, SalesChannelContext $context): Response{/** @var string $elementId */$elementId = $request->query->get('elementId');/** @var string[]|null $options */$options = json_decode($request->query->get('options', ''), true);$variantResponse = $this->findVariantRoute->load($productId,new Request(['switchedGroup' => $request->query->get('switched'),'options' => $options ?? [],]),$context);$newProductId = $variantResponse->getFoundCombination()->getVariantId();$result = $this->productRoute->load($newProductId, $request, $context, new Criteria());$product = $result->getProduct();$configurator = $result->getConfigurator();$request->request->set('parentId', $product->getParentId());$request->request->set('productId', $product->getId());$reviews = $this->productReviewLoader->load($request, $context);$reviews->setParentId($product->getParentId() ?? $product->getId());$event = new SwitchBuyBoxVariantEvent($elementId, $product, $configurator, $request, $context);$this->eventDispatcher->dispatch($event);$response = $this->renderStorefront('@Storefront/storefront/component/buy-widget/buy-widget.html.twig', ['product' => $product,'configuratorSettings' => $configurator,'totalReviews' => $reviews->getTotalReviews(),'elementId' => $elementId,]);$response->headers->set('x-robots-tag', 'noindex');return $response;}}