<?php declare(strict_types=1);
namespace SemesManufacturerPlus\Storefront\Controller;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\PlatformRequest;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Page\GenericPageLoader;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
use Shopware\Core\Content\Product\Aggregate\ProductManufacturer\ProductManufacturerDefinition;
use Shopware\Core\Framework\Context;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use SemesManufacturerPlus\Service\ConfigService;
use SemesManufacturerPlus\Service\UrlService;
use SemesManufacturerPlus\Service\CmsPageService;
use SemesManufacturerPlus\Service\ManufacturerService;
use SemesManufacturerPlus\Storefront\ManufacturerPlusPage;
use Shopware\Core\Content\Cms\SalesChannel\AbstractCmsRoute;
use Shopware\Storefront\Page\Cms\CmsPageLoadedHook;
use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
// old Annotation
// * @RouteScope(scopes={"storefront"})
// new Annotation
// * @Route(defaults={"_routeScope"={"storefront"}})
/**
* @RouteScope(scopes={"storefront"})
*/
class ManufacturerPlusController extends StorefrontController
{
private $configService;
private $manufacturerService;
private $genericLoader;
private $urlService;
private $cmsPageService;
private $productManufacturerDefinition;
private $cmsRoute;
public function __construct(
ConfigService $configService,
ManufacturerService $manufacturerService,
GenericPageLoader $genericLoader,
UrlService $urlService,
CmsPageService $cmsPageService,
ProductManufacturerDefinition $productManufacturerDefinition,
AbstractCmsRoute $cmsRoute
) {
$this->configService = $configService;
$this->manufacturerService = $manufacturerService;
$this->genericLoader = $genericLoader;
$this->urlService = $urlService;
$this->cmsPageService = $cmsPageService;
$this->productManufacturerDefinition = $productManufacturerDefinition;
$this->cmsRoute = $cmsRoute;
}
/**
* @Route("/{manufacturer?}", name="frontend.semes.manufacturer.plus.detail", methods={"GET"}, priority=-255, requirements={"manufacturer"=".+"}, defaults={"XmlHttpRequest"=true, "_routeScope"={"storefront"}})
*/
public function showManufacturer(Request $request, Context $context): Response
{
$manufacturer = $this->manufacturerService->getManufacturerFromUrl($request, $context);
if(!$manufacturer) return $this->forwardToRoute('frontend.home.page');
$request->attributes->set('semesManufacturerId', $manufacturer->getId());
$request->attributes->set('semesManufacturer', $manufacturer);
$cmsPageId = $this->manufacturerService->getManufacturerCmsPageId($manufacturer);
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $salesChannelContext->getSalesChannel()->getId();
if ($this->configService->getDeactivated() || (!isset($cmsPageId) && !empty($cmsPageId))) {
return $this->forwardToRoute('frontend.home.page');
}
$page = $this->genericLoader->load($request, $salesChannelContext);
$page = ManufacturerPlusPage::createFrom($page);
$cmsPage = $this->cmsPageService->getCmsPage($cmsPageId, $context);
// resolve slot data
$resolverContext = new EntityResolverContext($salesChannelContext, $request, $this->productManufacturerDefinition, $manufacturer);
$this->cmsPageService->resolveSlotData($cmsPage, $resolverContext);
$page->setCmsPage($cmsPage);
$breadcrumbs = $this->urlService->getBreadcrumbs($manufacturer, $request, $context);
$manufacturer->getExtension('manufacturerPlus')->setCanonical($this->urlService->getCanonical($manufacturer, $request, $context));
return $this->renderStorefront('@Storefront/storefront/page/content/index.html.twig', [
'semesManufacturer' => $manufacturer,
'page' => $page,
'cmsPage' => $cmsPage,
'breadcrumbs' => $breadcrumbs
]);
}
/**
* Route to load the listing filters
*
* @Route("/widgets/manufacturer/{manufacturerId}/filter", name="frontend.semes.manufacturer.plus.filter", methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true, "_routeScope"={"storefront"}})
*/
public function filter(string $manufacturerId, Request $request, SalesChannelContext $context): Response
{
if (!$manufacturerId) {
throw new MissingRequestParameterException('Parameter navigationId missing');
}
$request->attributes->set('semesManufacturerId', $manufacturerId);
// 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->manufacturerService->getManufacturerProductsListing($manufacturerId, 0, $request, $context);
$mapped = [];
foreach ($listing->getAggregations() as $aggregation) {
$mapped[$aggregation->getName()] = $aggregation;
}
$response = new JsonResponse($mapped);
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, '1');
$response->headers->set('x-robots-tag', 'noindex');
return $response;
}
/**
* Route to load a manufacturer page which assigned to the provided navigation id.
*
* @Route("/widgets/manufacturer/{manufacturerId}/{navigationId}", name="frontend.semes.manufacturer.plus.page", methods={"GET", "POST"}, defaults={"manufacturerId"=null,"navigationId"=null, "XmlHttpRequest"=true})
*/
public function manufacturer(?string $manufacturerId, ?string $navigationId, Request $request, SalesChannelContext $salesChannelContext): Response
{
if (!$manufacturerId) {
throw new MissingRequestParameterException('Parameter manufacturerId missing');
}
$request->attributes->set('semesManufacturerId', $manufacturerId);
$manufacturer = $this->manufacturerService->getManufacturerById($manufacturerId,$salesChannelContext->getContext());
if($navigationId) {
$cmsPageId = $navigationId;
} else {
$cmsPageId = $this->manufacturerService->getManufacturerCmsPageId($manufacturer);
}
$page = $this->cmsRoute->load($cmsPageId, $request, $salesChannelContext)->getCmsPage();
// resolve slot data
$resolverContext = new EntityResolverContext($salesChannelContext, $request, $this->productManufacturerDefinition, $manufacturer);
$this->cmsPageService->resolveSlotData($page, $resolverContext);
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;
}
}