src/Controller/FrontendConstructorController.php line 278

Open in your IDE?
  1. <?php
  2. // src/Controller/DefaultController.php
  3. namespace App\Controller;
  4. use App\Entity\ProductCategory;
  5. use App\Entity\ProductConstructor;
  6. use App\Entity\ProductSpecificationValue;
  7. use App\Entity\ProductType;
  8. use App\Entity\SeoFormula;
  9. use App\Entity\StaticPage;
  10. use App\Repository\FaqRepository;
  11. use App\Services\SeoFormulaService;
  12. use App\ZorrovAdmin\ApiBundle\Services\ConstructorCreateImageService;
  13. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. use Symfony\Contracts\Translation\TranslatorInterface;
  17. class FrontendConstructorController extends AbstractController
  18. {
  19.     /**
  20.      * @Route("/app/constructor/{main}/{category}/{type}", name="app_constructor")
  21.      */
  22.     public function constructorCategoryTypection(FaqRepository $faqRepository$main=null$category=null$type=nullRequest $request)
  23.     {
  24. //        // If this is the first visit to the site, the default language is set to 'ua'
  25. //        if (!$request->hasPreviousSession() and $request->getLocale() == 'ru') {
  26. //            return $this->redirectToRoute('app_constructor', ['_locale' => 'ua', 'main'=>$main,'category'=>$category,'type'=>$type]);
  27. //        }
  28.         $staticPage $this->getDoctrine()->getRepository(StaticPage::class)->findOneBy(['systemName' => 'constructor']);
  29.         $faqs =  $faqRepository->getByPage('constructor');
  30.         $typeObject $this->getDoctrine()->getRepository(ProductType::class)
  31.             ->findBySystemName($type);
  32.         $categoryObj $this->getDoctrine()->getRepository(ProductCategory::class)
  33.             ->findOneBy(array('slug'=>$category));
  34.         //test construсtor temprorary fix
  35.         $url 'app_constructor';
  36.         $template 'frontend/constructor/constructor.html.twig';
  37.         if($main == 'caps'
  38.             or $main == 'mirror'
  39.             or $main == 'badges'
  40.             or $main == 'puzzle'
  41.             or $main == 'christmas-toys'
  42.             or $main == 'paintings'
  43.             or $main == 'covers'
  44.             or $main == 'apron'
  45.             or $main == 'mouse-pad'
  46.             or $main == 'pillows'
  47.             or $main == 'holders'
  48.             or $main == 'notebook'
  49.             or $main == 'bags'
  50.             or $main == 'magnets'
  51. //            or $main == 'thermos'
  52.             or $main == 'thermal-stickers'
  53.             or $main == 'tattoo'
  54.             or $main == 'longsleeves'
  55.             or $main == 'hoodie-sweatshirts'
  56.             or $main == 't-shirts'
  57.             or $main == 'case'
  58.             or $main == null
  59.             or ($main == 'mugs' and $category == 'test-cup')
  60.         ){
  61.             $url 'app_canvas_constructor';
  62.             $template 'frontend/constructor/canvas-constructor.html.twig';
  63.         }
  64.         //end of test construсtor temprorary fix
  65.         if($category and $type){
  66.             $constructor $this->getDoctrine()->getRepository(ProductConstructor::class)->
  67.             findOneByCategoryAndType($category,$type);
  68.             if(!empty($constructor) and !$constructor[0]->getInStock()){
  69.                 return $this->redirect($this->generateUrl($url));
  70.             }
  71.         }
  72.         $categoryTitle '';
  73.         if($typeObject and $main != 'case'){
  74.             $metaTitle = ($typeObject->translate()->getTitleForTypePage()) ? $typeObject->translate()->getTitleForTypePage() : $typeObject->translate()->getTitle();
  75.             $metaDescription = ($typeObject->translate()->getSeoDescription())? $typeObject->translate()->getSeoDescription() : $metaTitle;
  76.         }
  77.         elseif ($main == 'case') {
  78.             if($categoryObj){
  79.                 $categoryTitle $categoryObj->getParent()->translate()->getTitleForProduct().' '.$categoryObj->translate()->getTitleForProduct();
  80.                 $metaTitle '【Создать Свой Чехол на Телефон '.$categoryTitle.'】 Конструктор Чехлов | Сделать Чехол со Своим Дизайном, Принтом, Фото Онлайн в Украине';
  81.                 $metaDescription 'Создайте свой уникальный чехол на телефон '.$categoryTitle.' при помощи специального конструктора на сайте zorrov.com! Вы можете использовать любой дизайн, принт, фото, чтобы подчеркнуть свою индивидуальность!';
  82.             }
  83.         }
  84.         else{
  85.             $metaTitle null;
  86.             $metaDescription null;
  87.         }
  88.         $canonicalUrl $this->generateUrl($url);
  89.         if($category and $main != 'case'){
  90.             if($categoryObj and $categoryObj->getParent() and
  91.                 !$categoryObj->getParent()->getShowChildrenOnWebsite()){
  92.                 $canonicalUrl $this->generateUrl('app_constructor_category', array('slug'=>$categoryObj->getParent()->getSlug()));
  93.             }
  94.             else{
  95.                 $canonicalUrl $this->generateUrl('app_constructor_category', array('slug'=>$category));
  96.             }
  97.         }
  98.         return $this->render($template, [
  99.             'metaTitle'=>$metaTitle,
  100.             'metaDescription'=>$metaDescription,
  101.             'main'=>$main,
  102.             'category'=>$category,
  103.             'categoryTitle'=>$categoryTitle,
  104.             'staticPage'=>$staticPage,
  105.             'type'=>$type,
  106.             'canonicalUrl'=>$canonicalUrl,
  107.             'faqs'=>$faqs
  108.         ]);
  109.     }
  110.     /**
  111.      * @Route("/app/test/constructor/{main}/{category}/{type}", name="app_canvas_constructor")
  112.      */
  113.     public function testConstructorCategoryTypection(FaqRepository $faqRepository$main=null$category=null$type=null)
  114.     {
  115.         $staticPage $this->getDoctrine()->getRepository(StaticPage::class)->findOneBy(['systemName' => 'constructor']);
  116.         $faqs =  $faqRepository->getByPage('constructor');
  117.         $typeObject $this->getDoctrine()->getRepository(ProductType::class)
  118.             ->findBySystemName($type);
  119.         $categoryObj $this->getDoctrine()->getRepository(ProductCategory::class)
  120.             ->findOneBy(array('slug'=>$category));
  121.         if($category and $type){
  122.             $constructor $this->getDoctrine()->getRepository(ProductConstructor::class)->
  123.             findOneByCategoryAndType($category,$type);
  124.             if(!empty($constructor) and !$constructor[0]->getInStock()){
  125.                 return $this->redirect($this->generateUrl('app_canvas_constructor'));
  126.             }
  127.         }
  128.         $categoryTitle '';
  129.         if($typeObject and $main != 'case'){
  130.             $metaTitle = ($typeObject->translate()->getTitleForTypePage()) ? $typeObject->translate()->getTitleForTypePage() : $typeObject->translate()->getTitle();
  131.             $metaDescription = ($typeObject->translate()->getSeoDescription())? $typeObject->translate()->getSeoDescription() : $metaTitle;
  132.         }
  133.         elseif ($main == 'case') {
  134.             if($categoryObj){
  135.                 $categoryTitle $categoryObj->getParent()->translate()->getTitleForProduct().' '.$categoryObj->translate()->getTitleForProduct();
  136.                 $metaTitle '【Создать Свой Чехол на Телефон '.$categoryTitle.'】 Конструктор Чехлов | Сделать Чехол со Своим Дизайном, Принтом, Фото Онлайн в Украине';
  137.                 $metaDescription 'Создайте свой уникальный чехол на телефон '.$categoryTitle.' при помощи специального конструктора на сайте zorrov.com! Вы можете использовать любой дизайн, принт, фото, чтобы подчеркнуть свою индивидуальность!';
  138.             }
  139.         }
  140.         else{
  141.             $metaTitle null;
  142.             $metaDescription null;
  143.         }
  144.         $canonicalUrl $this->generateUrl('app_canvas_constructor');
  145.         if($category and $main != 'case'){
  146.             if($categoryObj and $categoryObj->getParent() and
  147.                 !$categoryObj->getParent()->getShowChildrenOnWebsite()){
  148.                 $canonicalUrl $this->generateUrl('app_constructor_category', array('slug'=>$categoryObj->getParent()->getSlug()));
  149.             }
  150.             else{
  151.                 $canonicalUrl $this->generateUrl('app_constructor_category', array('slug'=>$category));
  152.             }
  153.         }
  154.         return $this->render('frontend/constructor/canvas-constructor.html.twig', [
  155.             'metaTitle'=>$metaTitle,
  156.             'metaDescription'=>$metaDescription,
  157.             'main'=>$main,
  158.             'category'=>$category,
  159.             'categoryTitle'=>$categoryTitle,
  160.             'staticPage'=>$staticPage,
  161.             'type'=>$type,
  162.             'canonicalUrl'=>$canonicalUrl,
  163.             'faqs'=>$faqs
  164.         ]);
  165.     }
  166.     /**
  167.      * @Route("/constructor-categories/", name="app_constructor_categories")
  168.      */
  169.     public function constructorCategoriesAction(SeoFormulaService $seoFormulaService)
  170.     {
  171.         $categories $this->getDoctrine()->getRepository(ProductCategory::class)
  172.             ->findTopCategoriesForConstructorMenu();
  173.         $staticPage $this->getDoctrine()->getRepository(StaticPage::class)->findOneBy(array('systemName'=>'constructor-categories'));
  174.         return $this->render('frontend/constructor/categories.html.twig', [
  175.             'seo'=>$staticPage,
  176.             'categories'=>$categories,
  177.         ]);
  178.     }
  179.     /**
  180.      * @Route("/constructor-category/{slug}/{filters}", name="app_constructor_category")
  181.      */
  182.     public function constructorCategoryAction($slug,
  183.                                               SeoFormulaService $seoFormulaService,
  184.                                               TranslatorInterface $translator,
  185.                                               $filters '')
  186.     {
  187.         $category $this->getDoctrine()->getRepository(ProductCategory::class)
  188.             ->findOneBy(array('slug'=>$slug));
  189.         $main $category->getMain()->getSlug();
  190.         $descedants $category->getDescendants();
  191.         $descedantIds = array();
  192.         foreach ($descedants as $descedant){
  193.             $descedantIds[] = $descedant->getId();
  194.         }
  195.         $filterStr $filters;
  196. //        dump($filterStr); die();
  197.         $filters $this->prepareFilters($filters);
  198.         if(!$filters)
  199.             throw $this->createNotFoundException('Filters does not exist');
  200.         $constructors $this->getDoctrine()->getRepository(ProductConstructor::class)
  201.             ->findByCategoryIds($descedants);
  202.         $constructorProducts = array();
  203.         $catTitle str_replace($translator->trans('constructor.case_for',[],'translation'), '',$category->translate()->getH1());
  204.         $dropshipper = ($this->getUser() and  $this->getUser()->getIsDropShipper());
  205. //        if ($this->getUser() and $this->getUser()->getUsername()=='admin'){
  206. //            dump($constructors); die();
  207. //        }
  208.         $typeIds = array();
  209.         foreach ($constructors as $constructor){
  210. //                $element = $constructors[$innerCategory['category']->getSlug()];
  211.             $preview $constructor->getPreview();
  212.             if(!$preview){
  213.                 if($constructor->getConstructorBackground()){
  214.                     $preview $constructor->getConstructorBackground();
  215.                 }
  216.                 else{
  217.                     $preview $constructor->getCategory()->getConstructorBackground();
  218.                 }
  219.             }
  220.             $type $constructor->getType();
  221.             $typeIds[] = $type->getId();
  222.             $title = ($type->translate()->getTitleForTypePage()) ?
  223.                 str_replace('%category%'$catTitle,$type->translate()->getTitleForTypePage()) :
  224.                 $type->translate()->getTitle();
  225.             if($dropshipper and $type->getDropshipperConstructorPrice()){
  226.                 $price = (int)round($type->getDropshipperConstructorPrice(),0);
  227.                 $originalPrice $price;
  228.             }
  229.             else{
  230.                 $price = (int)round($type->getConstructorPrice(),0);
  231.                 $originalPrice = (int)round($type->getConstructorOriginalPrice(),0);
  232.             }
  233.             $secondPreview '';
  234.             if(count($type->getConstructorGalleryImages())){
  235.                 $secondPreview $type->getConstructorGalleryImages()->first()->getImage();
  236.             }
  237.             $constructorProducts[] = array(
  238.                 'id' => $constructor->getId(),
  239.                 'preview' => $preview,
  240.                 'secondPreview' => $secondPreview,
  241.                 'inStock' => $constructor->getInStock(),
  242.                 'title' => $title,
  243.                 'link' => $this->generateUrl('app_constructor_product',array('id'=>$constructor->getId())),
  244.                 'price' => $price,
  245.                 'originalPrice' => $originalPrice,
  246.                 'constructorLink' => $this->generateUrl('app_constructor',
  247.                     array('main'=>$main,'category'=>$constructor->getCategory()->getSlug(),'type'=>$type->getSystemName())),
  248.             );
  249.         }
  250. //        dump($typeIds);
  251. //        dump($descedantIds); die();
  252. //        $productsSpecValues =
  253. //        $productsSpecValuesCount = $productHasSpecificationValueRepository->countAllProductsBySpecificationValues($produ
  254.         $productsSpecValues $this->getProductSpecificationValuesForConstructorProduct($descedantIds,$typeIds);
  255.         $specifications $this->prepareSpecificationArray($productsSpecValues$filters['filters'], $constructors);
  256.         dump($specifications); die();
  257.         $seo $this->seoConstructorCategoryData($category,$seoFormulaService);
  258. //        dump($constructorProducts); die();
  259.         $filterStr $this->prepareFilterStr($filterStr);
  260.         return $this->render('frontend/constructor/category.html.twig', [
  261.             'seo'=>$seo,
  262.             'category'=>$category,
  263.             'filters' => $filters,
  264.             'filterStr' => $filterStr,
  265.             'constructorProducts'=>$constructorProducts,
  266.         ]);
  267.     }
  268.     /**
  269.      * @Route("/constructor-category-filters-apply/{slug}/{sort}", name="app_constructor_category_filters_apply")
  270.      */
  271.     public function constructorCategoryFiltersApplyAction($slug$sortRequest $request)
  272.     {
  273.         $filterStr $this->filtersApply($request$sort);
  274.         return $this->redirectToRoute('app_category_show', ['slug' => $slug'filters' => $filterStr]);
  275.     }
  276.     /**
  277.      * @Route("/constructor-product/{id}", name="app_constructor_product")
  278.      */
  279.     public function constructorProductAction($idRequest $requestTranslatorInterface $translator,
  280.                                              ConstructorCreateImageService $constructorService,
  281.                                              SeoFormulaService $seoFormulaService)
  282.     {
  283.         $constructor $this->getDoctrine()->getRepository(ProductConstructor::class)
  284.             ->find($id);
  285.         if(!$constructor){
  286.             throw $this->createNotFoundException('The constructor does not exist');
  287.         }
  288.         $type $constructor->getType();
  289.         $category $constructor->getCategory();
  290.         if(!$type->getShowOnWebsite()){
  291.             return $this->redirect($this->generateUrl('app_homepage'));
  292.         }
  293.         $main $category->getMain()->getSlug();
  294.         $title $constructorService->createPreviewTitle($category$type$request->getLocale());
  295.         $catTitle str_replace($translator->trans('constructor.case_for',[],'translation'), '',$category->translate()->getH1());
  296.         $metaTitle = ($type->translate()->getTitleForTypePage()) ? $type->translate()->getTitleForTypePage() : $type->translate()->getTitle();
  297.         $metaTitle str_replace('%category%'$catTitle$metaTitle);
  298.         $preview $constructor->getPreview();
  299.         $dropshipper = ($this->getUser() and  $this->getUser()->getIsDropShipper());
  300.         if($dropshipper and $type->getDropshipperConstructorPrice()){
  301.             $price $type->getDropshipperConstructorPrice();
  302.             $originalPrice $price;
  303.         }
  304.         else{
  305.             $price $type->getConstructorPrice();
  306.             $originalPrice $type->getConstructorOriginalPrice();
  307.         }
  308.         if(!$preview){
  309.             if($constructor->getConstructorBackground()){
  310.                 $preview $constructor->getConstructorBackground();
  311.             }
  312.             else{
  313.                 $preview $constructor->getCategory()->getConstructorBackground();
  314.             }
  315.         }
  316.         $wholesalePrices $type->hasWholesalePrices() ? $type->getWholesalePrices() : array();
  317.         $specificationValues $this->getConstructorProductsSpecification($category$type);
  318.         $parentCategory = ($category->getAncestors()->count()) ? $category->getAncestors()->last(): $category;
  319.         $info $this->getInfo($type$request->getLocale());
  320.         $constructorProduct = array(
  321.             'id' => $id,
  322.             'title' => $title,
  323.             'parentCategory' => $parentCategory->translate()->getTitle(),
  324.             'description' => $type->translate()->getDescription(),
  325.             'metaTitle' => $metaTitle,
  326.             'metaDescription' => ($type->translate()->getSeoDescription())? $type->translate()->getSeoDescription() : $metaTitle,
  327.             'image' => $preview,
  328.             'price' => $price,
  329.             'originalPrice' => $originalPrice,
  330.             'wholesalePrices' => $wholesalePrices,
  331.             'object' => $type,
  332.             'info' => $info,
  333.             'inStock' => $constructor->getInStock(),
  334.             'gallery' => $type->getConstructorGalleryImages(),
  335.             'constructorLink' => $this->generateUrl('app_constructor',
  336.                 array('main'=>$main,'category'=>$constructor->getCategory()->getSlug(),'type'=>$type->getSystemName())),
  337.         );
  338.         $seo $this->seoConstructorCategoryData($category,$seoFormulaService);
  339.         return $this->render('frontend/constructor/product.html.twig', [
  340.             'seo'=>$seo,
  341.             'category'=>$category,
  342.             'constructor'=>$constructorProduct,
  343.             'specificationValues'=>$specificationValues,
  344.         ]);
  345.     }
  346.     private function seoConstructorCategoryData($category,$seoFormulaService)
  347.     {
  348.         $seo = array();
  349.         $seoFormula $category->getTreeSeoFormula();
  350.         if(!$seoFormula){
  351.             $seoFormula $this->getDoctrine()->getRepository(SeoFormula::class)
  352.                 ->findMainFormula()[0];
  353.         }
  354.         $categoryTitleFields = array(
  355.             'h1' => $category->translate()->getH1(),
  356.             'title' => $category->translate()->getTitle(),
  357.             'titleForProductCyrillic' => $category->translate()->getTitleForProductCyrillic(),
  358.         );
  359.         $seo['title'] = $seoFormulaService->getTitleForCustom($seoFormula,$categoryTitleFields);
  360.         $categoryDescriptionFields = array(
  361.             'title' => $category->translate()->getTitle(),
  362.             'h1' => $category->translate()->getH1(),
  363.         );
  364.         $seo['seo_description'] = $seoFormulaService->getSeoDescriptionForCustom($seoFormula,$categoryDescriptionFields);
  365.         $categoryOnThePageFields = array(
  366.             'parentTitleForProduct' => $category->getParent() ? $category->getParent()->translate()->getTitleForProduct() : $category->translate()->getTitleForProduct(),
  367.             'titleForProduct' => $category->translate()->getTitleForProduct(),
  368.         );
  369.         $seo['h1'] = $seoFormulaService->getH1ForCustom($seoFormula,$categoryOnThePageFields);
  370.         $seo['h1_second'] = $seoFormulaService->getH1SecondForCustom($seoFormula,$categoryOnThePageFields);
  371.         $seo['description'] = $seoFormulaService->getDescriptionForCustom($seoFormula,$categoryOnThePageFields);
  372.         return $seo;
  373.     }
  374.     private function getConstructorProductsSpecification($category$type){
  375.         $specificationValues = array();
  376.         $ancestors $category->getAncestors();
  377.         $ancestors array_reverse($ancestors->toArray());
  378.         $ancestors[] = $category;
  379.         if($category->hasTreeSpecificationValues()){
  380.             $specificationValues['category'] = array();
  381.             foreach (array_reverse($ancestors) as $category){
  382.                 if(!$category->getSpecificationValues()->isEmpty()){
  383.                     foreach ($category->getSpecificationValues() as $catSpecValue){
  384.                         if($catSpecValue->getProductSpecification()->getShowOnWebsite() and $catSpecValue->getProductSpecificationValue()){
  385.                             $specificationValues['category'][$catSpecValue->getProductSpecification()->getId()] = array(
  386.                                 'specification'=>$catSpecValue->getProductSpecification()->translate()->getTitle(),
  387.                                 'values'=>array(
  388.                                     $catSpecValue->getProductSpecificationValue()->translate()->getValue(),
  389.                                 )
  390.                             );
  391.                         }
  392.                     }
  393.                 }
  394.             }
  395.             if(empty($specificationValues['category'])){
  396.                 unset($specificationValues['category']);
  397.             }
  398.         }
  399.         if($type->hasSpecificationValues()){
  400.             $specificationValues['product-type'] = array();
  401.             foreach ($type->getSpecificationValues() as $typeSpecValue){
  402.                 if($typeSpecValue->getProductSpecification()->getShowOnWebsite()) {
  403.                     $id $typeSpecValue->getProductSpecification()->getId();
  404.                     if (empty($specificationValues['product-type'][$id])) {
  405.                         $specificationValues['product-type'][$id] = array(
  406.                             'specification' => $typeSpecValue->getProductSpecification()->translate()->getTitle(),
  407.                             'values' => array(
  408.                                 $typeSpecValue->getProductSpecificationValue()->translate()->getValue(),
  409.                             )
  410.                         );
  411.                     } else {
  412.                         $specificationValues['product-type'][$id]['values'][] = $typeSpecValue->getProductSpecificationValue()->translate()->getValue();
  413.                     }
  414.                 }
  415.             }
  416.             if(empty($specificationValues['product-type'])){
  417.                 unset($specificationValues['product-type']);
  418.             }
  419.         }
  420.         return $specificationValues;
  421.     }
  422.     private function getProductSpecificationValuesForConstructorProduct($catIds$typeIds)
  423.     {
  424.         $catValues $this->getDoctrine()->getRepository(ProductSpecificationValue::class)->findAllByCategories($catIds);
  425.         $catValuesIds array_keys($catValues);
  426.         $typeValues $this->getDoctrine()->getRepository(ProductSpecificationValue::class)->findAllByTypes($typeIds);
  427.         foreach ($typeValues as $typeValue){
  428.             if(!in_array($typeValue->getId(),$catValuesIds)){
  429.                 $catValues[$typeValue->getId()] = $typeValue;
  430.             }
  431.         }
  432.         return $catValues;
  433.     }
  434.     private function getInfo($type$locale)
  435.     {
  436.         $info null;
  437.         if($type and $type->getInfo()
  438.             and $type->getInfo()->getInfoItems()){
  439.             $info = array(
  440.                 'title'=>$type->getInfo()->getTitle(),
  441.                 'items'=>array()
  442.             );
  443.             foreach ($type->getInfo()->getInfoItems() as $item){
  444.                 if($item->translate($locale)->getValue()){
  445.                     $info $this->getInfoItem($info$item$locale);
  446.                 }
  447.                 else{
  448.                     $info $this->getInfoItem($info$item'ru');
  449.                 }
  450.             }
  451.         }
  452.         return $info;
  453.     }
  454.     private function getInfoItem($info$item$locale){
  455.         $values explode('/',$item->translate($locale)->getValue());
  456.         if(count($values) == and $item->translate($locale)->getParameter()){
  457.             $info['items'][] = array(
  458.                 'label'=>$item->translate($locale)->getParameter(),
  459.                 'min'=>$values[0],
  460.                 'max'=>$values[1],
  461.             );
  462.         }
  463.         return $info;
  464.     }
  465.     private function prepareFilterStr($filterStr)
  466.     {
  467.         $filterStr trim(explode('page=',$filterStr)[0],';');
  468.         $filterStr trim(explode('sort=',$filterStr)[0],';');
  469.         return $filterStr;
  470.     }
  471.     private function prepareFilters($filters)
  472.     {
  473.         $notFound = !empty($filters);
  474.         $prepared = array(
  475.             'page' => 1,
  476.             'sort' => $this->getParameter('default_sort'),
  477.             'filters' => array(),
  478.         );
  479.         return $prepared;
  480.         $filterArr explode(';'$filters);
  481. //        dump($filterArr);
  482. //        die();
  483.         $filterTexts = array();
  484.         foreach ($filterArr as $filterItem){
  485.             if(strpos($filterItem,'page') !== false) {
  486.                 $prepared['page'] = (int)str_replace('page='''$filterItem);
  487.                 $notFound false;
  488.                 continue;
  489.             }
  490.             if(strpos($filterItem,'sort') !== false) {
  491.                 $prepared['sort'] = str_replace('sort='''$filterItem);
  492.                 $notFound false;
  493.                 continue;
  494.             }
  495.             $filterParts explode('='$filterItem);
  496.             if(count($filterParts) == 2){
  497.                 if(empty($filterTexts[$filterParts[0]])){
  498.                     $filterTexts[$filterParts[0]] = array();
  499.                 }
  500.                 $filterTexts[$filterParts[0]] = explode(','$filterParts[1]);
  501.                 $notFound false;
  502.             }
  503.         }
  504.         if($filterTexts){
  505.             foreach ($filterTexts as $systemName=>$filter){
  506.                 $values $this->getDoctrine()->getRepository(ProductSpecificationValue::class)
  507.                     ->findBySystemNamesAndSpecSystemName($systemName,$filter);
  508.                 $prepared['filters'] = array_merge($prepared['filters'], array_keys($values));
  509.             }
  510.         }
  511.         if($notFound) return null;
  512.         return $prepared;
  513.     }
  514.     private function filtersApply($request$sort)
  515.     {
  516.         $filterIds $request->request->get('specifications');
  517.         dump($filterIds); die();
  518. //        dump($filterIds); die();
  519. //        foreach ($filterIds as $filterId){
  520. //            if(is_string($filterId)){
  521. //                return $this->redirectToRoute('app_category_show', ['slug' => $filterId]);
  522. //            }
  523. //        }
  524.         $filtersMin $this->getDoctrine()->getRepository(ProductSpecificationValue::class)
  525.             ->findByIdsMinimized($filterIds);
  526.         $filters = array();
  527.         foreach ($filtersMin as $filterRow){
  528.             if(empty($filters[$filterRow['productSpecification']['systemName']])){
  529.                 $filters[$filterRow['productSpecification']['systemName']] = array();
  530.             }
  531.             $filters[$filterRow['productSpecification']['systemName']][] = $filterRow['systemName'];
  532.         }
  533. //        $filters = array_column($filtersMin, 'systemName');
  534.         $filterStr '';
  535.         foreach($filters as $key => $filter){
  536.             if($filter)
  537.                 $filterStr .= $key.'='.implode(","$filter).';';
  538.         }
  539.         $filterStr rtrim($filterStr";");
  540. //        dump($filtersMin);
  541. //        dump($filterStr); die();
  542. //        $filterStr = ($filters) ? implode(";", $filters) : '';
  543.         if($sort and $sort != $this->getParameter('default_sort')){
  544.             if($filterStr)
  545.                 $filterStr .= ';sort='.$sort;
  546.             else
  547.                 $filterStr 'sort='.$sort;
  548.         }
  549.         return $filterStr;
  550.     }
  551.     private function prepareSpecificationArray($values$filters$constructors)
  552.     {
  553.         $filters = [];
  554.         $specifications = array();
  555. //        $productsSpecValuesCountArr = $this->prepareValuesConstructorCountArray(array_keys($values),$constructors);
  556.         foreach ($values as $value){
  557.             $specification $value->getProductSpecification();
  558.             if(empty($specifications[$specification->getId()])){
  559.                 $specifications[$specification->getId()] = array(
  560.                     'title' => $specification->translate()->getTitle(),
  561.                     'position' => $specification->getPosition() ? $specification->getPosition() : 0,
  562.                     'values' => array()
  563.                 );
  564.             }
  565. //            if(!empty($productsSpecValuesCountArr[$value->getId()])){
  566.                 $specifications[$specification->getId()]['values'][$value->translate()->getValue()] = array(
  567.                     'id' => $value->getId(),
  568.                     'value' => $value->translate()->getValue(),
  569. //                    'count' => $productsSpecValuesCountArr[$value->getId()],
  570.                     'checked' => in_array($value->getId(), $filters)
  571.                 );
  572. //            }
  573.         }
  574.         $result $specifications;
  575.         foreach ($specifications as $key => $specification){
  576.             ksort($specification['values']);
  577.             $result[$key]['values'] =  $specification['values'];
  578.         }
  579.         //to sort specifications by position
  580.         $price array_column($result'position');
  581.         array_multisort($priceSORT_DESC$result);
  582.         return $result;
  583.     }
  584.     private function prepareValuesConstructorCountArray($values,$constructors)
  585.     {
  586.         $countArr = array();
  587.         dump($values);
  588.         foreach ($values as $valueId){
  589.             foreach ($constructors as $constructor){
  590.                 $type $constructor->getType();
  591.                 $contain $type->productContainsProductSpecificationValueId($valueId);
  592.                 if($contain){
  593.                     if(empty($countArr[$valueId])){
  594.                         $countArr[$valueId] = 1;
  595.                     }
  596.                     else{
  597.                         $countArr[$valueId]++;
  598.                     }
  599.                 }
  600.             }
  601.         }
  602.         dump($countArr); die();
  603.         return $countArr;
  604.     }
  605. //    public function constructorImages(
  606. //        $categorySlug,$typeName,
  607. //        ProductConstructorRepository $productConstructorRepository
  608. //    )
  609. //    {
  610. //        $constructor = $productConstructorRepository->findOneByCategoryAndType($categorySlug,$typeName);
  611. //        dump($constructor); die();
  612. //        $categories = $this->getDoctrine()->getRepository(ProductCategory::class)
  613. //            ->findCategoriesForConstructorMenu('case');
  614. //        return $this->render('frontend/parts/top_constructor_menu.html.twig', [
  615. //            'categories' => $categories
  616. //        ]);
  617. //    }
  618. }