<?php declare(strict_types=1);
namespace Cbax\ModulManufacturers\Controller;
use Shopware\Core\Framework\Context;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Cbax\ModulManufacturers\Components\ManufacturersHelper;
use Cbax\ModulManufacturers\Components\ManufacturerSeo;
use Cbax\ModulManufacturers\Components\ManufacturersPage;
use Shopware\Storefront\Page\GenericPageLoader;
use Shopware\Core\PlatformRequest;
use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockEntity;
use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
/**
* @RouteScope(scopes={"storefront"})
*/
class FrontendController extends StorefrontController
{
private $helperComponent;
private $manufacturerSeo;
private $manufacturerRepository;
private $genericLoader;
private $mediaRepository;
private $systemConfigService;
public function __construct(
ManufacturersHelper $helperComponent,
ManufacturerSeo $manufacturerSeo,
EntityRepositoryInterface $manufacturerRepository,
GenericPageLoader $genericLoader,
EntityRepositoryInterface $mediaRepository,
SystemConfigService $systemConfigService
)
{
$this->helperComponent = $helperComponent;
$this->manufacturerSeo = $manufacturerSeo;
$this->manufacturerRepository = $manufacturerRepository;
$this->genericLoader = $genericLoader;
$this->mediaRepository = $mediaRepository;
$this->systemConfigService = $systemConfigService;
}
/**
* @HttpCache()
* alle Daten für die Herstellerübersicht holen und aufbereiten
* @param $request Request aktueller Request
* @param $context Context Standardcontext Object
* @return Object View mit Herstellerübersicht
* @Route("/cbax/manufacturer/index", name="frontend.cbax.manufacturer.index", options={"seo"=true}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function getManufacturers(Request $request, Context $context): Response
{
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $salesChannelContext->getSalesChannel()->getId();
$config = $this->systemConfigService->get('CbaxModulManufacturers', $salesChannelId)['config'];
if ($config['active'] !== true || empty($config['cmsPageIndex'])) {
return $this->forwardToRoute('frontend.home.page');
}
// Standard Page Object für Breadcrumb erzeugen
$newPage = $this->genericLoader->load($request, $salesChannelContext);
$page = ManufacturersPage::createFrom($newPage);
$cmsPage = $this->helperComponent->getCmsPage($config['cmsPageIndex'], $context);
$showProductCount = false;
if ($cmsPage)
{
if ($cmsPage->getSections())
{
$cmsPage->getSections()->sort(function (CmsSectionEntity $a, CmsSectionEntity $b) {
return $a->getPosition() <=> $b->getPosition();
});
$resolverContext = new ResolverContext($salesChannelContext, $request);
// sort blocks into sectionPositions
foreach ($cmsPage->getSections() as $section) {
$section->getBlocks()->sort(function (CmsBlockEntity $a, CmsBlockEntity $b) {
return $a->getPosition() <=> $b->getPosition();
});
// suche nach sidebar filter
foreach ($section->getBlocks() as $block) {
if (!empty($block) && $block->getType() === 'cbax-manufacturers-filter-button') {
$filterElement = !empty($block->getSlots()) ? $block->getSlots()->first() : null;
if (!empty($filterElement) && $filterElement->getType() === 'cbax-manufacturers-filter-button') {
$showProductCount = $showProductCount || $filterElement->getTranslated()['config']['showArticleCountInSidebar']['value'];
if ($showProductCount) break;
}
}
if (!empty($block) && $block->getType() === 'cbax-manufacturers-listing') {
$listingElement = !empty($block->getSlots()) ? $block->getSlots()->first() : null;
if (!empty($listingElement) && $listingElement->getType() === 'cbax-manufacturers-listing') {
$showProductCount = $showProductCount || $listingElement->getTranslated()['config']['showArticleCountInOverview']['value'];
if ($showProductCount) break;
}
}
}
}
// find config overwrite
//$overwrite = $config[$page->getId()] ?? $config;
// overwrite slot config
//$this->overwriteSlotConfig($page, $overwrite);
// resolve slot data
$this->helperComponent->loadSlotData($cmsPage, $resolverContext);
}
$page->setCmsPage($cmsPage);
}
// Herstellerdaten aufbereiten
$pageData = $this->helperComponent->getManufacturerByChar($showProductCount, $config, $salesChannelId, $context, true);
$cbaxModulManufacturers['data'] = $pageData['sortedData'];
// weitere allgemeine Templatedaten ermitteln, aktuell Top Hersteller
$result2 = $this->helperComponent->getTemplateData($pageData['unsortedData'], $config);
$cbaxModulManufacturers['templateData'] = $result2;
$cbaxModulManufacturers['page'] = 'index';
$link_index = $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.index', '/cbax/manufacturer/index', $context);
$breadcrumbLinkName = $this->container->get('translator')->trans('cbaxManufacturer.page.breadcrumb.allManufacturers');
$breadcrumb[] = array(
'link' => $link_index,
'name' => $breadcrumbLinkName,
'active' => true,
'translated' => array(
'name' => $breadcrumbLinkName
)
);
//Blöcke mit leeren Elementen nicht laden
$page = $this->helperComponent->filterEmptyCmsBlocksIndex($page, $cbaxModulManufacturers);
return $this->renderStorefront('@Storefront/storefront/base.html.twig', [
'cbaxModulManufacturers' => $cbaxModulManufacturers,
'page' => $page,
'breadcrumbList' => $breadcrumb
]);
}
/**
* @HttpCache()
* alle Daten für die Herstellerdetailseite holen und aufbereiten
* @param $request Request aktueller Request
* @param $context Context Standardcontext Object
* @return Object View mit Herstellerdetailseite
* @Route("/cbax/manufacturer/detail/{id?}", name="frontend.cbax.manufacturer.detail", options={"seo"=true}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
*/
public function getManufacturer(Request $request, Context $context): Response
{
$salesChannelContext = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$salesChannelId = $salesChannelContext->getSalesChannel()->getId();
$config = $this->systemConfigService->get('CbaxModulManufacturers', $salesChannelId)['config'];
$manufacturer_id = $request->get('id');
$pageNumber = $request->get('p');
// Checken, ob der Shopware Cache anfragt
if (empty($manufacturer_id)) {
$manufacturer_id = $request->get('cbaxManufacturerId');
if(empty($manufacturer_id)) {
return $this->forwardToRoute('frontend.home.page');
}
}
// einzelnen Hersteller mit Bildern und Produkten holen
$criteria = new Criteria();
$criteria->addAssociation('media');
$criteria->addFilter(new EqualsFilter('id', $manufacturer_id));
$data = $this->manufacturerRepository->search($criteria, $context)->first();
if(empty($data)) {
return $this->forwardToRoute('frontend.home.page');
}
$cmsConfigPageId = !empty($config['cmsPageDetail']) ? $config['cmsPageDetail'] : null;
$cmsAltPageId = (!empty($data) && !empty($data->getCustomFields()) && !empty($data->getCustomFields()['cbaxManufacturerAltCmsPage'])) ? $data->getCustomFields()['cbaxManufacturerAltCmsPage'] : null;
$cmsPageId = !empty($cmsAltPageId) ? $cmsAltPageId : $cmsConfigPageId;
if ($config['active'] !== true || empty($cmsPageId)) {
return $this->forwardToRoute('frontend.home.page');
}
if (!empty($data) && !empty($data->getCustomFields()) && !empty($data->getCustomFields()['cbaxManufacturerBannerMedia'])) {
$mediaCriteria = new Criteria();
$mediaCriteria->addFilter(new EqualsFilter('id', $data->getCustomFields()['cbaxManufacturerBannerMedia']));
$bannerMedia = $this->mediaRepository->search($mediaCriteria, $context)->first();
}
// Standard Page Object für Breadcrumb erzeugen
$newPage = $this->genericLoader->load($request, $salesChannelContext);
$page = ManufacturersPage::createFrom($newPage);
$cmsPage = $this->helperComponent->getCmsPage($cmsPageId, $context);
$hasSidebarFilterBlock = false;
$showProductCount = false;
if ($cmsPage)
{
if ($cmsPage->getSections())
{
$cmsPage->getSections()->sort(function (CmsSectionEntity $a, CmsSectionEntity $b) {
return $a->getPosition() <=> $b->getPosition();
});
$resolverContext = new ResolverContext($salesChannelContext, $request);
// sort blocks into sectionPositions
foreach ($cmsPage->getSections() as $section) {
$section->getBlocks()->sort(function (CmsBlockEntity $a, CmsBlockEntity $b) {
return $a->getPosition() <=> $b->getPosition();
});
// suche nach sidebar filter
foreach ($section->getBlocks() as $block) {
if (!empty($block) && $block->getType() === 'cbax-manufacturers-filter-button') {
$filterElement = !empty($block->getSlots()) ? $block->getSlots()->first() : null;
if (!empty($filterElement) && $filterElement->getType() === 'cbax-manufacturers-filter-button') {
$hasSidebarFilterBlock = true;
$showProductCount = $filterElement->getTranslated()['config']['showArticleCountInSidebar']['value'];
break;
}
}
}
}
// find config overwrite
//$overwrite = $config[$page->getId()] ?? $config;
// overwrite slot config
//$this->overwriteSlotConfig($page, $overwrite);
// resolve slot data
$this->helperComponent->loadSlotData($cmsPage, $resolverContext);
}
$page->setCmsPage($cmsPage);
}
if ($hasSidebarFilterBlock) {
// alle Hersteller für Sidebar laden
$result = $this->helperComponent->getManufacturerByChar($showProductCount, $config, $salesChannelId, $context);
$cbaxModulManufacturers['data'] = $result;
}
// Produktlistendaten ermitteln
$data2 = $this->helperComponent->getProductsListing($manufacturer_id, $pageNumber, $salesChannelContext);
if ($pageNumber > 0) {
$limit = $this->systemConfigService->get("core.listing.productsPerPage", $salesChannelId);
$limit = !empty($limit) ? (int)$limit : 20;
$offset = $limit * ($pageNumber -1);
$cbaxModulManufacturers['offset'] = $offset;
}
$cbaxModulManufacturers['manufacturer'] = $data;
if (!empty($bannerMedia) && !empty($bannerMedia->getUrl())) {
$cbaxModulManufacturers['bannerMedia'] = $bannerMedia;
}
$cbaxModulManufacturers['products'] = $data2;
$cbaxModulManufacturers['p'] = $pageNumber;
$cbaxModulManufacturers['page'] = 'detail';
$link_index = $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.index', '/cbax/manufacturer/index', $context);
$link_detail = $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.detail', '/cbax/manufacturer/detail/' . $manufacturer_id, $context);
$breadcrumbLinkName = $this->container->get('translator')->trans('cbaxManufacturer.page.breadcrumb.allManufacturers');
$breadcrumb[] = array(
'link' => $link_index,
'name' => $breadcrumbLinkName,
'translated' => array(
'name' => $breadcrumbLinkName
)
);
$breadcrumb[] = array(
'link' => $link_detail,
'name' => $cbaxModulManufacturers['manufacturer']->getName(),
'active' => true,
'translated' => array(
'name' => $cbaxModulManufacturers['manufacturer']->getTranslated()['name']
)
);
//Blöcke mit leeren Elementen nicht laden
$page = $this->helperComponent->filterEmptyCmsBlocksDetail($page, $cbaxModulManufacturers);
return $this->renderStorefront('@Storefront/storefront/base.html.twig', [
'cbaxModulManufacturers' => $cbaxModulManufacturers,
'page' => $page,
'breadcrumbList' => $breadcrumb
]);
}
}