vendor/store.shopware.com/cbaxmodulmanufacturers/src/Controller/FrontendController.php line 173

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Cbax\ModulManufacturers\Controller;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Storefront\Controller\StorefrontController;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  9. use Symfony\Component\Routing\Annotation\Route;
  10. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  11. use Shopware\Core\System\SystemConfig\SystemConfigService;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Core\Content\Product\SalesChannel\Listing\AbstractProductListingRoute;
  15. use Shopware\Storefront\Framework\Routing\RequestTransformer;
  16. use Cbax\ModulManufacturers\Components\ManufacturersHelper;
  17. use Cbax\ModulManufacturers\Components\ManufacturerSeo;
  18. use Cbax\ModulManufacturers\Components\ManufacturersPage;
  19. use Shopware\Storefront\Page\GenericPageLoaderInterface;
  20. use Shopware\Core\PlatformRequest;
  21. use Shopware\Core\Content\Cms\Aggregate\CmsBlock\CmsBlockEntity;
  22. use Shopware\Core\Content\Cms\Aggregate\CmsSection\CmsSectionEntity;
  23. use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
  24. use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
  25. use Shopware\Core\Content\Cms\CmsPageEntity;
  26. use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
  27. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  28. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  29. use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
  30. use Shopware\Core\Content\Product\Aggregate\ProductManufacturer\ProductManufacturerDefinition;
  31. use Shopware\Core\Content\Product\Aggregate\ProductManufacturer\ProductManufacturerEntity;
  32. /**
  33.  * @RouteScope(scopes={"storefront"})
  34.  */
  35. class FrontendController extends StorefrontController
  36. {
  37.     private AbstractProductListingRoute $listingRoute;
  38.     private ProductManufacturerDefinition $manufacturerDefinition;
  39.     private $helperComponent;
  40.     private $manufacturerSeo;
  41.     private $manufacturerRepository;
  42.     private $genericLoader;
  43.     private $mediaRepository;
  44.     private $systemConfigService;
  45.     public function __construct(
  46.         ManufacturersHelper $helperComponent,
  47.         ManufacturerSeo $manufacturerSeo,
  48.         EntityRepositoryInterface $manufacturerRepository,
  49.         GenericPageLoaderInterface $genericLoader,
  50.         EntityRepositoryInterface $mediaRepository,
  51.         SystemConfigService $systemConfigService,
  52.         AbstractProductListingRoute $listingRoute,
  53.         ProductManufacturerDefinition $manufacturerDefinition
  54.     )
  55.     {
  56.         $this->helperComponent $helperComponent;
  57.         $this->manufacturerSeo $manufacturerSeo;
  58.         $this->manufacturerRepository $manufacturerRepository;
  59.         $this->genericLoader $genericLoader;
  60.         $this->mediaRepository $mediaRepository;
  61.         $this->systemConfigService $systemConfigService;
  62.         $this->listingRoute $listingRoute;
  63.         $this->manufacturerDefinition $manufacturerDefinition;
  64.     }
  65.     /**
  66.      * @HttpCache()
  67.      * alle Daten für die Herstellerübersicht holen und aufbereiten
  68.      * @param $request Request aktueller Request
  69.      * @param $context Context Standardcontext Object
  70.      * @return Object View mit Herstellerübersicht
  71.      * @Route("/cbax/manufacturer/index", name="frontend.cbax.manufacturer.index",  options={"seo"=true}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
  72.      */
  73.     public function getManufacturers(Request $requestContext $context): Response
  74.     {
  75.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  76.         $salesChannelId     $salesChannelContext->getSalesChannelId();
  77.         $languageId         $salesChannelContext->getSalesChannel()->getLanguageId();
  78.         $shopUrl            $request->attributes->get(RequestTransformer::STOREFRONT_URL);
  79.         $config $this->systemConfigService->get('CbaxModulManufacturers'$salesChannelId)['config'];
  80.         if ($config['active'] !== true || empty($config['cmsPageIndex'])) {
  81.             return $this->forwardToRoute('frontend.home.page');
  82.         }
  83.         // Standard Page Object für Breadcrumb erzeugen
  84.         $newPage $this->genericLoader->load($request$salesChannelContext);
  85.         $page ManufacturersPage::createFrom($newPage);
  86.         $cmsPage $this->helperComponent->getCmsPage($config['cmsPageIndex'], $context);
  87.         if ($cmsPage)
  88.         {
  89.             if ($cmsPage->getSections())
  90.             {
  91.                 $cmsPage->getSections()->sort(function (CmsSectionEntity $aCmsSectionEntity $b) {
  92.                     return $a->getPosition() <=> $b->getPosition();
  93.                 });
  94.                 $resolverContext = new ResolverContext($salesChannelContext$request);
  95.                 // sort blocks into sectionPositions
  96.                 foreach ($cmsPage->getSections() as $section) {
  97.                     $section->getBlocks()->sort(function (CmsBlockEntity $aCmsBlockEntity $b) {
  98.                         return $a->getPosition() <=> $b->getPosition();
  99.                     });
  100.                 }
  101.                 // find config overwrite
  102.                 //$overwrite = $config[$page->getId()] ?? $config;
  103.                 // overwrite slot config
  104.                 //$this->overwriteSlotConfig($page, $overwrite);
  105.                 // resolve slot data
  106.                 $this->helperComponent->loadSlotData($cmsPage$resolverContext);
  107.             }
  108.             $page->setCmsPage($cmsPage);
  109.         }
  110.         // Herstellerdaten aufbereiten
  111.         $pageData $this->helperComponent->getManufacturerByChar($config$salesChannelContext$contexttrue);
  112.         $cbaxModulManufacturers['data'] = $pageData['sortedData'];
  113.         $cbaxModulManufacturers['page'] = 'index';
  114.         $link_index $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.index''/cbax/manufacturer/index'$salesChannelId$languageId$shopUrl);
  115.         $breadcrumbLinkName $this->container->get('translator')->trans('cbaxManufacturer.page.breadcrumb.allManufacturers');
  116.         $breadcrumb[] = array(
  117.             'link' => $link_index,
  118.             'name' => $breadcrumbLinkName,
  119.             'active' => true,
  120.             'translated' => array(
  121.                 'name' => $breadcrumbLinkName
  122.             )
  123.         );
  124.         //Blöcke mit leeren Elementen nicht laden
  125.         $page $this->helperComponent->filterEmptyCmsBlocksIndex($page$cbaxModulManufacturers);
  126.         return $this->renderStorefront('@Storefront/storefront/base.html.twig', [
  127.             'cbaxModulManufacturers' => $cbaxModulManufacturers,
  128.             'page' => $page,
  129.             'breadcrumbList' => $breadcrumb
  130.         ]);
  131.     }
  132.     /**
  133.      * @HttpCache()
  134.      * alle Daten für die Herstellerdetailseite holen und aufbereiten
  135.      * @param $request Request aktueller Request
  136.      * @param $context Context Standardcontext Object
  137.      * @return Object View mit Herstellerdetailseite
  138.     * @Route("/cbax/manufacturer/detail/{cbaxManufacturerId?}", name="frontend.cbax.manufacturer.detail", options={"seo"=true}, methods={"GET"}, defaults={"XmlHttpRequest"=true})
  139.     */
  140.     public function getManufacturer(Request $requestContext $context): Response
  141.     {
  142.         $salesChannelContext $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
  143.         $salesChannelId     $salesChannelContext->getSalesChannelId();
  144.         $languageId         $salesChannelContext->getSalesChannel()->getLanguageId();
  145.         $shopUrl            $request->attributes->get(RequestTransformer::STOREFRONT_URL);
  146.         $config $this->systemConfigService->get('CbaxModulManufacturers'$salesChannelId)['config'];
  147.         $manufacturerId $request->get('cbaxManufacturerId');
  148.         $pageNumber $request->get('p');
  149.         // Checken, ob der Shopware Cache anfragt
  150.         if (empty($manufacturerId)) {
  151.             $manufacturerId $request->get('cbaxManufacturerId');
  152.             if (empty($manufacturerId)) {
  153.                 return $this->forwardToRoute('frontend.home.page');
  154.             }
  155.         }
  156.         // einzelnen Hersteller mit Bildern und Produkten holen
  157.         $criteria = new Criteria();
  158.         $criteria->addAssociation('media');
  159.         $criteria->addFilter(new EqualsFilter('id'$manufacturerId));
  160.         /** @var $data ProductManufacturerEntity|null */
  161.         $data $this->manufacturerRepository->search($criteria$context)->first();
  162.         if (empty($data)) {
  163.             return $this->forwardToRoute('frontend.home.page');
  164.         }
  165.         $cmsConfigPageId = !empty($config['cmsPageDetail']) ? $config['cmsPageDetail'] : null;
  166.         $cmsAltPageId = (!empty($data->getTranslated()) && !empty($data->getTranslated()['customFields']) && !empty($data->getTranslated()['customFields']['cbaxManufacturerAltCmsPage'])) ? $data->getTranslated()['customFields']['cbaxManufacturerAltCmsPage'] : null;
  167.         $cmsPageId = !empty($cmsAltPageId) ? $cmsAltPageId $cmsConfigPageId;
  168.         if ($config['active'] !== true || empty($cmsPageId)) {
  169.             return $this->forwardToRoute('frontend.home.page');
  170.         }
  171.         if (!empty($data->getTranslated()) && !empty($data->getTranslated()['customFields']) && !empty($data->getTranslated()['customFields']['cbaxManufacturerBannerMedia'])) {
  172.             $mediaCriteria = new Criteria();
  173.             $mediaCriteria->addFilter(new EqualsFilter('id'$data->getTranslated()['customFields']['cbaxManufacturerBannerMedia']));
  174.             $bannerMedia $this->mediaRepository->search($mediaCriteria$context)->first();
  175.         }
  176.         // Standard Page Object für Breadcrumb erzeugen
  177.         $newPage $this->genericLoader->load($request$salesChannelContext);
  178.         $page ManufacturersPage::createFrom($newPage);
  179.         /** @var $cmsPage CmsPageEntity|null **/
  180.         $cmsPage $this->helperComponent->getCmsPage($cmsPageId$context);
  181.         $hasSidebarFilterBlock false;
  182.         if ($cmsPage)
  183.         {
  184.             if ($cmsPage->getSections())
  185.             {
  186.                 $cmsPage->getSections()->sort(function (CmsSectionEntity $aCmsSectionEntity $b) {
  187.                     return $a->getPosition() <=> $b->getPosition();
  188.                 });
  189.                 
  190.                 $resolverContext = new EntityResolverContext($salesChannelContext$request$this->manufacturerDefinition$data);
  191.                 // sort blocks into sectionPositions
  192.                 foreach ($cmsPage->getSections() as $section) {
  193.                     $section->getBlocks()->sort(function (CmsBlockEntity $aCmsBlockEntity $b) {
  194.                         return $a->getPosition() <=> $b->getPosition();
  195.                     });
  196.                 }
  197.                 // find config overwrite
  198.                 //$overwrite = $config[$page->getId()] ?? $config;
  199.                 // overwrite slot config
  200.                 //$this->overwriteSlotConfig($page, $overwrite);
  201.                 // resolve slot data
  202.                 $this->helperComponent->loadSlotData($cmsPage$resolverContext);
  203.             }
  204.             // suche nach sidebar filter
  205.             $filterElement $cmsPage->getFirstElementOfType('cbax-manufacturers-filter-button');
  206.             if (!empty($filterElement))
  207.             {
  208.                 $hasSidebarFilterBlock true;
  209.             }
  210.             // suche nach sw product-listing
  211.             /** @var $swListingElement CmsSlotEntity|null **/
  212.             $swListingElement $cmsPage->getFirstElementOfType('product-listing');
  213.             // sidebar-filter block entfernen, wenn keine Produkte im Listing
  214.             if (!empty($cmsPage->getSections()) &&
  215.                 !empty($swListingElement) &&
  216.                 !empty($swListingElement->getData()) &&
  217.                 !empty($swListingElement->getData()->getListing()) &&
  218.                 $swListingElement->getData()->getListing()->getTotal() == 0
  219.             ) {
  220.                 /** @var $sidebarFilter CmsSlotEntity|null **/
  221.                 $sidebarFilter $cmsPage->getFirstElementOfType('sidebar-filter');
  222.                 if (!empty($sidebarFilter)) {
  223.                     $sidebarFilterBlockId $sidebarFilter->getBlockId() ?? null;
  224.                     if (!empty($sidebarFilterBlockId)) {
  225.                         foreach ($cmsPage->getSections() as $section) {
  226.                             if (!empty($section->getBlocks())) {
  227.                                 $section->getBlocks()->filterAndReduceByProperty('id'$sidebarFilterBlockId);
  228.                             }
  229.                         }
  230.                     }
  231.                 }
  232.             }
  233.             $page->setCmsPage($cmsPage);
  234.         }
  235.         if ($hasSidebarFilterBlock) {
  236.             // alle Hersteller für Sidebar laden
  237.             $result $this->helperComponent->getManufacturerByChar($config$salesChannelContext$context);
  238.             $cbaxModulManufacturers['data'] = $result;
  239.         }
  240.         //Produktlistendaten holen, wenn eigenes Listing, bei SW Listing kommen Daten über SW Resolver
  241.         if (empty($swListingElement))
  242.         {
  243.             // Produktlistendaten ermitteln
  244.             $data2 $this->helperComponent->getProductsListing($manufacturerId$pageNumber$salesChannelContext);
  245.             if ($pageNumber 0) {
  246.                 $limit $this->systemConfigService->get("core.listing.productsPerPage"$salesChannelId);
  247.                 $limit = !empty($limit) ? (int)$limit 20;
  248.                 $offset $limit * ($pageNumber -1);
  249.                 $cbaxModulManufacturers['offset'] = $offset;
  250.             }
  251.             $cbaxModulManufacturers['products'] = $data2;
  252.         }
  253.         $cbaxModulManufacturers['manufacturer'] = $data;
  254.         if (!empty($bannerMedia) && !empty($bannerMedia->getUrl())) {
  255.             $cbaxModulManufacturers['bannerMedia'] = $bannerMedia;
  256.         }
  257.         $cbaxModulManufacturers['p'] = $pageNumber;
  258.         $cbaxModulManufacturers['page'] = 'detail';
  259.         $link_index $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.index''/cbax/manufacturer/index'$salesChannelId$languageId$shopUrl);
  260.         $link_detail $this->manufacturerSeo->getSeoUrl('frontend.cbax.manufacturer.detail''/cbax/manufacturer/detail/' $manufacturerId$salesChannelId$languageId$shopUrl);
  261.         $breadcrumbLinkName $this->container->get('translator')->trans('cbaxManufacturer.page.breadcrumb.allManufacturers');
  262.         $breadcrumb[] = array(
  263.             'link' => $link_index,
  264.             'name' => $breadcrumbLinkName,
  265.             'translated' => array(
  266.                 'name' => $breadcrumbLinkName
  267.             )
  268.         );
  269.         $breadcrumb[] = array(
  270.             'link' => $link_detail,
  271.             'name' => $cbaxModulManufacturers['manufacturer']->getName(),
  272.             'active' => true,
  273.             'translated' => array(
  274.                 'name' => $cbaxModulManufacturers['manufacturer']->getTranslated()['name']
  275.             )
  276.         );
  277.         //Blöcke mit leeren Elementen nicht laden
  278.         $page $this->helperComponent->filterEmptyCmsBlocksDetail($page$cbaxModulManufacturers);
  279.         return $this->renderStorefront('@Storefront/storefront/base.html.twig', [
  280.             'cbaxModulManufacturers' => $cbaxModulManufacturers,
  281.             'page' => $page,
  282.             'breadcrumbList' => $breadcrumb
  283.         ]);
  284.     }
  285.     /**
  286.      * @HttpCache()
  287.      *
  288.      * Route to load the listing filters
  289.      *
  290.      * @Route("/widgets/cbax/manufacturer/{cbaxManufacturerId}/filter", name="frontend.cbax.manufacturer.filter", methods={"GET", "POST"}, defaults={"XmlHttpRequest"=true, "_routeScope"={"storefront"}})
  291.      */
  292.     public function filter(string $cbaxManufacturerIdRequest $requestSalesChannelContext $context): Response
  293.     {
  294.         $navigationId $context->getSalesChannel()->getNavigationCategoryId();
  295.         $criteria = new Criteria();
  296.         $criteria->addFilter(new EqualsFilter('manufacturerId'$cbaxManufacturerId));
  297.         // Allows to fetch only aggregations over the gateway.
  298.         $request->request->set('only-aggregations'true);
  299.         $request->request->set('manufacturer-filter'false);
  300.         // 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.
  301.         $request->request->set('reduce-aggregations'true);
  302.         $listing $this->listingRoute
  303.             ->load($navigationId$request$context$criteria)
  304.             ->getResult();
  305.         $mapped = [];
  306.         foreach ($listing->getAggregations() as $aggregation) {
  307.             $mapped[$aggregation->getName()] = $aggregation;
  308.         }
  309.         $response = new JsonResponse($mapped);
  310.         $response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER'1');
  311.         $response->headers->set('x-robots-tag''noindex');
  312.         return $response;
  313.     }
  314. }