src/Controller/ProductController.php line 133

Open in your IDE?
  1. <?php
  2. // src/Controller/DefaultController.php
  3. namespace App\Controller;
  4. use App\Entity\Comment;
  5. use App\Entity\Product;
  6. use App\Entity\ProductCategory;
  7. use App\Entity\ProductGroup;
  8. use App\Entity\ProductHasProductSpecificationValue;
  9. use App\Entity\ProductSpecification;
  10. use App\Entity\ProductSpecificationValue;
  11. use App\Entity\SeoFormula;
  12. use App\Repository\ProductCategoryRepository;
  13. use App\Repository\ProductHasProductSpecificationValueRepository;
  14. use App\Repository\ProductRepository;
  15. use App\Repository\ProductSpecificationValueRepository;
  16. use App\Services\CartManager;
  17. use App\Services\LikesService;
  18. use App\Services\MenuService;
  19. use App\Services\SearchService;
  20. use App\Services\SeoFormulaService;
  21. use App\ZorrovAdmin\ApiBundle\Controller\ApiController;
  22. use App\ZorrovAdmin\DashboardBundle\Services\DropshipperBalanceService;
  23. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  24. use Symfony\Component\HttpFoundation\Request;
  25. use Symfony\Component\HttpFoundation\Response;
  26. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  27. use Symfony\Component\Routing\Annotation\Route;
  28. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  29. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  30. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  31. use Symfony\Contracts\Translation\TranslatorInterface;
  32. class ProductController extends ApiController
  33. {
  34.     /**
  35.      * @Route("/category-filters-apply/{slug}/{sort}", name="app_category_filters_apply")
  36.      */
  37.     public function categoryFiltersApplyAction($slug$sortRequest $request)
  38.     {
  39.         $filterStr $this->filtersApply($request$sort);
  40.         return $this->redirectToRoute('app_category_show', ['slug' => $slug'filters' => $filterStr]);
  41.     }
  42.     /**
  43.      * @Route("/category/{slug}/{filters}", name="app_category_show")
  44.      */
  45.     public function categoryShowAction($slug,
  46.                                        CartManager $cartManager,
  47.                                        MenuService $menuService,
  48.                                        ProductSpecificationValueRepository $productSpecificationValueRepository,
  49.                                        ProductCategoryRepository $categoryRep,
  50.                                        ProductHasProductSpecificationValueRepository $productHasSpecificationValueRepository,
  51.                                        LikesService $likesService,
  52.                                        SeoFormulaService $seoFormulaService,
  53.                                        DropshipperBalanceService $dropshipperBalanceService,
  54.                                        $filters '')
  55.     {
  56.         if(preg_match('/[A-Z]/'$slug)){
  57.             $url $this->generateUrl('app_category_show',array('slug'=>strtolower($slug),'filters'=>$filters));
  58.             return $this->redirect($url301);
  59.         }
  60.         $category $categoryRep->findOneBySlug($slug);
  61.         if($category->hasShownGrandChildren()
  62.             or ($category->getParent() and $category->hasChildren() and $category->getShowChildrenOnWebsite())){
  63. //            $categories =  $categoryRep->findThreeLevelWithSeries($category);
  64. //            $preparedCategories = $menuService->generateChildren($categories, [],'app_category_show');
  65.             return $this->render('frontend/product/category_list.html.twig', [
  66.                 'slug'=>$slug,
  67. //                'categories'=>$preparedCategories,
  68. //                'categoryId' => $category->getId(),
  69.                 'mainCategory'=>$category,
  70.             ]);
  71.         }
  72. //        else{
  73. //            $categories = $categoryRep->findTwoLevelWithSeries($category);
  74. //            $preparedCategories = $menuService->generateOneLevelChildren($categories, [],'app_category_show');
  75. //            return $this->render('frontend/product/category_small_list.html.twig', [
  76. //                'categories'=>$preparedCategories,
  77. //                'categoryId' => $category->getId(),
  78. //                'category'=>$category,
  79. //            ]);
  80. //        }
  81.         if(!$category){
  82.             throw $this->createNotFoundException('Category does not exist');
  83.         }
  84.         $constructor $category->getCategoryUsedForGeneration();
  85.         $cart $cartManager->getCurrentCart($this->getUser());
  86.         $cartProducts $this->getDoctrine()->getRepository(Product::class)
  87.             ->getAllCartProductsIndexById($cart->getId());
  88.         $seo $this->seoCategoryData($category,$seoFormulaService);
  89.         $filterStr $filters;
  90.         $filters $this->prepareFilters($filters);
  91.         if(!$filters)
  92.             throw $this->createNotFoundException('Filters does not exist');
  93.         $specifications $this->getDoctrine()->getRepository(ProductSpecification::class)
  94.             ->findByValuesIds($filters['filters']);
  95.         $filterTexts $this->prepareFilterTexts($specifications);
  96.         $seoTitle $this->prepareSeoTitle($filterTexts,$filters['page']);
  97.         $count = (int)$this->getParameter('product_on_page');
  98.         $products $this->getProducts($category$filters$specifications$count);
  99.         $last = (int)ceil($products['allProductsCount']['1']/$count);
  100.         if($category->checkIfGroupsIn()){
  101.             $productsSpecValues $productSpecificationValueRepository->findAllByGroups($products['productIdsUnLimited']);
  102.             $productsSpecValuesCount $productHasSpecificationValueRepository->countAllGroupsBySpecificationValues($products['productIdsUnLimited']);
  103.         }
  104.         else{
  105.             $productsSpecValues $productSpecificationValueRepository->findAllByProducts($products['productIdsUnLimited']);
  106.             $productsSpecValuesCount $productHasSpecificationValueRepository->countAllProductsBySpecificationValues($products['productIdsUnLimited']);
  107.         }
  108. //        dump($products['productIdsUnLimited']);
  109. //        dump($productsSpecValues);
  110. //        dump($filters);
  111. //        dump($productsSpecValuesCount);
  112. //        die();
  113.         $specifications $this->prepareSpecificationArray($productsSpecValues$filters['filters'], $productsSpecValuesCount);
  114.         $wishlist $likesService->getStorageIds();
  115.         $filterStr $this->prepareFilterStr($filterStr);
  116.         $filterFilterNextPageStr $this->prepareFilterNextPageText($filterStr$filters$last);
  117.         $productsCount $this->productsCountInit($filters$count$products['allProductsCount'], $last);
  118. //        dump($productsCount); die();
  119.         $productsLimited $dropshipperBalanceService->checkPrices($products['productsLimited'], $this->getUser());
  120.         dump($filters);
  121.         dump($filterStr);
  122.         die();
  123.         return $this->render('frontend/product/category.html.twig', [
  124.             'category' => $category,
  125.             'categoryId' => $category->getId(),
  126.             'constructor' => $constructor,
  127.             'products' => $productsLimited,
  128.             'productsIdsUnLimitedStr' => implode(',',$products['productIdsUnLimited']),
  129.             'productsIdsUnLimited' => $products['productIdsUnLimited'],
  130.             'filters' => $filters,
  131.             'filterStr' => $filterStr,
  132.             'filterFilterNextPageStr' => $filterFilterNextPageStr,
  133.             'filterTexts' => $filterTexts,
  134.             'seoTitle' => $seoTitle,
  135.             'cart' => $cart,
  136.             'count' => $count,
  137.             'productsCount' => $productsCount,
  138.             'last' => $last,
  139.             'seo' => $seo,
  140.             'wishlist' => $wishlist,
  141.             'orderProducts' => array_keys($cartProducts),
  142.             'specifications' => $specifications,
  143. //            'pagesInRange' => $pagesInRange
  144.         ]);
  145.     }
  146.     /**
  147.      * @Route("/category-step/{slug}/{filters}", name="app_category_steps")
  148.      */
  149.     public function categoryStepAction($slug,
  150.                                        Request $request,
  151.                                        CartManager $cartManager,
  152.                                        LikesService $likesService,
  153.                                        DropshipperBalanceService $dropshipperBalanceService,
  154.                                        $filters '')
  155.     {
  156.         $filterStr $filters;
  157.         if(preg_match('/[A-Z]/'$slug)){
  158.             $url $this->generateUrl('app_category_show',array('slug'=>strtolower($slug)));
  159.             return $this->redirect($url301);
  160.         }
  161.         $filters $this->prepareFilters($filters);
  162.         $activePages $this->activePagesInit($request$filters);
  163.         $specifications $this->getDoctrine()->getRepository(ProductSpecification::class)
  164.             ->findByValuesIds($filters['filters']);
  165.         $cart $cartManager->getCurrentCart($this->getUser());
  166.         $cartProducts $this->getDoctrine()->getRepository(Product::class)
  167.             ->getAllCartProductsIndexById($cart->getId());
  168.         $category $this->getDoctrine()->getRepository(ProductCategory::class)
  169.             ->findOneBySlug($slug);
  170.         $count = (int)$this->getParameter('product_on_page');
  171.         $products $this->getProducts($category$filters$specifications$count);
  172. //        $products = $this->getDoctrine()->getRepository(Product::class)
  173. //            ->findProductsByCategoryMinimized($category->getId(), $filtersPrepared, $filters['sort'], $filters['page']-1, $count);
  174. //        dump($products); die();
  175.         $last = (int)ceil($products['allProductsCount']['1']/$count);
  176.         $wishlist $likesService->getStorageIds();
  177.         $filterStr $this->prepareFilterStr($filterStr);
  178.         $filterFilterNextPageStr $this->prepareFilterNextPageText($filterStr$filters$last);
  179.         $productsCount $this->productsCountInit($filters$count$products['allProductsCount'], $last);
  180.         $productsLimited $dropshipperBalanceService->checkPrices($products['productsLimited'], $this->getUser());
  181.         $data = array(
  182.             'products' => $this->renderView('frontend/product/category_step.html.twig', [
  183.                 'category'=>$category,
  184.                 'products'=>$productsLimited,
  185.                 'filters'=>$filterFilterNextPageStr,
  186.                 'current'=>$filters['page'],
  187.                 'last' => $last,
  188.                 'orderProducts' => array_keys($cartProducts)
  189.             ]),
  190.             'pagination' => $this->renderView('frontend/parts/pagination.html.twig', [
  191.                 'slug'=> $slug,
  192.                 'activePages'=> $activePages,
  193.                 'filters'=> $filterStr,
  194.                 'current'=> $filters['page'],
  195.                 'last' => $last
  196.             ]),
  197.             'buttonCount' => $productsCount
  198.         );
  199.         return $this->respond($data);
  200.     }
  201.     /**
  202.      * @Route("/product/{slug}", name="app_product_show")
  203.      * @Route("/product/custom/{slug}", name="app_product_show_custom")
  204.      */
  205.     public function productShowAction($slug,
  206.                                       CartManager $cartManager,
  207.                                       LikesService $likesService,
  208.                                       SeoFormulaService $seoFormulaService,
  209.                                       Request $request)
  210.     {
  211.         $cart $cartManager->getCurrentCart($this->getUser());
  212.         $product $this->getDoctrine()->getRepository(Product::class)
  213.             ->findProductBySlug($slug);
  214.         if(!$product){
  215.             $products $this->getDoctrine()->getRepository(Product::class)
  216.                 ->findProductByTranslationSlug($slug);
  217.             if($products)
  218.                 $product $products[0];
  219.         }
  220.         if($product->getCustom()){
  221.             $product $cartManager->recalculateCustomProductPrice($product);
  222.         }
  223.         $productSpecifications $this->getDoctrine()->getRepository(ProductHasProductSpecificationValue::class)
  224.             ->findSpecificationsForProductPage($product);
  225.         if(!$product){
  226.             throw $this->createNotFoundException('The product does not exist');
  227.         }
  228.         $constructor $product->getCategory()->getCategoryUsedForGeneration();
  229.         $wishlistIds $likesService->getStorageIds();
  230.         $cartProducts $this->getDoctrine()->getRepository(Product::class)
  231.             ->getAllCartProductsIndexById($cart->getId());
  232.         $seo $this->seoProductData($product,$seoFormulaService);
  233.         $models $this->getModels($product);
  234.         $gallery $this->getProductGallery($product);
  235. //        $suggestions = $this->getDoctrine()->getRepository(Product::class)
  236. //            ->getSuggstionsProductsByCategory($cart->getId());
  237. //        $number = random_int(0, 100);
  238. //        return new Response(
  239. //            '<html><body>Lucky number: '.$number.'</body></html>'
  240. //        );
  241. //        dump($productSpecifications); die();
  242.         $info $this->getInfo($product$request->getLocale());
  243.         return $this->render('frontend/product/product.html.twig', [
  244.             'product'=>$product,
  245.             'gallery'=>$gallery,
  246.             'constructor' => $constructor,
  247.             'models' => $models,
  248.             'info' => $info,
  249.             'categoryId' => $product->getCategory()->getId(),
  250.             'productSpecificationValues'=>$productSpecifications,
  251.             'seo'=>$seo,
  252.             'wishlist' => $wishlistIds,
  253.             'orderProducts' => array_keys($cartProducts),
  254.         ]);
  255.     }
  256.     /**
  257.      * @Route("/you-may-like-it/{id}", name="app_you_may_like_it")
  258.      */
  259.     public function youMayLikeItAction($idCartManager $cartManagerTranslatorInterface $translator,
  260.                                        DropshipperBalanceService $dropshipperBalanceService)
  261.     {
  262.         $cart $cartManager->getCurrentCart($this->getUser());
  263. //        $product = $this->getDoctrine()->getRepository(Product::class)
  264. //            ->find($id);
  265.         $cartProducts $this->getDoctrine()->getRepository(Product::class)
  266.             ->getAllCartProductsIndexById($cart->getId());
  267.         $ids = ($cartProducts) ? array_keys($cartProducts) : array();
  268.         $ids[] = $id;
  269.         $suggestions $this->getDoctrine()->getRepository(Product::class)
  270.             ->getRandomSuggestionsProductsNotInCart($ids);
  271. //        $number = random_int(0, 100);
  272. //        return new Response(
  273. //            '<html><body>Lucky number: '.$number.'</body></html>'
  274. //        );
  275.         $suggestions $dropshipperBalanceService->checkPrices($suggestions$this->getUser());
  276.         return $this->render('frontend/parts/you_may_like_it.html.twig', [
  277.             'products'=>$suggestions,
  278.             'blockTitle'=>$translator->trans('product.you_will_like_it',[],'translation')
  279. //            'orderProducts' => array_keys($cartProducts)
  280.         ]);
  281.     }
  282.     /**
  283.      * @Route("/pattern-on-other-products/{id}", name="app_pattern_on_other_products")
  284.      */
  285.     public function patternOnOtherProductsAction($idTranslatorInterface $translator,
  286.                                                  ProductRepository $productRepository,
  287.                                                  DropshipperBalanceService $dropshipperBalanceService)
  288.     {
  289.         $product $productRepository->find($id);
  290.         if(!$product){
  291.             throw $this->createNotFoundException('The product does not exist');
  292.         }
  293.         $patternCategoryConstructor $product->getPatternCategoryConstructor();
  294.         if(!$patternCategoryConstructor){
  295.             return new Response();
  296.         }
  297.         $category $patternCategoryConstructor->getCategory();
  298.         $pattern $patternCategoryConstructor->getPattern();
  299.         $products $productRepository->getPatternOnOtherProducts($category$pattern20);
  300.         $products $dropshipperBalanceService->checkPrices($products$this->getUser());
  301.         return $this->render('frontend/parts/you_may_like_it.html.twig', [
  302.             'patternProducts'=>true,
  303.             'products'=>$products,
  304.             'blockTitle'=>$translator->trans('product.other_products_with_print',[],'translation')
  305. //            'orderProducts' => array_keys($cartProducts)
  306.         ]);
  307.     }
  308.     /**
  309.      * @Route("/wishlist-page/", name="app_wishlist_page")
  310.      */
  311.     public function wishlistPageAction(LikesService $likesService)
  312.     {
  313.         $wishlistIds $likesService->getStorageIds();
  314. //        dump($wishlistIds); die();
  315.         $wishlistProducts $this->getDoctrine()->getRepository(Product::class)
  316.             ->findByIds($wishlistIds);
  317.         return $this->render('frontend/product/wishlist-page.html.twig', [
  318.             'products' => $wishlistProducts,
  319.             'wishlist' => $wishlistIds,
  320. //            'orderProducts' => array_keys($cartProducts)
  321.         ]);
  322.     }
  323.     public function wishlistCount(LikesService $likesService)
  324.     {
  325.         $wishlistCount $likesService->getWishlistCount();
  326.         return new Response($wishlistCount);
  327.     }
  328.     private function prepareSpecificationArray($values$filters$productsSpecValuesCount)
  329.     {
  330.         $specifications = array();
  331.         $productsSpecValuesCountArr $this->prepareValuesProductCountArray($productsSpecValuesCount);
  332.         foreach ($values as $value){
  333.             $specification $value->getProductSpecification();
  334.             if(empty($specifications[$specification->getId()])){
  335.                 $specifications[$specification->getId()] = array(
  336.                     'title' => $specification->translate()->getTitle(),
  337.                     'position' => $specification->getPosition() ? $specification->getPosition() : 0,
  338.                     'values' => array()
  339.                 );
  340.             }
  341.             if(!empty($productsSpecValuesCountArr[$value->getId()])){
  342.                 $specifications[$specification->getId()]['values'][$value->translate()->getValue()] = array(
  343.                     'id' => $value->getId(),
  344.                     'value' => $value->translate()->getValue(),
  345.                     'count' => $productsSpecValuesCountArr[$value->getId()],
  346.                     'checked' => in_array($value->getId(), $filters)
  347.                 );
  348.             }
  349.         }
  350.         $result $specifications;
  351.         foreach ($specifications as $key => $specification){
  352.             ksort($specification['values']);
  353.             $result[$key]['values'] =  $specification['values'];
  354.         }
  355.         //to sort specifications by position
  356.         $price array_column($result'position');
  357.         array_multisort($priceSORT_DESC$result);
  358.         return $result;
  359.     }
  360.     private function prepareValuesProductCountArray($productsSpecValuesCountArr)
  361.     {
  362.         $values = array();
  363.         foreach ($productsSpecValuesCountArr as $productsSpecValuesCount){
  364.             $values[$productsSpecValuesCount[0]['productSpecificationValue']['id']] = $productsSpecValuesCount[1];
  365.         }
  366.         return $values;
  367.     }
  368.     /**
  369.      * @Route("/category-list/{slug}", name="app_productcategory_list")
  370.      */
  371.     public function categoryListAction($slugMenuService $menuServiceRequest $request)
  372.     {
  373.         $categoryRep $this->getDoctrine()->getRepository(ProductCategory::class);
  374.         $category $categoryRep->findOneBySlug($slug);
  375. //        $preparedCategories = $this->getDoctrine()->getRepository(ProductCategory::class)
  376. //            ->findByParentCategoryWithSeriesPrepared($category);
  377.         if($category->hasGrandChildren()){
  378.             $categories =  $categoryRep->findThreeLevelWithSeries($category);
  379. //            if($this->getUser() and $this->getUser()->getUsername()=='admin'){
  380. //                dump($categories); die();
  381. //            }
  382. //            dump($categories); die();
  383.             $items $menuService->generateChildrenForCategoryList($categories$request->getLocale());
  384.             $preparedCategories = array(
  385.                 'items'=>$items,
  386.                 'title'=>$category->translate()->getTitle()
  387.             );
  388.         }
  389.         else{
  390.             $categories $categoryRep->findTwoLevelWithSeries($category);
  391.             $icon $category->getPoster() ?  json_decode($category->getPoster())->default_file "";
  392.             $preparedCategories = array(
  393. //                'items'=>array(
  394. //                    'children'=>$menuService->generateChilden($categories),
  395. //                    'icon'=>$icon,
  396. //                    'label'=> $category->translate()->getTitle(),
  397. //                    'url'=> $this->generateUrl('app_category_show',array('slug'=>$slug))
  398. //                ),
  399.                 'items'=>$menuService->generateChilden($categories$request->getLocale()),
  400.                 'title'=>$category->translate()->getTitle()
  401.             );
  402.         }
  403. //        dump($preparedCategories); die();
  404.         return $this->respond($preparedCategories);
  405.     }
  406.     /**
  407.      * @Route("/add-to-wishlist/{id}", name="app_add_to_wishlist")
  408.      */
  409.     public function likesAction($idLikesService $likesService)
  410.     {
  411.         $data = array(
  412.             'status' => false,
  413.             'message' => ''
  414.         );
  415.         $product $this->getDoctrine()->getRepository(Product::class)
  416.             ->find($id);
  417.         if(!$product){
  418.             $data['message'] = "product doesn't exist";
  419.         }
  420.         else{
  421.             $result $likesService->addRemoveLike($product$this->getUser());
  422.             if($result){
  423.                 $data['status'] = true;
  424.                 $data['isInWishlist'] = $result['status'];
  425.                 $data['count'] = $result['count'];
  426.                 $data['cartProductPrice'] = $product->getPrice();
  427.             }
  428.             else{
  429.                 $data['message'] = "something went wrong with like service";
  430.             }
  431.         }
  432.         return $this->respond($data);
  433.     }
  434.     private function prepareFilters($filters)
  435.     {
  436.         $notFound = !empty($filters);
  437.         $prepared = array(
  438.             'page' => 1,
  439.             'sort' => $this->getParameter('default_sort'),
  440.             'filters' => array(),
  441.         );
  442.         $filterArr explode(';'$filters);
  443. //        dump($filterArr);
  444. //        die();
  445.         $filterTexts = array();
  446.         foreach ($filterArr as $filterItem){
  447.             if(strpos($filterItem,'page') !== false) {
  448.                 $prepared['page'] = (int)str_replace('page='''$filterItem);
  449.                 $notFound false;
  450.                 continue;
  451.             }
  452.             if(strpos($filterItem,'sort') !== false) {
  453.                 $prepared['sort'] = str_replace('sort='''$filterItem);
  454.                 $notFound false;
  455.                 continue;
  456.             }
  457.             $filterParts explode('='$filterItem);
  458.             if(count($filterParts) == 2){
  459.                 if(empty($filterTexts[$filterParts[0]])){
  460.                     $filterTexts[$filterParts[0]] = array();
  461.                 }
  462.                 $filterTexts[$filterParts[0]] = explode(','$filterParts[1]);
  463.                 $notFound false;
  464.             }
  465.         }
  466.         if($filterTexts){
  467.             foreach ($filterTexts as $systemName=>$filter){
  468.                 $values $this->getDoctrine()->getRepository(ProductSpecificationValue::class)
  469.                     ->findBySystemNamesAndSpecSystemName($systemName,$filter);
  470.                 $prepared['filters'] = array_merge($prepared['filters'], array_keys($values));
  471.             }
  472.         }
  473.         if($notFound) return null;
  474.         return $prepared;
  475.     }
  476.     private function prepareFilterValues($specifications)
  477.     {
  478.         $prepared = array();
  479.         foreach ($specifications as $id => $specification){
  480.             $prepared[$id] = array();
  481.             foreach ($specification['values'] as $value){
  482.                 $prepared[$id][] = $value['id'];
  483.             }
  484.         }
  485.         return $prepared;
  486.     }
  487.     private function prepareFilterTexts($specifications$locale 'ru')
  488.     {
  489.         $prepared = array();
  490.         foreach ($specifications as $specification){
  491.             foreach ($specification['values'] as $value){
  492.                 $prepared[$value['id']] = array(
  493.                     'specification' => $specification['translations'][$locale]['title'],
  494.                     'value' => $value['translations'][$locale]['value']
  495.                 );
  496.             }
  497.         }
  498.         return $prepared;
  499.     }
  500.     private function prepareSeoTitle($filterTexts,$page)
  501.     {
  502.         $seoTitle ' - ';
  503.         if(count($filterTexts)){
  504.             $seoTitles = array();
  505.             foreach ($filterTexts as $filterText){
  506.                 if(empty($seoTitles[$filterText['specification']])){
  507.                     $seoTitles[$filterText['specification']] = array();
  508.                 }
  509.                 $seoTitles[$filterText['specification']][] = $filterText['value'];
  510.             }
  511.             //        dump($seoTitles);die();
  512.             foreach ($seoTitles as $specification => $seoValues){
  513.                 $seoTitle .= $specification ': ' implode(", "$seoValues). '; ';
  514.             }
  515.         }
  516.         if($page 1)
  517.             $seoTitle .= 'Страница '.$page;
  518.         $seoTitle ' 'trim($seoTitle,'; ');
  519.         return $seoTitle == ' -' '' $seoTitle;
  520.     }
  521.     private function prepareFilterStr($filterStr)
  522.     {
  523.         $filterStr trim(explode('page=',$filterStr)[0],';');
  524.         $filterStr trim(explode('sort=',$filterStr)[0],';');
  525.         return $filterStr;
  526.     }
  527.     private function prepareFilterNextPageText($filterStr$filters$last)
  528.     {
  529.         if ($filters['page'] and $filters['page'] != $last){
  530.             $filters['page'] += 1;
  531.             if($filterStr)
  532.                 $filterStr .= ';page='.$filters['page'];
  533.             else
  534.                 $filterStr .= 'page='.$filters['page'];
  535.         }
  536.         if($filters['sort'] and $filters['sort'] != $this->getParameter('default_sort')){
  537.             if($filterStr)
  538.                 $filterStr .= ';sort='.$filters['sort'];
  539.             else
  540.                 $filterStr .= 'sort='.$filters['sort'];
  541.         }
  542.         return $filterStr;
  543.     }
  544.     /**
  545.      * @Route("/add-view/{id}", name="app_add_view")
  546.      */
  547.     public function viewProductAction($id)
  548.     {
  549.         $data = array(
  550.             'status' => false,
  551.             'message' => ''
  552.         );
  553.         $product $this->getDoctrine()->getRepository(Product::class)
  554.             ->find($id);
  555.         if(!$product){
  556.             $data['message'] = "product doesn't exist";
  557.         }
  558.         else{
  559.             $views $product->getViews();
  560.             $product->setViews($views 1);
  561.             $em $this->getDoctrine()->getManager();
  562.             $em->persist($product);
  563.             $em->flush();
  564.             $data['status'] = true;
  565.         }
  566.         return $this->respond($data);
  567.     }
  568.     /**
  569.      * @Route("/search", name="app_product_search", methods={"POST"})
  570.      */
  571.     public function productSearchAction(Request $requestSearchService $searchService)
  572.     {
  573.         $search $search_str $searchService->sanitaze($request->request->get('value'));
  574.         file_put_contents('search_log.txt'$search."\n"FILE_APPEND);
  575.         $categoryResults $searchService->getCategoryResults($search);
  576.         $productResults $searchService->getProductResults($search);
  577.         
  578.         if(!$productResults)  {
  579.             $search explode(' '$search);
  580.             $search implode('|'$search);
  581.             $productResults $searchService->getProductResults($search);
  582.         }
  583.         $content $this->renderView('frontend/search/popup.html.twig', [
  584.             'productResults' => $productResults,
  585.             'categoryResults' => $categoryResults,
  586.             'search_str' => $search_str,
  587.         ]);
  588.         $response = new Response;
  589.         $response->setContent($content);
  590.         return $response;
  591.     }
  592.     /**
  593.      * @Route("/search-filters-apply/{search}/{sort}", name="app_search_filters_apply")
  594.      */
  595.     public function searchFiltersApplyAction($search$sortRequest $request)
  596.     {
  597.         $filterStr $this->filtersApply($request$sort);
  598.         return $this->redirectToRoute('app_product_search_result', ['search' => $search'filters' => $filterStr]);
  599.     }
  600.     /**
  601.      * @Route("/search/{search}/{filters}", name="app_product_search_result", defaults={"search": "", "filters": ""})
  602.      */
  603.     public function productSearchResultAction(Request $requestSearchService $searchServiceCartManager $cartManager$search ''$filters '')
  604.     {
  605.         $filterStr $filters;
  606.         $filters $this->prepareFilters($filters);
  607.         $count = (int)$this->getParameter('product_on_page');
  608.         $specifications $this->getDoctrine()->getRepository(ProductSpecification::class)
  609.             ->findByValuesIds($filters['filters']);
  610.         $filtersPrepared $this->prepareFilterValues($specifications);
  611.         $search $searchService->sanitaze($search ? : $request->query->get('query'));
  612.         $productIdsUnLimited $searchService->getProductIds($search);
  613.         $productQuery $searchService->getProductQuery($search$filtersPrepared);
  614.         
  615.         $products $productQuery
  616.             ->addOption('max_matches'SearchService::MAX_MATCHES)
  617.             ->setFirstResult(($filters['page']-1) * $count)
  618.             ->setMaxResults($count)
  619.             ->getResults();
  620.         if(!sizeof($products)) {
  621.             $productQuery $searchService->getProductVendorCodeQuery($search);
  622.             $products $productQuery
  623.                 ->setFirstResult(($filters['page']-1) * $count)
  624.                 ->setMaxResults($count)
  625.                 ->getResults();
  626.         }
  627.         $last = (int)ceil($productQuery->getTotalFound()/$count);
  628.         $count = ($last <= $filters['page'] + ) ? $productQuery->getTotalFound() % $count $count;
  629.         $cart $cartManager->getCurrentCart($this->getUser());
  630.         $cartProducts $this->getDoctrine()->getRepository(Product::class)
  631.             ->getAllCartProductsIndexById($cart->getId());
  632.         $productsSpecValues $this->getDoctrine()->getRepository(ProductSpecificationValue::class)
  633.             ->findAllByProducts(array_column($productIdsUnLimited'id'));
  634.         $productsSpecValuesCount $this->getDoctrine()->getRepository(ProductHasProductSpecificationValue::class)
  635.             ->countAllProductsBySpecificationValues(array_keys($productIdsUnLimited));
  636.         $specifications $this->prepareSpecificationArray($productsSpecValues$filters['filters'],$productsSpecValuesCount);
  637.         $specifications array_filter($specifications, function($el) { return !empty($el['values']); });
  638.         $filterStr $this->prepareFilterStr($filterStr);
  639.         $filterFilterNextPageStr $this->prepareFilterNextPageText($filterStr$filters$last);
  640.         $params = [
  641.             'search' => $search,
  642.             'products' => $products,
  643.             'filters' => $filters,
  644.             'filtersStr' => $filterStr,
  645.             'filterFilterNextPageStr' => $filterFilterNextPageStr,
  646.             'count' => $count,
  647.             'last' => $last,
  648.             'current' => $filters['page'],
  649.             'orderProducts' => array_keys($cartProducts),
  650.             'specifications' => $specifications,
  651.         ];
  652.         if($request->isXmlHttpRequest()) {
  653.             $params['filtersStr'] = $filterFilterNextPageStr;
  654.             $data = [
  655.                 'products' => $this->renderView('frontend/search/list_items.html.twig'$params),
  656.                 'pagination' => $this->renderView('frontend/search/pagination.html.twig', [
  657.                     'filters'=> $filterStr,
  658.                     'search' => $search,
  659.                     'current'=> $filters['page'],
  660.                     'last' => $last,
  661.                 ]),
  662.                 'buttonCount' => $filters['page'] != $last $count 0,
  663.             ];
  664.             return $this->respond($data);
  665.         }
  666.         
  667.         return $this->render('frontend/search/index.html.twig'$params);
  668.     }
  669.     /**
  670.      * @Route("/cover/{slug}", name="app_old_covers_reidirect")
  671.      */
  672.     public function oldCoversRedirectAction($slug)
  673.     {
  674.         $product $this->getDoctrine()->getRepository(Product::class)
  675.             ->findPartialByOldSlug($slug);
  676.         $url = ($product) ? $this->generateUrl('app_product_show',array('slug'=>$product->translate()->getSlug()))
  677.             : $this->generateUrl('app_homepage');
  678.         return $this->redirect($url301);
  679.     }
  680.     /**
  681.      * @Route("/phone/{slug}", name="app_old_phones_reidirect")
  682.      */
  683.     public function oldPhonesRedirectAction($slug)
  684.     {
  685.         $category $this->getDoctrine()->getRepository(ProductCategory::class)
  686.             ->findPartialByOldSlug($slug);
  687.         $url = ($category) ? $this->generateUrl('app_category_show',array('slug'=>$category->getSlug()))
  688.             : $this->generateUrl('app_homepage');
  689.         return $this->redirect($url301);
  690.     }
  691.     private function filtersApply($request$sort)
  692.     {
  693.         $filterIds $request->request->get('specifications');
  694. //        dump($filterIds); die();
  695. //        foreach ($filterIds as $filterId){
  696. //            if(is_string($filterId)){
  697. //                return $this->redirectToRoute('app_category_show', ['slug' => $filterId]);
  698. //            }
  699. //        }
  700.         $filtersMin $this->getDoctrine()->getRepository(ProductSpecificationValue::class)
  701.             ->findByIdsMinimized($filterIds);
  702.         $filters = array();
  703.         foreach ($filtersMin as $filterRow){
  704.             if(empty($filters[$filterRow['productSpecification']['systemName']])){
  705.                 $filters[$filterRow['productSpecification']['systemName']] = array();
  706.             }
  707.             $filters[$filterRow['productSpecification']['systemName']][] = $filterRow['systemName'];
  708.         }
  709. //        $filters = array_column($filtersMin, 'systemName');
  710.         $filterStr '';
  711.         foreach($filters as $key => $filter){
  712.             if($filter)
  713.                 $filterStr .= $key.'='.implode(","$filter).';';
  714.         }
  715.         $filterStr rtrim($filterStr";");
  716. //        dump($filtersMin);
  717. //        dump($filterStr); die();
  718. //        $filterStr = ($filters) ? implode(";", $filters) : '';
  719.         if($sort and $sort != $this->getParameter('default_sort')){
  720.             if($filterStr)
  721.                 $filterStr .= ';sort='.$sort;
  722.             else
  723.                 $filterStr 'sort='.$sort;
  724.         }
  725.         return $filterStr;
  726.     }
  727.     private function seoCategoryData($category,$seoFormulaService)
  728.     {
  729.         $seo = array();
  730.         $seoFormula $category->getTreeSeoFormula();
  731.         if(!$seoFormula){
  732.             $seoFormula $this->getDoctrine()->getRepository(SeoFormula::class)
  733.                 ->findMainFormula()[0];
  734.         }
  735.         $categoryTitleFields = array(
  736.             'title' => $category->translate()->getTitle(),
  737.             'titleForProductCyrillic' => $category->translate()->getTitleForProductCyrillic(),
  738.         );
  739.         $seo['title'] = $seoFormulaService->getTitle($seoFormula,$categoryTitleFields);
  740.         $categoryDescriptionFields = array(
  741.             'title' => $category->translate()->getTitle(),
  742.             'h1' => $category->translate()->getH1(),
  743.         );
  744.         $seo['description'] = $seoFormulaService->getDescription($seoFormula,$categoryDescriptionFields);
  745.         return $seo;
  746.     }
  747.     private function seoProductData($product,$seoFormulaService)
  748.     {
  749.         $seo = array();
  750.         $seoFormula $this->getDoctrine()->getRepository(SeoFormula::class)
  751.             ->findMainFormula()[0];
  752.         $productTitleFields = array(
  753.             'title' => $product->translate()->getTitle(),
  754.         );
  755.         $seo['title'] = $seoFormulaService->getTitle($seoFormula,$productTitleFields);
  756.         $productDescriptionFields = array(
  757.             'title' => $product->translate()->getTitle(),
  758.         );
  759.         $seo['description'] = $seoFormulaService->getDescription($seoFormula,$productDescriptionFields);
  760.         return $seo;
  761.     }
  762.     private function activePagesInit($request$filters)
  763.     {
  764.         $activePages = array();
  765.         $firstPage 1;
  766.         $referer $request->server->get('HTTP_REFERER');
  767.         if(str_contains($referer'page=')){
  768.             $str substr($refererstrrpos($referer,'/') + 1);
  769.             $firstPage $this->prepareFilters($str)['page'];
  770.         }
  771.         if($firstPage != $filters['page']){
  772.             for ($i $firstPage$i < (int)$filters['page']; $i++ ){
  773.                 $activePages[] = $i;
  774.             }
  775.         }
  776.         return $activePages;
  777.     }
  778.     private function productsCountInit($filters$count$allProductsCount$last)
  779.     {
  780.         $productsCount $count;
  781.         if($last <= $filters['page'] + 1){
  782.             if($last $filters['page'] + 1)
  783.                 $productsCount false;
  784.             else
  785.                 $productsCount = ($allProductsCount['1'] % $count) ? $allProductsCount['1'] % $count $count;
  786.         }
  787.         return $productsCount;
  788.     }
  789.     private function getProducts($category$filters$specifications$count)
  790.     {
  791.         $products = array();
  792.         $filtersPrepared $this->prepareFilterValues($specifications);
  793.         if($category->checkIfGroupsIn()){
  794.             $products['productsLimited'] = $this->getDoctrine()->getRepository(Product::class)
  795.                 ->findProductsByCategoryMinimized($category->getId(), $filtersPrepared$filters['sort'],$filters['page'] - 1$counttrue$category->getDisablePatternSortInCategoryTree());
  796.             $products['allProductsCount'] = $this->getDoctrine()->getRepository(ProductGroup::class)
  797.                 ->countProductsByCategoryFiltered($category->getId(),$filtersPrepared);
  798.             $products['productIdsUnLimited'] = $this->getDoctrine()->getRepository(ProductGroup::class)
  799.                 ->findUnlimitedGroupsIds($category->getId());
  800.         }
  801.         else{
  802.             $products['productsLimited'] = $this->getDoctrine()->getRepository(Product::class)
  803.                 ->findProductsByCategoryMinimized($category->getId(), $filtersPrepared$filters['sort'],$filters['page'] - 1$count,false$category->getDisablePatternSortInCategoryTree());
  804.             $products['allProductsCount'] = $this->getDoctrine()->getRepository(Product::class)
  805.                 ->countProductsByCategoryFiltered($category->getId(),$filtersPrepared);
  806.             $products['productIdsUnLimited'] = $this->getDoctrine()->getRepository(Product::class)
  807.                 ->findUnlimitedProductsIds($category->getId());
  808.         }
  809. //        dump($products); die();
  810.         return $products;
  811.     }
  812.     private function getModels($product)
  813.     {
  814.         $models = array();
  815.         $group $product->getGroup();
  816.         if ($group){
  817. //            foreach ($group->getSpecificationValues() as $specificationValue){
  818. //                $value = $specificationValue->getProductSpecificationValue();
  819. //                if($value->getShowOnWebsite()){
  820. //                    $models[$specificationValue->getId()] = array(
  821. //                        'label'=> $value->translate()->getValue(),
  822. //                        'isInStock'=> false,
  823. //                        'link'=> 'javascript:void(0)',
  824. //                    );
  825. //                }
  826. //            }
  827.             foreach ($group->getProducts() as $groupProduct){
  828.                 $value $groupProduct->getCreateModelSpecificationValue();
  829. //                if ($this->getUser() and $this->getUser()->getUsername() == 'admin'){
  830. //                    dump($value);
  831. //                }
  832.                 $index $value->getProductSpecificationValue()->getPosition() ? $value->getProductSpecificationValue()->getPosition() : $value->getId();
  833.                 $models[$index] = array(
  834.                     'label'=> $value->getProductSpecificationValue()->translate()->getValue(),
  835.                     'isInStock'=> $groupProduct->getInStock(),
  836.                     'active'=> ($product->getId()==$groupProduct->getId()),
  837.                     'link'=> $this->generateUrl(
  838.                         'app_product_show', array('slug'=>$groupProduct->getSlug())
  839.                     ),
  840.                 );
  841.             }
  842.             ksort($models);
  843. //            if ($this->getUser() and $this->getUser()->getUsername() == 'admin'){
  844. //                dump($models); die();
  845. //            }
  846.         }
  847.         return $models;
  848.     }
  849.     private function getInfo($product$locale)
  850.     {
  851.         $info null;
  852.         if($product->getType() and $product->getType()->getInfo()
  853.         and $product->getType()->getInfo()->getInfoItems()){
  854.             $info = array(
  855.                 'title'=>$product->getType()->getInfo()->getTitle(),
  856.                 'items'=>array()
  857.             );
  858.             foreach ($product->getType()->getInfo()->getInfoItems() as $item){
  859.                 if($item->translate($locale)->getValue()){
  860.                     $info $this->getInfoItem($info$item$locale);
  861.                 }
  862.                 else{
  863.                     $info $this->getInfoItem($info$item'ru');
  864.                 }
  865.             }
  866.         }
  867.         return $info;
  868.     }
  869.     private function getInfoItem($info$item$locale){
  870.         $values explode('/',$item->translate($locale)->getValue());
  871.         if(count($values) == and $item->translate($locale)->getParameter()){
  872.             $info['items'][] = array(
  873.                 'label'=>$item->translate($locale)->getParameter(),
  874.                 'min'=>$values[0],
  875.                 'max'=>$values[1],
  876.             );
  877.         }
  878.         return $info;
  879.     }
  880.     private function getProductGallery($product)
  881.     {
  882.         $gallery = array();
  883.         if($product->hasGalleryImages()){
  884.             $gallery $this->getGalleryItems($product->getGalleryImages());
  885.         }
  886.         if($product->getPatternCategoryConstructor() and
  887.             $product->getPatternCategoryConstructor()->hasGalleryImages()){
  888.             $gallery array_merge($gallery,
  889.                 $this->getGalleryItems($product->getPatternCategoryConstructor()->getGalleryImages()));
  890.         }
  891.         if($product->isCase() and
  892.             $product->getPatternCategoryConstructor() and
  893.             $product->getPatternCategoryConstructor()->getPattern() and
  894.             $product->getPatternCategoryConstructor()->getPattern()->hasGalleryImages()){
  895.             $gallery array_merge($gallery,
  896.                 $this->getGalleryItems($product->getPatternCategoryConstructor()->getPattern()->getGalleryImages()));
  897.         }
  898.         if($product->getType() and
  899.             $product->getType()->hasGalleryImages()){
  900.             $gallery array_merge($gallery,
  901.                 $this->getGalleryItems($product->getType()->getProductsGalleryImages()));
  902.         }
  903.         return $gallery;
  904.     }
  905.     private function getGalleryItems($gallery){
  906.         $galleryItems = array();
  907.         foreach ($gallery as $galleryImage){
  908.             if($galleryImage->getShowOnWebsite())
  909.                 $galleryItems[] = $galleryImage;
  910.         }
  911.         return $galleryItems;
  912.     }
  913. }