custom/plugins/CbaxModulManufacturers/src/Controller/FrontendController.php line 343

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