src/Controller/ProductController.php line 323

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\DataMapper\Pagination\PaginatorDataMapper;
  4. use App\DataMapper\Product\ProductDetailDataMapper;
  5. use App\DataMapper\Product\ProductListingDataMapper;
  6. use App\Model\Product\Product;
  7. use App\Repository\ProductRepository;
  8. use App\Website\LinkGenerator\ProductLinkGenerator;
  9. use Knp\Component\Pager\Pagination\SlidingPagination;
  10. use Knp\Component\Pager\PaginatorInterface;
  11. use Pimcore\Bundle\EcommerceFrameworkBundle\Factory;
  12. use Pimcore\Bundle\EcommerceFrameworkBundle\FilterService\ListHelper;
  13. use Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\ElasticSearch\AbstractElasticSearch;
  14. use Pimcore\Bundle\EcommerceFrameworkBundle\IndexService\ProductList\ProductListInterface;
  15. use Pimcore\Config;
  16. use Pimcore\Controller\FrontendController;
  17. use App\Model\Product\Category;
  18. use Pimcore\Model\DataObject\ClassDefinition;
  19. use Pimcore\Model\DataObject\FilterDefinition;
  20. use Pimcore\Model\DataObject\ProductGroup;
  21. use Pimcore\Model\DataObject\ProductLine;
  22. use Pimcore\Translation\Translator;
  23. use Pimcore\Twig\Extension\Templating\HeadTitle;
  24. use Pimcore\Twig\Extension\Templating\Placeholder;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. class ProductController extends FrontendController
  29. {
  30.     public function __construct(
  31.         private ProductRepository $productRepository
  32.     ){
  33.     }
  34.     /**
  35.      * @param Request $request
  36.      * @return Response
  37.      */
  38.     public function indexAction(Request $requestHeadTitle $headTitleHelperFactory $ecommerceFactoryListHelper $listHelperPaginatorInterface $paginator): Response
  39.     {
  40.         $params array_merge($request->query->all(), $request->attributes->all());
  41.         $indexService $ecommerceFactory->getIndexService();
  42.         $productListing $indexService->getProductListForCurrentTenant();
  43.         if(!isset($params['sort'])){
  44.             $params['sort'] = 'o_id-desc';
  45.         }
  46.         $elements explode("-"$params['sort']);
  47.         $productListing->setOrder(strtoupper($elements[1]));
  48.         $productListing->setOrderKey($elements[0]);
  49.         $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_HIDE);
  50.         $params['productListing'] = $productListing;
  51.         if ($request->get('filterdefinition') instanceof FilterDefinition) {
  52.             $filterDefinition $request->get('filterdefinition');
  53.         }
  54.         if (empty($filterDefinition)) {
  55.             $filterDefinition Config::getWebsiteConfig()['fallbackFilterdefinition'];
  56.         }
  57.         $filterService $ecommerceFactory->getFilterService();
  58.         $listHelper->setupProductList($filterDefinition$productListing$params$filterServicetrue);
  59.         $params['filterService'] = $filterService;
  60.         $params['filterDefinition'] = $filterDefinition;
  61.         /** @var SlidingPagination $paginator */
  62.         // init pagination
  63.         $paginator $paginator->paginate(
  64.             $productListing,
  65.             $request->get('page'1),
  66.             $filterDefinition->getPageLimit()
  67.         );
  68.         $params['results'] = $paginator;
  69.         $params['paginationVariables'] = $paginator->getPaginationData();
  70.         return $this->render('product/index.html.twig'$params);
  71.     }
  72.     /**
  73.      *
  74.      * @Route("/{_locale}/product-category/{categoryname}-{category}", name="shop-category", requirements={"categoryname"="[\w-]+", "category"="\d+"})
  75.      *
  76.      * @param Request $request
  77.      * @param HeadTitle $headTitleHelper
  78.      * @param Factory $ecommerceFactory
  79.      * @param ListHelper $listHelper
  80.      *
  81.      * @return Response
  82.      */
  83.     public function listingAction(Request $requestFactory $ecommerceFactoryListHelper $listHelperPaginatorInterface $paginator)
  84.     {
  85.         $params array_merge($request->query->all(), $request->attributes->all());
  86.         //needed to make sure category filter filters for active category
  87.         $params['parentCategoryIds'] = $params['category'] ?? null;
  88.         $category Category::getById($params['category'] ?? -1);
  89.         $params['category'] = $category;
  90.         $indexService $ecommerceFactory->getIndexService();
  91.         $productListing $indexService->getProductListForCurrentTenant();
  92.         if(!isset($params['sort'])){
  93.             $params['sort'] = 'o_id-desc';
  94.         }
  95.         $elements explode("-"$params['sort']);
  96.         $productListing->setOrder(strtoupper($elements[1]));
  97.         $productListing->setOrderKey($elements[0]);
  98.         $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_HIDE);
  99.         $params['productListing'] = $productListing;
  100.         // load current filter
  101.         if ($category) {
  102.             $filterDefinition $category->getFilterDefinition();
  103.             $trackingManager $ecommerceFactory->getTrackingManager();
  104.             $trackingManager->trackCategoryPageView($category->getName(), null);
  105.         }
  106.         if ($request->get('filterdefinition') instanceof FilterDefinition) {
  107.             $filterDefinition $request->get('filterdefinition');
  108.         }
  109.         if (empty($filterDefinition)) {
  110.             $filterDefinition Config::getWebsiteConfig()['fallbackFilterdefinition'];
  111.         }
  112.         $filterService $ecommerceFactory->getFilterService();
  113.         $listHelper->setupProductList($filterDefinition$productListing$params$filterServicetrue);
  114.         $params['filterService'] = $filterService;
  115.         $params['filterDefinition'] = $filterDefinition;
  116.         /** @var SlidingPagination $paginator */
  117.         // init pagination
  118.         $paginator $paginator->paginate(
  119.             $productListing,
  120.             $request->get('page'1),
  121.             $filterDefinition->getPageLimit()
  122.         );
  123.         $params['results'] = $paginator;
  124.         $params['paginationVariables'] = $paginator->getPaginationData();
  125.         if ($request->attributes->get('noLayout')) {
  126.             return $this->render('product/listing_content.html.twig'$params);
  127.         }
  128.         // track product impressions
  129.         $trackingManager $ecommerceFactory->getTrackingManager();
  130.         foreach ($paginator as $product) {
  131.             $trackingManager->trackProductImpression($product'grid');
  132.         }
  133.         return $this->render('product/index.html.twig'$params);
  134.     }
  135.     /**
  136.      *
  137.      * @Route("/{_locale}/product-line/{productlinename}-{productline}", name="shop-productline", requirements={"productlinename"="[\w-]+", "productline"="\d+"})
  138.      *
  139.      * @param Request $request
  140.      * @param HeadTitle $headTitleHelper
  141.      * @param Factory $ecommerceFactory
  142.      * @param ListHelper $listHelper
  143.      *
  144.      * @return Response
  145.      */
  146.     public function listingProductLines(Request $requestFactory $ecommerceFactoryListHelper $listHelperPaginatorInterface $paginator): Response
  147.     {
  148.         $params array_merge($request->query->all(), $request->attributes->all());
  149.         $productLine ProductLine::getById($params['productline'] ?? -1);
  150.         $indexService $ecommerceFactory->getIndexService();
  151.         $productListing $indexService->getProductListForCurrentTenant();
  152.         if(!isset($params['sort'])){
  153.             $params['sort'] = 'o_id-desc';
  154.         }
  155.         $elements explode("-"$params['sort']);
  156.         $productListing->setOrder(strtoupper($elements[1]));
  157.         $productListing->addRelationCondition("productLine""dest IN (".$productLine->getId().")");
  158.         $productListing->setOrderKey($elements[0]);
  159.         $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_HIDE);
  160.         $params['productListing'] = $productListing;
  161.         if ($request->get('filterdefinition') instanceof FilterDefinition) {
  162.             $filterDefinition $request->get('filterdefinition');
  163.         }
  164.         if (empty($filterDefinition)) {
  165.             $filterDefinition Config::getWebsiteConfig()['fallbackFilterdefinition'];
  166.         }
  167.         $filterService $ecommerceFactory->getFilterService();
  168.         $listHelper->setupProductList($filterDefinition$productListing$params$filterServicetrue);
  169.         $params['filterService'] = $filterService;
  170.         $params['filterDefinition'] = $filterDefinition;
  171.         /** @var SlidingPagination $paginator */
  172.         // init pagination
  173.         $paginator $paginator->paginate(
  174.             $productListing,
  175.             $request->get('page'1),
  176.             $filterDefinition->getPageLimit()
  177.         );
  178.         $params['results'] = $paginator;
  179.         $params['paginationVariables'] = $paginator->getPaginationData();
  180.         if ($request->attributes->get('noLayout')) {
  181.             return $this->render('product/listing_content.html.twig'$params);
  182.         }
  183.         // track product impressions
  184.         $trackingManager $ecommerceFactory->getTrackingManager();
  185.         foreach ($paginator as $product) {
  186.             $trackingManager->trackProductImpression($product'grid');
  187.         }
  188.         return $this->render('product/index.html.twig'$params);
  189.     }
  190.     /**
  191.      *
  192.      * @Route("/{_locale}/product-group/{productgroupname}-{productgroup}", name="shop-productgroup", requirements={"productgroupname"="[\w-]+", "productgroup"="\d+"})
  193.      *
  194.      * @param Request $request
  195.      * @param HeadTitle $headTitleHelper
  196.      * @param Factory $ecommerceFactory
  197.      * @param ListHelper $listHelper
  198.      *
  199.      * @return Response
  200.      */
  201.     public function listingProductGroups(Request $requestFactory $ecommerceFactoryListHelper $listHelperPaginatorInterface $paginator): Response
  202.     {
  203.         $params array_merge($request->query->all(), $request->attributes->all());
  204.         $productGroup ProductGroup::getById($params['productgroup'] ?? -1);
  205.         $indexService $ecommerceFactory->getIndexService();
  206.         $productListing $indexService->getProductListForCurrentTenant();
  207.         if(!isset($params['sort'])){
  208.             $params['sort'] = 'o_id-desc';
  209.         }
  210.         $elements explode("-"$params['sort']);
  211.         $productListing->setOrder(strtoupper($elements[1]));
  212.         $productListing->addRelationCondition("productGroup""dest IN (".$productGroup->getId().")");
  213.         $productListing->setOrderKey($elements[0]);
  214.         $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_HIDE);
  215.         $params['productListing'] = $productListing;
  216.         if ($request->get('filterdefinition') instanceof FilterDefinition) {
  217.             $filterDefinition $request->get('filterdefinition');
  218.         }
  219.         if (empty($filterDefinition)) {
  220.             $filterDefinition Config::getWebsiteConfig()['fallbackFilterdefinition'];
  221.         }
  222.         $filterService $ecommerceFactory->getFilterService();
  223.         $listHelper->setupProductList($filterDefinition$productListing$params$filterServicetrue);
  224.         $params['filterService'] = $filterService;
  225.         $params['filterDefinition'] = $filterDefinition;
  226.         /** @var SlidingPagination $paginator */
  227.         // init pagination
  228.         $paginator $paginator->paginate(
  229.             $productListing,
  230.             $request->get('page'1),
  231.             $filterDefinition->getPageLimit()
  232.         );
  233.         $params['results'] = $paginator;
  234.         $params['paginationVariables'] = $paginator->getPaginationData();
  235.         if ($request->attributes->get('noLayout')) {
  236.             return $this->render('product/listing_content.html.twig'$params);
  237.         }
  238.         // track product impressions
  239.         $trackingManager $ecommerceFactory->getTrackingManager();
  240.         foreach ($paginator as $product) {
  241.             $trackingManager->trackProductImpression($product'grid');
  242.         }
  243.         return $this->render('product/index.html.twig'$params);
  244.     }
  245.     /**
  246.      * @Route ("/{_locale}/products/{slug}-{productId}", name="product_show", requirements={"slug"="[\w-]+", "productId"="\d+"})
  247.      * @param Request $request
  248.      * @param int $productId
  249.      * @return Response
  250.      * @throws \Exception
  251.      */
  252.     public function showAction(Request $requestint $productIdProductLinkGenerator $productLinkGeneratorTranslator $translator): Response
  253.     {
  254.         $product $this->productRepository->find($productId);
  255.         if(empty($product)){
  256.             throw $this->createNotFoundException('Product not found');
  257.         }
  258.         $otherLanguageUrl str_replace("/" $request->getLocale() . "/""/" . ($request->getLocale() == "de" "en" "de") . "/"$request->getRequestUri());
  259.         return $this->render('product/show.html.twig', [
  260.             'otherLanguageUrl' => $otherLanguageUrl,
  261.             'product' => (new ProductDetailDataMapper($product$translator))->toArray($request),
  262.         ]);
  263.     }
  264.     /**
  265.      * @Route("/{_locale}/search", name="search", methods={"GET"})
  266.      */
  267.     public function searchAction(Request $requestListHelper $listHelperFactory $ecommerceFactoryProductLinkGenerator $productLinkGeneratorTranslator $translatorHeadTitle $headTitleHelperPlaceholder $placeholderPaginatorInterface $paginator): Response
  268.     {
  269.         $params $request->query->all();
  270.         $indexService $ecommerceFactory->getIndexService();
  271.         $productListing $indexService->getProductListForCurrentTenant();
  272.         $productListing->setVariantMode(ProductListInterface::VARIANT_MODE_HIDE);
  273.         $term strip_tags($request->query->get('term'));
  274.         if ($productListing instanceof AbstractElasticSearch) {
  275.             // simple elastic search query - uses multi-match query on all defined search_attributes
  276. //            $productListing->addQueryCondition($term);
  277.             //sample for a more specific elastic search query - not considers search_attributes but provides full flexibility
  278.             // this query weights cars more that accessories
  279.             $query = [
  280.                 'function_score' => [
  281.                     'query' => [
  282.                         'multi_match' => [
  283.                             'query' => $term,
  284.                             'type' => 'cross_fields',
  285.                             'operator' => 'and',
  286.                             'fields' => [
  287.                                 'attributes.name^4',
  288.                                 'attributes.name.analyzed',
  289.                                 'attributes.name.analyzed_ngram',
  290.                                 'attributes.manufacturer_name^3',
  291.                                 'attributes.manufacturer_name.analyzed',
  292.                                 'attributes.manufacturer_name.analyzed_ngram',
  293.                                 'attributes.code',
  294.                                 'attributes.code.analyzed',
  295.                                 'attributes.code.analyzed_ngram',
  296.                                 'attributes.carClass',
  297.                                 'attributes.carClass.analyzed',
  298.                                 'attributes.carClass.analyzed_ngram'
  299.                             ]
  300.                         ]
  301.                     ],
  302.                     'boost_mode' => 'multiply'
  303.                 ]
  304.             ];
  305.             $productListing->addQueryCondition($query'searchTerm');
  306.         } else {
  307.             //default mysql search query condition - would also work for elastic search in that way
  308.             $term trim(preg_replace('/\s+/'' '$term));
  309.             if (!empty($term)) {
  310.                 foreach (explode(' '$term) as $t) {
  311.                     if(strpos($t'/') !== false){
  312.                         $productListing->addCondition('code LIKE "%'.$t.'%"');
  313.                     }else{
  314.                         $productListing->addQueryCondition($t);
  315.                     }
  316.                 }
  317.             }
  318.         }
  319.         //$productListing->addCondition('code LIKE "%12/5510%"');
  320.         if (isset($params['autocomplete'])) {
  321.             $resultset = [];
  322.             $productListing->setLimit(10);
  323.             foreach ($productListing as $product) {
  324.                 $result['href'] = $productLinkGenerator->generate($product, []);
  325.                 $result['product'] = $product->getOSName() ?? '';
  326.                 if ($product instanceof Product) {
  327.                     $result['product'] .= ' ' $product->getColor()[0] . ', ' $product->getShoeForm();
  328.                 }
  329.                 $resultset[] = $result;
  330.             }
  331.             return $this->json($resultset);
  332.         }
  333.         if ($request->get('filterdefinition') instanceof FilterDefinition) {
  334.             $filterDefinition $params['filterDefinition'] = $request->get('filterdefinition');
  335.         }
  336.         if (empty($filterDefinition)) {
  337.             $filterDefinition $params['filterDefinition'] = Config::getWebsiteConfig()['fallbackFilterdefinition'];
  338.         }
  339.         // create and init filter service
  340.         $filterService Factory::getInstance()->getFilterService();
  341.         $listHelper->setupProductList($filterDefinition$productListing$params$filterServicetrue);
  342.         $params['filterService'] = $filterService;
  343.         $params['productListing'] = $productListing;
  344.         // init pagination
  345.         $paginator $paginator->paginate(
  346.             $productListing,
  347.             $request->query->getInt('page'1),
  348.             $filterDefinition->getPageLimit()
  349.         );
  350.         $params['results'] = $paginator;
  351.         $params['paginationVariables'] = $paginator->getPaginationData();
  352.         $trackingManager $ecommerceFactory->getTrackingManager();
  353.         foreach ($paginator as $product) {
  354.             $trackingManager->trackProductImpression($product'search-results');
  355.         }
  356.         $params['language'] = $request->getLocale();
  357.         $params['term'] = $term;
  358.         //$breadcrumbHelperService->enrichGenericDynamicPage($translator->trans('shop.search-result', [$term]));
  359.         $headTitleHelper($translator->trans('shop.search-result', [$term]));
  360.         return $this->render('product/index.html.twig'$params);
  361.     }
  362. }