src/Controller/CatalogController.php line 106

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\DTO\AppDTO;
  4. use App\Entity\Cat;
  5. use App\Entity\Catpage;
  6. use App\Entity\Char;
  7. use App\Entity\Cube;
  8. use App\Entity\Page;
  9. use App\Entity\Photo;
  10. use App\Entity\Prod;
  11. use App\Entity\ProdViews;
  12. use App\Event\ProdViewedEvent;
  13. use App\Func;
  14. use App\Model\Cart as ModelCart;
  15. use App\Model\Cat as ModelCat;
  16. use App\Model\Prod as ModelProd;
  17. use App\Repository\CatpageRepository;
  18. use App\Repository\CatRepository;
  19. use App\Repository\CharRepository;
  20. use App\Repository\CubeRepository;
  21. use App\Repository\PageRepository;
  22. use App\Repository\PhotoRepository;
  23. use App\Repository\ProdRepository;
  24. use App\Repository\ProdViewsRepository;
  25. use App\Service\Cart\Cart;
  26. use App\Service\Filter\Cats;
  27. use App\Service\Filter\Chars;
  28. use App\Service\Filter\Filter;
  29. use App\Service\Filter\Prods;
  30. use App\Service\Paginator as ServicePaginator;
  31. use App\Service\Statistics\ProdView;
  32. use App\Service\Utils\Bc;
  33. use Doctrine\ORM\EntityManagerInterface;
  34. use Doctrine\ORM\Tools\Pagination\Paginator;
  35. use Psr\EventDispatcher\EventDispatcherInterface;
  36. use RecursiveArrayIterator;
  37. use RecursiveIteratorIterator;
  38. use stdClass;
  39. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  40. use Symfony\Component\HttpFoundation\Request;
  41. use Symfony\Component\HttpFoundation\RequestStack;
  42. use Symfony\Component\HttpFoundation\Response;
  43. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  44. use Symfony\Component\Routing\Annotation\Route;
  45. use Symfony\Contracts\Cache\CacheInterface;
  46. /** @package App\Controller */
  47. class CatalogController extends AbstractASController
  48. {
  49.     private CacheInterface $Cache;
  50.     private EntityManagerInterface $em;
  51.     protected AppDTO $app;
  52.     protected ModelProd $ModelProd;
  53.     protected Cart $Cart;
  54.     protected ModelCart $ModelCart;
  55.     // Repositories
  56.     protected CatRepository $Cats;
  57.     protected ProdRepository $Prods;
  58.     protected PageRepository $Pages;
  59.     protected CatpageRepository $Catpages;
  60.     protected PhotoRepository $Photos;
  61.     protected CharRepository $Chars;
  62.     protected CubeRepository $Cube;
  63.     protected ProdView $prodView;
  64.     public function __construct(CacheInterface $CacheEntityManagerInterface $emAppDTO $appModelProd $ModelProdCart $CartModelCart $ModelCartRequestStack $requestStackProdView $prodView)
  65.     {
  66.         $this->requestStack $requestStack;
  67.         $this->Cache $Cache;
  68.         $this->em $em;
  69.         $this->app $app;
  70.         $this->ModelProd $ModelProd;
  71.         $this->ModelCart $ModelCart;
  72.         $this->Cart $Cart;
  73.         $this->prodView $prodView;
  74.         $this->Cats $this->em->getRepository(Cat::class);
  75.         $this->Prods $this->em->getRepository(Prod::class);
  76.         $this->Pages $this->em->getRepository(Page::class);
  77.         $this->Catpages $this->em->getRepository(Catpage::class);
  78.         $this->Photos $this->em->getRepository(Photo::class);
  79.         $this->Chars $this->em->getRepository(Char::class);
  80.         $this->Cube $this->em->getRepository(Cube::class);
  81.     }
  82.     #[Route('/catalog'name'app_catalog')]
  83.     public function index(): Response
  84.     {
  85.         return $this->redirectToRoute('home');
  86.     }
  87.     #[Route(path'/catalog/cat-{cat_id}-{cat_intname}'name'prod_list_cat_no_locale'defaults: ['_locale' => '%app.default_lang%'])]
  88.     #[Route(path'/catalog/cat-{cat_id}-{cat_intname}/filter-{filters}'name'prod_list_cat_filte_no_locale'defaults: ['_locale' => '%app.default_lang%'])]
  89.     #[Route(path'/catalog/{spec}/cat-{cat_id}-{cat_intname}/filter-{filters}'name'prod_list_cat_spec_filter_no_locale'defaults: ['_locale' => '%app.default_lang%'], requirements: ['spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  90.     #[Route(path'/catalog/{spec}/cat-{cat_id}-{cat_intname}'name'prod_list_cat_spec_no_locale'defaults: ['_locale' => '%app.default_lang%'], requirements: ['spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  91.     #[Route(path'/catalog/{spec}'name'prod_list_spec_no_locale'defaults: ['_locale' => '%app.default_lang%'], requirements: ['spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  92.     #[Route(path'/{_locale}/catalog/cat-{cat_id}-{cat_intname}'name'prod_list_cat'requirements: ['_locale' => '%app.langs%'])]
  93.     #[Route(path'/{_locale}/catalog/cat-{cat_id}-{cat_intname}/filter-{filters}'name'prod_list_cat_filter'requirements: ['_locale' => '%app.langs%'])]
  94.     #[Route(path'/{_locale}/catalog/{spec}/cat-{cat_id}-{cat_intname}/filter-{filters}'name'prod_list_cat_spec_filter'requirements: ['_locale' => '%app.langs%''spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  95.     #[Route(path'/{_locale}/catalog/{spec}/cat-{cat_id}-{cat_intname}'name'prod_list_cat_spec'requirements: ['_locale' => '%app.langs%''spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  96.     #[Route(path'/{_locale}/catalog/{spec}'name'prod_list_spec'requirements: ['_locale' => '%app.langs%''spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  97.     public function prodList(Request $requestSessionInterface $sessionModelCat $ModelCatChars $CharsCats $CatsProds $ModelProdint $cat_id 0string $cat_intname ''string $spec ''string $filters ''): Response
  98.     {
  99.         if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  100.             $bc = ["/" => $this->app->labels->get('home')];
  101.         } else {
  102.             $bc = ["/" $request->getLocale() . "/" => $this->app->labels->get('home')];
  103.         }
  104.         switch ($spec) {
  105.             case 'new':
  106.                 $bctype '/new';
  107.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  108.                     $bc["/catalog/new"] = $this->app->labels->get('main-mobile-buttons-1');
  109.                 } else {
  110.                     $bc["/" $request->getLocale() . "/catalog/new"] = $this->app->labels->get('main-mobile-buttons-1');
  111.                 }
  112.                 break;
  113.             case 'action':
  114.                 $bctype '/action';
  115.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  116.                     $bc["/catalog/action"] = $this->app->labels->get('main-mobile-buttons-2');
  117.                 } else {
  118.                     $bc["/" $request->getLocale() . "/catalog/action"] = $this->app->labels->get('main-mobile-buttons-2');
  119.                 }
  120.                 break;
  121.             case 'pop':
  122.                 $bctype '/pop';
  123.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  124.                     $bc["/catalog/pop"] = $this->app->labels->get('main-mobile-buttons-4');
  125.                 } else {
  126.                     $bc["/" $request->getLocale() . "/catalog/pop"] = $this->app->labels->get('main-mobile-buttons-4');
  127.                 }
  128.                 
  129.                 break;
  130.             case 'mix':
  131.                 $bctype '/mix';
  132.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  133.                     $bc["/catalog/mix"] = $this->app->labels->get('main-mobile-buttons-3');
  134.                 } else {
  135.                     $bc["/" $request->getLocale() . "/catalog/mix"] = $this->app->labels->get('main-mobile-buttons-3');
  136.                 }
  137.                 break;
  138.             case 'onsale':
  139.                 $bctype '/onsale';
  140.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  141.                     $bc["/catalog/onsale"] = $this->app->labels->get('catalog-bc-sale');
  142.                 } else {
  143.                     $bc["/" $request->getLocale() . "/catalog/onsale"] = $this->app->labels->get('catalog-bc-sale');
  144.                 }                
  145.                 break;
  146.             case 'selection1':
  147.                 $bctype '/selection1';
  148.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  149.                     $bc["/catalog/selection1"] = $this->app->labels->get('catalog-bc-selection1');
  150.                 } else {
  151.                     $bc["/" $request->getLocale() . "/catalog/selection1"] = $this->app->labels->get('catalog-bc-selection1');
  152.                 }
  153.                 break;
  154.             case 'selection2':
  155.                 $bctype '/selection2';
  156.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  157.                     $bc["/catalog/selection1"] = $this->app->labels->get('catalog-bc-selection2');
  158.                 } else {
  159.                     $bc["/" $request->getLocale() . "/catalog/selection2"] = $this->app->labels->get('catalog-bc-selection2');
  160.                 }
  161.                 break;
  162.             case 'search':
  163.                 $bctype '/search';
  164.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  165.                     $bc["/catalog/search?q=" $request->get('q')] = $this->app->labels->get('catalog-bc-1') . ": \"" $request->get('q') . "\"";
  166.                 } else {
  167.                     $bc["/" $request->getLocale() . "/catalog/search?q=" $request->get('q')] = $this->app->labels->get('catalog-bc-1') . ": \"" $request->get('q') . "\"";
  168.                 }                
  169.                 break;
  170.             case '':
  171.                 $bctype '';
  172.                 break;
  173.         }
  174.         $bcc = [];
  175.         $is_filter 0;
  176.         $noindex 0;
  177.         $catpage null;
  178.         $showcont 1;
  179.         if ($request->get('filter')) {
  180.             return $this->redirect($this->_makeFilterUrl($request$spec));
  181.         }
  182.         if ($request->get('results') && $request->get('results') != $session->get('results')) {
  183.             $session->set('results'$request->get('results'));
  184.         }
  185.         if ($request->get('view') === 'list' || $request->get('view') === 'grid') {
  186.             setcookie("view_mode"$_GET['view'], time() + 86400 365'/');
  187.         }
  188.         $results $session->get('results') ?? 30;
  189.         $start = (int) $request->query->get('start');
  190.         $view_mode $request->get('view') ?? $request->cookies->get('view_mode') ?? 'list';
  191.         if ($spec) {
  192.             $page $this->Pages->findOneBy(['intname' => 'catalog/' $spec]);
  193.         } else {
  194.             $page $this->Pages->findOneBy(['intname' => 'catalog']);
  195.         }
  196.         if (!$page) {
  197.             $page = new Page();
  198.         }
  199.         $cont '';
  200.         if ($cat_id) {
  201.             $cat_row $row $this->Cats->find($cat_id);
  202.             if ($row === null ||!$row->isVisible() || $row->getIntname() != $cat_intname) {
  203.                 throw $this->createNotFoundException('Page not found');
  204.             }
  205.             $page->setName($row->getName());
  206.             $page->setCont($row->getCont());
  207.             $page->setCont2($row->getCont2());
  208.             $page->setTitle(!empty($row->getTitle()) ? $row->getTitle() : Func::mess_from_tmp($this->app->templates->get('cat_title'), array("name" => $row->getName())));
  209.             $page->setName($row->getName());
  210.             $page->setH1($row->getH1() ? $row->getH1() : $row->getName());
  211.             $page->setKw($row->getKw());
  212.             $page->setDescr(!empty($row->getDescr()) ? $row->getDescr() : Func::mess_from_tmp($this->app->templates->get('cat_desc'), array("name" => $row->getName())));
  213.             $cont $row->getCont();
  214.             $tree array_reverse($ModelCat->get_cat_tree_up($cat_id));
  215.             $bctype $spec '/' $spec '';
  216.             $locale $request->getLocale() == $this->getParameter('app.default_lang') ? '' '/'.$request->getLocale();
  217.             foreach ($tree as $k => $v) {
  218.                 $cat_row $this->Cats->find($v['id']);
  219.                 $searchq '';
  220.                 if ($request->query->get('q')) {
  221.                     $searchq '?q=' $request->query->get('q');
  222.                 }
  223.                 $relatives $this->Cats->findBy(['cat' => $cat_row->getCat(), 'visible' => 1], ['prior' => 'desc']);
  224.                 $bc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()] = $cat_row->getName();
  225.                 
  226.                 foreach ($relatives as $k => $v) {
  227.                     if (!isset($bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()])) {
  228.                         $bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()] = [];
  229.                     }
  230.                     
  231.                     $bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()][$locale "/catalog/cat-" $v->getId() . "-" $v->getIntname()] = $v->getName();
  232.                 }
  233.             }
  234.         }
  235.         $prods $ModelProd->getProds($cat_id$spec$request->get('q'''));
  236.         if ($filters) {
  237.             $is_filter 1;
  238.             $sale 0;
  239.             preg_match_all("/char(\d+)\-([\d_]+)/"$filters$m);
  240.             $chars = [];
  241.             if (preg_match("/sale-(\w+)/"$filters$m2)) {
  242.                 $sale $m2[1];
  243.             }
  244.             foreach ($m[1] as $k => $v) {
  245.                 if (preg_match("/_/"$m[2][$k])) {
  246.                     preg_match_all("/(\d+)/"$m[2][$k], $mm);
  247.                     $chars[$v] = $mm[0];
  248.                 } else {
  249.                     $chars[$v][] = $m[2][$k];
  250.                 }
  251.             }
  252.             $catpage $this->Catpages->findOneBy(['intname' => str_replace("/".$request->getLocale()."/""/"$request->getPathInfo())]);
  253.             if ($catpage) {
  254.                 $is_catpage 1;
  255.                 $page->setName($catpage->getName());
  256.                 $page->setTitle($catpage->getTitle());
  257.                 $page->setH1($catpage->getH1());
  258.                 $page->setKw($catpage->getKw());
  259.                 $page->setDescr($catpage->getDescr());
  260.                 $page->setCont($catpage->getCont());
  261.                 $page->setCont2($catpage->getCont2());
  262.                 $page->setLocale($request->getLocale());                
  263.                 $cont $catpage->getCont();
  264.                 if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  265.                     $bc["/" $catpage->getIntname()] = $catpage->getName();
  266.                 } else {
  267.                     $bc["/" $request->getLocale() . "/" $catpage->getIntname()] = $catpage->getName();
  268.                 }                
  269.             }
  270.             $chars['sale'] = $sale;
  271.             $prods $this->Prods->filter($prods$chars);
  272.         }
  273.         if ($request->get('order') == 'prior') {
  274.             uasort($prods'\App\Repository\ProdRepository::sortArrayByPriorDesc');
  275.         } elseif ($request->get('order') == 'changed' || (empty($request->get('order')) && $spec == 'new')) {
  276.             uasort($prods'\App\Repository\ProdRepository::sortArrayByChangedAsc');
  277.         } elseif ($request->get('order') == 'prior' && $request->get('desc_asc') == 'asc') {
  278.             uasort($prods'\App\Repository\ProdRepository::sortArrayByPriceAsc');
  279.         } elseif ($request->get('order') == 'prior' && $request->get('desc_asc') == 'desc') {
  280.             uasort($prods'\App\Repository\ProdRepository::sortArrayByPriceDesc');
  281.         }  elseif ($request->get('order') == 'skidka') {
  282.             uasort($prods'\App\Repository\ProdRepository::sortArrayBySkidkaDesc');
  283.         } else {
  284.             uasort($prods'\App\Repository\ProdRepository::sortArrayByPriorDesc');
  285.         }
  286.         $cnt count($prods);
  287.         $show_prods = [];
  288.         $k 1;
  289.         $i 1;
  290.         $prodstable = ['cat' => ($cat_id $page->getH1() : ''), 'cnt' => count($prods), 'minprice' => (count($prods) ? 999999999 0), 'maxprice' => 0'avgprice' => 0];
  291.         foreach ($prods as &$prod) {
  292.             if ($start != && $i++ <= $start) continue;
  293.             if ($k <= $results) {
  294.                 $show_prods[] = $prod;
  295.             }
  296.             $k++;
  297.             (($prod['price'] > 0) && ($prodstable['minprice'] > $prod['price'])) ? $prodstable['minprice'] = round($prod['price']) : false;
  298.             (($prod['price'] > 0) && ($prodstable['maxprice'] < $prod['price'])) ? $prodstable['maxprice'] = round($prod['price']) : false;
  299.             $prodstable['avgprice'] += $prod['price'];
  300.         }
  301.         if ($prodstable['cnt']) {
  302.             $prodstable['avgprice'] = round($prodstable['avgprice'] / $prodstable['cnt'], 2);
  303.         } else {
  304.             $prodstable['avgprice'] = 0;
  305.         }
  306.         if ($start) {
  307.             $page = new Page();
  308.             if (isset($row) && $row) {
  309.                 $page->setTitle(Func::mess_from_tmp($this->app->templates->get('cat_page_title'), array("page" => round($start $results) + 1"name" => $row->getName())));
  310.                 $page->setDescr(Func::mess_from_tmp($this->app->templates->get('cat_page_descr'), array("page" => round($start $results) + 1"name" => $row->getName())));
  311.             } else {
  312.                 $page->setTitle(Func::mess_from_tmp($this->app->templates->get('cat_page_title'), array("page" => round($start $results) + 1"name" => "")));
  313.                 $page->setDescr(Func::mess_from_tmp($this->app->templates->get('cat_page_descr'), array("page" => round($start $results) + 1"name" => "")));
  314.             }
  315.             
  316.             $page->setCont('');
  317.             $page->setCont2('');
  318.             $showcont 0;
  319.         }
  320.         /* For SEO. Indexing */        
  321.         $route $request->get('_route');
  322.         $canonical '';
  323.         if ($request->get('start')) {
  324.             $canonical "https://".$request->getHost().$request->getPathInfo()."?start=".$request->get('start');
  325.         } else {
  326.             $canonical "https://".$request->getHost().$request->getPathInfo();
  327.         }
  328.         
  329.         if ($request->get('start', -1) == || $request->get('start') == || $request->get('start') == 'x') {            
  330.             if ($spec && isset($row)) {
  331.                 return $this->redirectToRoute($request->get('_route'), ['cat_id' => $row->getId(), "cat_intname" => $row->getIntname(), "spec" => $spec], 301);
  332.             } elseif (isset($row)) {
  333.                 return $this->redirectToRoute($request->get('_route'), ['cat_id' => $row->getId(), "cat_intname" => $row->getIntname()], 301);
  334.             }
  335.         }
  336.         if ($start && count($show_prods) == 0) {
  337.             $this->createNotFoundException();
  338.         }
  339.         if (!empty($spec)) {
  340.             $noindex 1;
  341.         }
  342.         if ($is_filter || strpos($request->getUri(), 'filter') !== false) {
  343.             if ($catpage) {
  344.                 $noindex 0;
  345.             } else {
  346.                 $noindex 1;
  347.             }
  348.         }
  349.         if (count($request->query->all()) > 1) {
  350.             $noindex 1;
  351.         }
  352.         if (!empty($request->query->all()) && $start 30 != 0) {
  353.             $noindex 1;
  354.         }
  355.         if (!empty($request->get('results'))) {
  356.             $noindex 1;
  357.         }
  358.         if (!empty($request->get('view'))) {
  359.             $noindex 1;
  360.         }
  361.         /* End For SEO */
  362.         // Render Subcats
  363.         $subcat_list_rendered '';
  364.         if (empty($spec)) {
  365.             $cats $this->Cats->findBy(['visible' => 1'cat' => $cat_id], ["prior" => "desc""name" => "asc"]);
  366.             if (count($cats)) {
  367.                 $subcat_list_rendered $this->render('catalog/subcat-list.html.twig', [
  368.                     'cats' => $cats,
  369.                 ]);
  370.             }
  371.         }
  372.         // Ids in Cart
  373.         $cartids = [];
  374.         foreach ($this->Cart->getCart() as $k => $v) {
  375.             $cartids[] = $v['id'];
  376.         }
  377.         $cat $this->Cats->find($cat_id);
  378.         if ($request->get('test')) {
  379.             foreach ($show_prods as $k => $v) {
  380.                 echo $v['id']."-".$v['price']."<br>";
  381.             }
  382.         }
  383.         
  384.         if ($start) {
  385.             // if ($cat) {
  386.             //     $cat->setCont('');
  387.             // }
  388.             
  389.             $showcont 0;
  390.         }
  391.         
  392.         if (!empty($show_prods)) {
  393.             $show_prods $this->Prods->prodArrayToEntity($show_prods);        
  394.             
  395.             if ($request->get('order') == 'prior') {
  396.                 uasort($show_prods'\App\Repository\ProdRepository::sortByPriorDesc');
  397.             } elseif ($request->get('order') == 'changed' || (empty($request->get('order')) && $spec == 'new')) {
  398.                 uasort($show_prods'\App\Repository\ProdRepository::sortByChangedAsc');
  399.             } elseif ($request->get('order') == 'price' && $request->get('desc_asc') == 'asc') {
  400.                 uasort($show_prods'\App\Repository\ProdRepository::sortByPriceAsc');
  401.             } elseif ($request->get('order') == 'price' && $request->get('desc_asc') == 'desc') {                        
  402.                 uasort($show_prods'\App\Repository\ProdRepository::sortByPriceDesc');            
  403.             } else {
  404.                 uasort($show_prods'\App\Repository\ProdRepository::sortByPriorDesc');
  405.             }
  406.             foreach ($show_prods as $k => $v) {                
  407.                 $prod_chars $this->Prods->getprodchars($v->getId(), $request->getLocale());
  408.                 $show_prods[$k]->setPrices($this->ModelProd->getPrices($v));
  409.                 //TODO. Import Photos. Photos из базы
  410.                 $show_prods[$k]->photos $this->Photos->findBy(['type' => 'prod''par' => $v]);
  411.                 $colors = [];
  412.                 $sizes = [];
  413.                 $inpacks = [];
  414.         
  415.                 // if (isset($prod_chars[415])) {
  416.                 //     $size = $prod_chars[415]['cvid'];
  417.                 //     $color = $prod_chars[317]['cvid'];
  418.                 //     $show_prods[$k]->colors = $this->Cube->getColors($v->getModel(), $size, $v->getInpack(), $color);
  419.                 // }
  420.                 
  421.                 // if (isset($prod_chars[317])) {
  422.                 //     $size = $prod_chars[415]['cvid'];
  423.                 //     $color = $prod_chars[317]['cvid'];
  424.                 //     $show_prods[$k]->sizes = $this->Cube->getSizes($v->getModel(), $color, $v->getInpack(), $size);
  425.                 // }
  426.                 
  427.                 if (isset($prod_chars[317]) && isset($prod_chars[415])) {
  428.                     $color $prod_chars[317]['cvid'];
  429.                     $size $prod_chars[415]['cvid'];
  430.                     $show_prods[$k]->colors $this->Cube->getColors($v->getModel(), $size$v->getInpack());
  431.                     $show_prods[$k]->sizes $this->Cube->getSizes($v->getModel(), $color$v->getInpack());
  432.                     $show_prods[$k]->inpacks $this->Cube->getPacks($v->getModel(), $color$size);
  433.                 }
  434.             }
  435.         }
  436.         
  437.         if ($request->get('q''')) {
  438.             $ga_events_search 1;
  439.             $ga_events_prodlist 0;
  440.         } else {
  441.             $ga_events_search 0;
  442.             $ga_events_prodlist 1;
  443.         }
  444.         // CatMenu
  445.         $cats $Cats->getSpecCatMenu($cat_id$spec$request->get('q'''));
  446.         $catpages = [];
  447.         //TODO. Сделать выборку catpages
  448.         // foreach ($cats as $k => $v) {            
  449.         //     foreach ($v as $kk => $subcat) {
  450.         //         $catpages[$subcat['id']] = $this->Catpages->findBy(["visible" => 1, "cat" => $subcat['id']], ["prior" => "DESC"]);
  451.         //         if (empty($catpages[$subcat['id']])) {
  452.         //             unset($catpages[$subcat['id']]);
  453.         //         }
  454.         //     }
  455.         // }
  456.         // Filter
  457.         $chars $Chars->getChars($cat_id);
  458.         $charvals $Chars->getCharVals($cat_id);
  459.         $filter_prods $ModelProd->getProds($cat_id);
  460.         $chars_selected = [];
  461.         $charvals_selected = [];
  462.         
  463.         if ($filters) {
  464.             preg_match_all("/char(\d+)\-([\d_]+)/"$filters$m);
  465.             if (preg_match("/sale-(\w+)/"$filters$m2)) {
  466.                 $chars_selected['sale'] = $m2[1];
  467.             }
  468.             if (isset($m[1]) && count($m[1])) {
  469.                 foreach ($m[1] as $k => $v) {
  470.                     if (preg_match("/_/"$m[2][$k])) {
  471.                         preg_match_all("/(\d+)/"$m[2][$k], $mm);
  472.                         $chars_selected[$v] = $mm[0];
  473.                     } else {
  474.                         $chars_selected[$v][] = $m[2][$k];
  475.                     }
  476.                 }
  477.             }         
  478.         }
  479.         return $this->render('catalog/list.html.twig', [
  480.             'subcat_list_rendered' => $subcat_list_rendered,
  481.             'spec' => $spec,
  482.             'cat_id' => $cat_id,
  483.             'cat_intname' => $cat_intname,
  484.             'filters' => $filters,
  485.             'chars' => $chars,
  486.             'charvals' => $charvals,
  487.             'chars_selected' => $chars_selected,
  488.             'charvals_selected' => $charvals_selected,
  489.             'filter_prods' => $filter_prods,
  490.             'speccatmenu_menu' => $cats,
  491.             'speccatmenu_spec' => $spec,
  492.             'speccatmenu_catpages' => $catpages,
  493.             'speccatmenu_parent_id' => ($cat) ? $cat->getCat() : 0,
  494.             'speccatmenu_cat_id' => $cat_id,
  495.             'speccatmenu_search' => $request->get('q'''),
  496.             'prods' => $show_prods,
  497.             'noindex' => $noindex,
  498.             'cat' => $cat,
  499.             'results' => $results,
  500.             'view_mode' => $view_mode,
  501.             'page' => $page,
  502.             'cont' => $cont,
  503.             'cartids' => $cartids,
  504.             'paginator' => new ServicePaginator($request->attributes->get('_route'), $cnt$results$start),
  505.             'prod_count' => $cnt,
  506.             'bc' => $bc,
  507.             'bcc' => $bcc,
  508.             'canonical' => $canonical,
  509.             'showcont' => $showcont,
  510.             'prodstable' => $prodstable,
  511.             'cart_items' => $this->ModelCart->getCart(),
  512.             'ga_events_search' => $ga_events_search,
  513.             'ga_events_prodlist' => $ga_events_prodlist,
  514.             'q' => $request->get('q'''),
  515.         ]);
  516.     }
  517.     #[Route('/catalog/prod-{prod_id}'name'prod_cont_no_locale'defaults: ['_locale' => '%app.default_lang%'])]
  518.     #[Route('/{_locale}/catalog/prod-{prod_id}'name'prod_cont'requirements: ['_locale' => '%app.langs%'])]
  519.     public function prodCont(Request $requestModelCat $ModelCatEventDispatcherInterface $dispatcherint $prod_id 0): Response
  520.     {
  521.         if ($request->getLocale() == $this->getParameter('app.default_lang')) {
  522.             $bc = ["/" => $this->app->labels->get('home')];
  523.         } else {
  524.             $bc = ["/" $request->getLocale() . "/" => $this->app->labels->get('home')];
  525.         }
  526.         
  527.         $bcc = [];
  528.         $prod $this->Prods->find($prod_id);
  529.         if (!$prod) {
  530.             throw $this->createNotFoundException('Page not found');
  531.         }
  532.         if ($prod) {
  533.             $prices $this->ModelProd->getPrices($prod);
  534.             $prod->setPrices($prices);
  535.         }
  536.         
  537.         $dispatcher->dispatch(
  538.             new ProdViewedEvent($prod), 
  539.             ProdViewedEvent::NAME
  540.         );
  541.         //TODO. Завернуть в событие. Статистика показов
  542.         $this->prodView->addProd($prod->getId());
  543.         
  544.         //TODO. Import Photos. Photos из базы
  545.         $photos $this->Photos->findBy(['type' => 'prod''par' => $prod->getId()]);
  546.         $cat_id $prod->getCat();
  547.         $tree array_reverse($ModelCat->get_cat_tree_up($cat_id));
  548.         $locale $request->getLocale() == $this->getParameter('app.default_lang') ? '' '/'.$request->getLocale();
  549.         
  550.         foreach ($tree as $k => $v) {
  551.             $cat_row $this->Cats->find($v['id']);
  552.             $searchq '';
  553.             if ($request->query->get('q')) {
  554.                 $searchq '?q=' $request->query->get('q');
  555.             }
  556.             $relatives $this->Cats->findBy(['cat' => $cat_row->getCat(), 'visible' => 1], ['prior' => 'desc']);
  557.             $bc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()] = $cat_row->getName();
  558.             
  559.             foreach ($relatives as $k => $v) {
  560.                 if (!isset($bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()])) {
  561.                     $bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()] = [];
  562.                 }
  563.                 
  564.                 $bcc[$locale "/catalog/cat-" $cat_row->getId() . "-" $cat_row->getIntname()][$locale "/catalog/cat-" $v->getId() . "-" $v->getIntname()] = $v->getName();
  565.             }
  566.         }
  567.         
  568.         $prod_chars $this->Prods->getprodchars($prod_id$request->getLocale());
  569.         $prod_childs $this->Prods->getprodchilds($prod_id);
  570.         //TODO. Alex. SEO
  571.         $page = new Page();
  572.         $page->setTitle(Func::mess_from_tmp($this->app->templates->get('prod_title'), array("name" => $prod->getName())));
  573.         $page->setDescr(Func::mess_from_tmp($this->app->templates->get('prod_descr'), array("name" => $prod->getName())));
  574.         $page->setCont('');
  575.         $page->setCont2('');
  576.         
  577.         $colors = [];
  578.         $sizes = [];
  579.         $inpacks = [];
  580.         
  581.         if (isset($prod_chars[317]) && isset($prod_chars[415])) {
  582.             $color $prod_chars[317]['cvid'];
  583.             $size $prod_chars[415]['cvid'];
  584.             $sizes $this->Cube->getSizes($prod->getModel(), $color$prod->getInpack());
  585.             $colors $this->Cube->getColors($prod->getModel(), $size$prod->getInpack());
  586.             $inpacks $this->Cube->getPacks($prod->getModel(), $color$size);
  587.         }
  588.         
  589.         return $this->render('catalog/cont.html.twig', [
  590.             'page' => $page,
  591.             'prod' => $prod,
  592.             'photos' => $photos,
  593.             'bc' => $bc,
  594.             'bcc' => $bcc,
  595.             'chars' => $prod_chars,
  596.             'childs' => $prod_childs,
  597.             'colors' => $colors,
  598.             'sizes' => $sizes,
  599.             'inpacks' => $inpacks,
  600.             'cart_items' => $this->ModelCart->getCart(),
  601.             'ga_events_prodcont' => 1,
  602.         ]);
  603.     }
  604.     #[Route('/catalog/prod/ajax/{prod_id}'name'prod_ajax_no_locale'defaults: ['_locale' => '%app.default_lang%'])]
  605.     #[Route('/{_locale}/catalog/prod/ajax/{prod_id}'name'prod_ajax'requirements: ['_locale' => '%app.langs%'])]
  606.     public function prodAjaxCont(Request $requestint $prod_id 0): Response
  607.     {
  608.         $prod $this->Prods->find($prod_id);
  609.         if ($prod) {
  610.             $prod->setPrices($this->ModelProd->getPrices($prod));
  611.         }
  612.         //TODO. Import Photos. Photos из базы
  613.         $photos $this->Photos->findBy(['type' => 'prod''par' => $prod->getId()]);
  614.         $photosarray = [];
  615.         foreach ($photos as $photo) {
  616.             $obj = new stdClass();
  617.             $obj->id $photo->getId();
  618.             $photosarray[] = $obj;
  619.         }
  620.         $prod_chars $this->Prods->getprodchars($prod_id$request->getLocale());
  621.         if (isset($prod_chars[317]) && isset($prod_chars[415])) {
  622.             $color $prod_chars[317]['cvid'];
  623.             $size $prod_chars[415]['cvid'];
  624.             $colors $this->Cube->getColors($prod->getModel(), $size$prod->getInpack());
  625.             $sizes $this->Cube->getSizes($prod->getModel(), $color$prod->getInpack());
  626.             $inpacks $this->Cube->getPacks($prod->getModel(), $color$size);
  627.         }
  628.         $newprod = [
  629.             'name' => $prod->getName(),
  630.             'labels' => $this->render('catalog/block/prod-labels.html.twig', [
  631.                 'prodone' => $prod,
  632.             ])->getContent(),
  633.             'price' => $this->render('catalog/block/prod-price.html.twig', [
  634.                 'prodone' => $prod,
  635.             ])->getContent(),
  636.             'inpack' => $this->render('catalog/block/prod-inpack.html.twig', [
  637.                 'prodone' => $prod,
  638.             ])->getContent(),
  639.             'weight' => $this->render('catalog/block/prod-weight.html.twig', [
  640.                 'prodone' => $prod,
  641.             ])->getContent(),
  642.             'form' => $this->render('catalog/block/prod-form.html.twig', [
  643.                 'prodone' => $prod,
  644.                 'cart_items' => $this->ModelCart->getCart(),
  645.             ])->getContent(),
  646.             'wishlist' => $this->render('catalog/block/prod-wishlist.html.twig', [
  647.                 'prodone' => $prod,
  648.             ])->getContent(),
  649.             'photos' => $photosarray,
  650.             'colors' => $this->render('catalog/block/prod-colors-list.html.twig', [
  651.                 'prodone' => $prod,
  652.                 'colors' => $colors,
  653.             ])->getContent(),
  654.             'colors2' => $this->render('catalog/block/prod-colors.html.twig', [
  655.                 'prodone' => $prod,
  656.                 'colors' => $colors,
  657.             ])->getContent(),
  658.             'sizes' => $this->render('catalog/block/prod-sizes-list.html.twig', [
  659.                 'prodone' => $prod,
  660.                 'sizes' => $sizes,
  661.             ])->getContent(),
  662.             'inpacks' => $this->render('catalog/block/prod-inpack-list.html.twig', [
  663.                 'prodone' => $prod,
  664.                 'inpacks' => $inpacks,
  665.             ])->getContent(),
  666.         ];
  667.         return $this->render('catalog/ajax.html.twig', [
  668.             'prod' => json_encode($newprod),
  669.         ]);
  670.     }
  671.     #[Route(path'/catalog/getnum/{cat_id}'name'getnum_no_locale'defaults: ['_locale' => '%app.default_lang%'])]
  672.     #[Route(path'/catalog/{spec}/getnum/{cat_id}'name'getnum_spec_no_locale'defaults: ['_locale' => '%app.default_lang%'], requirements: ['spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  673.     #[Route(path'/{_locale}/catalog/getnum/{cat_id}'name'getnum'requirements: ['_locale' => '%app.langs%'])]
  674.     #[Route(path'/{_locale}/catalog/{spec}/getnum/{cat_id}'name'getnum_spec'requirements: ['_locale' => '%app.langs%''spec' => 'new|action|pop|onsale|mix|search|selection1|selection2'])]
  675.     public function getNum(Request $requestProds $ModelProdChars $ModelCharint $cat_id 0string $spec ''): Response
  676.     {
  677.         $result = [];
  678.         $prods $ModelProd->getProds($cat_id$spec);
  679.         $chars $ModelChar->getChars($cat_id);
  680.         $charvals $ModelChar->getCharVals($cat_id);
  681.         $get_chars $ModelProd->getchars($request->query->all());
  682.         //$result = array("num" => count($ModelProd->filter($request->query->all(), $prods)));
  683.         $prods_filtered $this->Prods->filter($prods$get_chars);
  684.         $result = array("num" => count($prods_filtered));
  685.         foreach ($chars as $k => $char) {
  686.             foreach ($charvals[$char->getId()] as $k => $cv) {
  687.                 $result['prodcount'][$cv->getId()] = $ModelProd->prodcount($prods$get_chars$char->getId(), $cv->getId());
  688.             }
  689.             $result['prodcount']['action'] = $ModelProd->prodcount($prods$get_chars'action'1);
  690.             $result['prodcount']['new'] = $ModelProd->prodcount($prods$get_chars'new'1);
  691.             $result['prodcount']['pop'] = $ModelProd->prodcount($prods$get_chars'pop'1);
  692.             $result['prodcount']['mix'] = $ModelProd->prodcount($prods$get_chars'mix'1);
  693.             $result['prodcount']['selection1'] = $ModelProd->prodcount($prods$get_chars'selection1'1);
  694.             $result['prodcount']['selection2'] = $ModelProd->prodcount($prods$get_chars'selection2'1);
  695.         }
  696.         if (is_array($get_chars)) {
  697.             $result['chars'] = array_keys($get_chars);
  698.             $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($get_chars));
  699.             foreach ($it as $v) {
  700.                 $result['charvals'][] = $v;
  701.             }
  702.         } else {
  703.             $result['charvals'] = array();
  704.             $result['chars'] = array();
  705.         }
  706.         return $this->json($result);
  707.     }
  708.     private function _makeFilterUrl(Request $requeststring $spec): string
  709.     {
  710.         $url_redir $request->getPathInfo() . Filter::generate_url($request->query->all());
  711.         return $url_redir;
  712.     }
  713. }