src/AutomarketBundle/Services/CatalogService.php line 321

Open in your IDE?
  1. <?php
  2. namespace AutomarketBundle\Services;
  3. use CoreBundle\Entity\Brand;
  4. use CoreBundle\Entity\Dealer;
  5. use CoreBundle\Entity\Featured;
  6. use CoreBundle\Entity\Model;
  7. use CoreBundle\Entity\Vehicles\RecommendGroup;
  8. use CoreBundle\Entity\Vehicles\VariationCharacteristic;
  9. use CoreBundle\Entity\Vehicles\Vehicle;
  10. use CoreBundle\Entity\Vehicles\VehicleItem;
  11. use CoreBundle\Model\Vehicles\VehicleType;
  12. use CoreBundle\Services\ImageProviderVidi;
  13. use CoreBundle\Services\MediaExtensionVidi;
  14. use CoreBundle\Factory\Vehicle as VehicleFactory;
  15. use DateTime;
  16. use DcSiteBundle\Model\CreditModel;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use Doctrine\ORM\Query\Expr\Join;
  19. use Exception;
  20. use PortalBundle\Model\Catalog;
  21. use Symfony\Bundle\FrameworkBundle\Routing\Router;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. use Symfony\Component\Routing\RouterInterface;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. class CatalogService
  26. {
  27.     private RouterInterface $router;
  28.     private MediaExtensionVidi $media;
  29.     private TranslatorInterface $translator;
  30.     private EntityManagerInterface $em;
  31.     private RequestStack $requestStack;
  32.     private VehicleFactory $coreFactoryVehicle;
  33.     private CreditModel $creditModel;
  34.     public function __constructMediaExtensionVidi $mediaRouterInterface $routerTranslatorInterface $translator,
  35.                                  EntityManagerInterface $emRequestStack $requestStackVehicleFactory $coreFactoryVehicle,
  36.                                  CreditModel $creditModel)
  37.     {
  38.         $this->media $media;
  39.         $this->router $router;
  40.         $this->translator $translator;
  41.         $this->em $em;
  42.         $this->requestStack $requestStack;
  43.         $this->coreFactoryVehicle $coreFactoryVehicle;
  44.         $this->creditModel $creditModel;
  45.     }
  46.     /**
  47.      * Фільтр
  48.      *
  49.      * @return array
  50.      */
  51.     public function initSearch ()
  52.     {
  53.         $request $this->requestStack->getCurrentRequest();
  54.     }
  55.     public function getVehicleType()
  56.     {
  57.         $request $this->requestStack->getCurrentRequest();
  58.         $vehicleTypeData VehicleType::getTypeDataByUrl($request->get('type') ?? 'car');
  59.         return $vehicleTypeData;
  60.     }
  61.     /**
  62.      * Отримати параметри для фільтра на головній
  63.      *
  64.      * @return array
  65.      */
  66.     public function getOnShowFilter()
  67.     {
  68.         $request $this->requestStack->getCurrentRequest();
  69.         $router $this->router;
  70.         /** @var Dealer $dealer */
  71.         $dealer $this->em->getRepository(Dealer::class)->find(6);
  72.         $brandId $request->get('brandId');
  73.         $modelId $request->get('modelId');
  74.         $minYear $request->get('minYear');
  75.         $maxYear $request->get('maxYear');
  76.         $minPrice $request->get('minPrice');
  77.         $maxPrice $request->get('maxPrice');
  78.         $paramRoute = [];
  79.         $responseData = [
  80.             'brands' => [],
  81.             'models' => [],
  82.             'years' => [],
  83.             'maxPrice' => null,
  84.             'countVehicle' => 0,
  85.         ];
  86.         $queryBuilder $this->em->getRepository(\CoreBundle\Entity\Vehicles\VehicleItem::class)
  87.             ->createQueryBuilder('vi')
  88.             ->addSelect('vi')
  89.             ->addSelect('CASE WHEN ( d.id in (32,33)) THEN (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE (CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate * vi.price ELSE vi.price * d.rate END) END) ELSE ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE vi.price END) END AS price')
  90.             ->addSelect('vi.year AS year')
  91.             ->join('vi.vehicle','ve')
  92.             ->join('ve.model''m')
  93.             ->join('m.brand','b')
  94.             ->join('ve.dealer''d')
  95.             ->where('ve.vehicle_type = :type')->setParameter('type'1)
  96.             //  TODO Навіщо ми перевіряємо vehicleItem state на вживаних авто? У вживаного авто є всього 1 vehicleItem, і ми маємо відображати авто по vehicle state. Якщо все буде ок, повидаляти з усіх запитів
  97.             //  ->andWhere('vi.state = 1')
  98.             ->andWhere('vi.sold = :sold')->setParameter('sold'false)
  99.             ->andWhere('ve.state = 1')
  100.             ->andWhere('ve.is_not_filled = 0')
  101.             ->andWhere('ve.is_delete != 1')
  102.             ->andWhere('ve.is_used = :isUsed')->setParameter('isUsed'true);
  103.         if ($brandId) {
  104.             $queryBuilder->andWhere('b.id = :brandId')->setParameter('brandId'$brandId);
  105.         }
  106.         if ($modelId) {
  107.             $queryBuilder->andWhere('m.id = :modelId')->setParameter('modelId'$modelId);
  108.         }
  109.         if ($minPrice) {
  110.             $queryBuilder->andHaving('price >= :minPrice')->setParameter('minPrice'$minPrice $dealer->getRate());
  111.             $paramRoute['minPrice'] = $minPrice $dealer->getRate();
  112.         }
  113.         if ($maxPrice) {
  114.             $queryBuilder->andHaving('price <= :maxPrice')->setParameter('maxPrice'$maxPrice $dealer->getRate());
  115.             $paramRoute['maxPrice'] = $maxPrice $dealer->getRate();
  116.         }
  117.         if ($minYear) {
  118.             $queryBuilder->andHaving('vi.year >= :minYear')->setParameter('minYear'$minYear);
  119.             $paramRoute['minYear'] = $minYear;
  120.         }
  121.         if ($maxYear) {
  122.             $queryBuilder->andHaving('vi.year <= :maxYear')->setParameter('maxYear'$maxYear);
  123.             $paramRoute['maxYear'] = $maxYear;
  124.         }
  125.         $result $queryBuilder->getQuery()->getResult();
  126. //        /** @var VehicleItem $item */
  127. //        foreach ($result as $item){
  128. //            dump($item[0]->getVehicle()->getDealer());
  129. //            dump($item[]->getPrice());
  130. //            dump('----------');
  131. //        }
  132. //
  133. //        dump($result);exit;
  134.         if($result) {
  135.             $responseData['years'] = range(min(array_column($result'year')), max(array_column($result'year'))) ;
  136.             $responseData['countVehicle'] = count($result);
  137.             foreach ($result as $item) {
  138.                 /** @var Vehicle $vehicle */
  139.                 $vehicle $item[0]->getVehicle();
  140.                 $vBrand $vehicle->getModel()->getBrand();
  141.                 $vModel $vehicle->getModel();
  142.                 if (!isset($responseData['brands'][$vBrand->getId()])) {
  143.                     $responseData['brands'][$vBrand->getId()] = [
  144.                         'id' => $vBrand->getId(),
  145.                         'title' => $vBrand->getName(),
  146.                         'url' => $vBrand->getUrl()
  147.                     ];
  148.                 }
  149.                 if (!isset($responseData['models'][$vModel->getId()])) {
  150.                     $responseData['models'][$vModel->getId()] = [
  151.                         'id' => $vModel->getId(),
  152.                         'brandId' => $vBrand->getId(),
  153.                         'title' => $vModel->getTitle(),
  154.                         'url' => $vModel->getUrl()
  155.                     ];
  156.                 }
  157.             }
  158.             $maxPrice max(array_column($result'price'));
  159.             if($maxPrice 10) {
  160.                 $price intval(ceil($maxPrice));
  161.                 $shorNum intval('1' str_repeat('0'floor(log10($price))));
  162.                 $remainder $price $shorNum;
  163.                 $responseData['maxPrice'] = $price + ($shorNum $remainder);
  164.             }
  165.         }
  166.         if($brandId && isset($responseData['brands'][$brandId]['url'])) {
  167.             $brandUrl $responseData['brands'][$brandId]['url'];
  168.             $paramRoute['brand'][$brandUrl] = 'true';
  169.         }
  170.         if($modelId && isset($responseData['models'][$modelId]['url'])) {
  171.             $modelUrl $responseData['models'][$modelId]['url'];
  172.             $paramRoute['model'][$modelUrl] = 'true';
  173.         }
  174.         if($result && $responseData['countVehicle'] > && !empty($paramRoute)) {
  175.             $responseData['link'] = $router->generate('automarket_catalog_search'$paramRoute);
  176.         }else{
  177.             $responseData['link'] = $router->generate('automarket_catalog', ['state' => 'used''type' => 'car']);
  178.         }
  179.         return  $responseData;
  180.     }
  181.     public function getBrands($vehicleType)
  182.     {
  183.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\Vehicle::class)
  184.             ->createQueryBuilder('v')
  185.             ->select('b.id''b.name''b.url')
  186.             ->join('v.model''m')
  187.             ->join('m.brand''b')
  188.             ->andWhere('v.state = :state')->setParameter('state'true)
  189.             ->andWhere('v.is_delete = :isDelete')->setParameter('isDelete'false)
  190.             ->andWhere('v.is_used = :isUsed')->setParameter('isUsed'true)
  191.             ->andWhere('v.vehicle_type = :type')->setParameter('type'$vehicleType);
  192.         $query->orderBy('b.name');
  193.         $query->groupBy('b.id');
  194.         return $query->getQuery()->getResult();
  195.     }
  196.     public function getModels($vehicleTypeBrand $brand null)
  197.     {
  198.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\Vehicle::class)
  199.             ->createQueryBuilder('v')
  200.             ->select('m.id''m.title''m.url')
  201.             ->innerJoin('v.model''m')
  202.             ->innerJoin('m.brand''b')
  203.             ->andWhere('v.state = :state')->setParameter('state'true)
  204.             ->andWhere('v.is_delete = :isDelete')->setParameter('isDelete'false)
  205.             ->andWhere('v.is_used = :isUsed')->setParameter('isUsed'true)
  206.             ->andWhere('v.vehicle_type = :type')->setParameter('type'$vehicleType);
  207.         if ($brand) {
  208.             $query->andWhere('b.id = :brand')->setParameter('brand'$brand);
  209.         }
  210.         $query->orderBy('m.title');
  211.         $query->groupBy('m.id');
  212.         return $query->getQuery()->getResult();
  213.     }
  214.     public function getRecommendGroupByParams($vehicleType)
  215.     {
  216.         $request $this->requestStack->getCurrentRequest();
  217.         $locale $request->getLocale();
  218.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\RecommendGroup::class)
  219.             ->createQueryBuilder('rg')
  220.             ->select('rg')
  221.             ->andWhere('rg.state = :rgState')
  222.             ->setParameter('rgState'true)
  223.             ->andWhere('rg.state_slider = :rgStateSlider')
  224.             ->setParameter('rgStateSlider'true);
  225.         $recommendGroup $query->getQuery()->getResult();
  226.         $result = [];
  227.         /** @var RecommendGroup $item */
  228.         foreach ($recommendGroup as $item) {
  229.             $result[$item->getUrl()] = $item->getTitle($locale);
  230.         }
  231.         return $result;
  232.     }
  233.     public function getCharacteristicsByParams($vehicleType$brand null$model null$vehicleIds = [])
  234.     {
  235.         $request $this->requestStack->getCurrentRequest();
  236.         $locale $request->getLocale();
  237.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\VariationCharacteristic::class)
  238.             ->createQueryBuilder('vc');
  239.         if ($locale == 'ru') {
  240.             $query->select('cv.id''c.url AS cUrl''cv.url''cv.value_ru AS value');
  241.         } else {
  242.             $query->select('cv.id''c.url AS cUrl''cv.url''cv.value_ua AS value');
  243.         }
  244.         $query->join('vc.characteristic_value''cv')
  245.             ->join('vc.characteristic''c'Join::WITH'c.vehicle_type = :type')->setParameter('type'$vehicleType)
  246.             ->join('vc.variation''v'Join::WITH'v.state = 1')
  247.             ->join('v.vehicle''ve'Join::WITH've.state = 1 AND ve.is_delete <> 1 AND ve.is_used = :is_used')->setParameter('is_used'true)
  248.             ->join('ve.model''m')
  249.             ->join('m.brand''b');
  250.         if ($brand) {
  251.             $query->andWhere('b.url = :bUrl')->setParameter('bUrl'$brand->getUrl());
  252.         }
  253.         if ($model) {
  254.             $query->andWhere('m.url = :mUrl')->setParameter('mUrl'$model->getUrl());
  255.         }
  256.         if (!empty($vehicleIds)) {
  257.             $query->andWhere('ve.id IN (:vehicleIds)')
  258.                 ->setParameter('vehicleIds'$vehicleIds);
  259.         }
  260.         $query->groupBy('cv''c');
  261.         $characteristics $query->getQuery()->getResult();
  262.         $result = [];
  263.         foreach ($characteristics as $row) {
  264.             $result[$row['cUrl']][$row['url']] = $row['value'];
  265.         }
  266.         return $result;
  267.     }
  268.     public function getVehicleByCatalog(Dealer $dealer$findVehicles$user$lang): array
  269.     {
  270.         $rows array_column($findVehicles0);
  271.         return $this->getVehicleCatalogItem($dealer$rows$user$lang);
  272.     }
  273.     public function getVehicleCatalogItem(Dealer $dealer$vehicleItems$user$lang): array
  274.     {
  275.         $request $this->requestStack->getCurrentRequest();
  276.         $features $this->em->getRepository(\CoreBundle\Entity\Featured::class)->findBy(['type' => 'vehicle''user' => $user]);
  277.         $featuresIds = [];
  278.         /** @var Featured $feature */
  279.         foreach ($features as $feature) {
  280.             $favData json_decode($feature->getData());
  281.             if(!isset($favData->vehicleItemId)){
  282.                 continue;
  283.             }
  284.             $featuresIds[$favData->vehicleItemId] = $feature->getId();
  285.         }
  286.         $compareCookie $request->cookies->get('compare');
  287.         $vehicleComparison explode(','$compareCookie);
  288.         return array_reduce($vehicleItems, function($rows$row) use ($dealer$featuresIds$vehicleComparison$lang$request) {
  289.             try {
  290.                 $row $this->coreFactoryVehicle->createByVehicleItem($row);
  291.                 if (empty($row)) {
  292.                     return $rows;
  293.                 }
  294.                 $dollar $dealer->getRate();
  295.                 $price $row->price();
  296.                 $priceAlt $row->getPriceAlt();
  297.                 $priceDollar 0;
  298.                 $sale 0;
  299.                 if ($priceAlt && $priceAlt $row->getPrice()) {
  300.                     $priceAlt $row->getPrice();
  301.                     $sale = ($row->getPriceAlt() / $row->getPrice()) * 100;
  302.                 }
  303.                 if ($dollar 0) {
  304.                     $priceDollar ceil($price $dollar);
  305.                 }
  306.                 $vehicleTypeData VehicleType::getTypeDataById($row->getVehicleType());
  307.                 $vehicleUrl $this->router->generate('automarket_vehicle', ['state' => 'used''type' => $vehicleTypeData['url'], 'brand' => $row->getBrand()->getUrl(), 'model' => $row->getModel()->getUrl(),'id' => $row->getVehicleId()]);
  308.                 $engineVolume = (int)$row->getEngineVolume($request->getLocale());
  309.                 $engineVolumeFormat $engineVolume 10 number_format$engineVolume/10001'.''') : number_format$engineVolume1'.''');
  310.                 $rows[] = [
  311.                     'id' => $row->getVehicleId(),
  312.                     'itemId' => $row->getVehicleItemId(),
  313.                     'title' => $row->getModelName(),
  314.                     'fullName' => $row->getFullName(),
  315.                     'year' => $row->getYear(),
  316.                     'price' => intval($price),
  317.                     'price_alt' => intval($priceAlt),
  318.                     'price_dollar' => intval($priceDollar),
  319.                     'deposit' => $row->getDeposit(),
  320.                     'sold' => $row->getSold(),
  321.                     'sale' => ($sale)? 100 intval($sale) : null,
  322.                     'engine_volume' => $engineVolumeFormat,
  323.                     'mileage' => $row->getMileage(),
  324.                     'mileageThousand' => floor($row->getMileage() / 1000),
  325.                     'url' => $vehicleUrl,
  326.                     'bodyType' => $row->getBodyTypeName($lang),
  327.                     'engine_type' => $row->getFuelTypeName($lang),
  328.                     'transmission' => $row->getTransmissionTypeName($lang),
  329.                     'creditPayment' => $this->creditModel->getMinPayment($row),
  330.                     'featuredId' => $featuresIds[$row->getVehicleItemId()] ?? null,
  331.                     'featuredLink' => $request->getSchemeAndHttpHost().$vehicleUrl,
  332.                     'comparedId' => in_array($row->getVehicleItemId(),$vehicleComparison)? $row->getVehicleItemId() : null,
  333.                     'media' => [
  334.                         'image' => $this->media->getPath($row->getPreview(), 'reference')
  335.                     ],
  336.                     'riaPublicationDate' => $row->getRiaPublicationDate(),
  337.                     'isElectric' => $row->isElectric(),
  338.                     'batteryCapacity' => $row->getBatteryCapacity($lang),
  339.                 ];
  340.                 return $rows;
  341.             } catch (Exception $e) {
  342.                 return $rows;
  343.             }
  344.         }, []);
  345.     }
  346.     private function roundMaxData($num){
  347.         if($num 10) {
  348.             $shorNum intval('1' str_repeat('0'floor(log10($num))));
  349.             $remainder $num $shorNum;
  350.             $num += $shorNum $remainder;
  351.         }
  352.         return $num;
  353.     }
  354.     public function buildFilter($typeFilter null){
  355.         $request $this->requestStack->getCurrentRequest();
  356.         $locale $request->getLocale();
  357.         $vehicleTypeData $this->getVehicleType();
  358.         $brand = isset($routeParams['brand']) ? $this->em->getRepository(\CoreBundle\Entity\Brand::class)->findOneBy(['url' => $routeParams['brand']]) : null;
  359.         $model = isset($routeParams['model']) && $brand $this->em->getRepository(\CoreBundle\Entity\Model::class)->findOneBy(['url' => $routeParams['model'], 'brand' => $brand]) : null;
  360.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\VariationCharacteristic::class)
  361.             ->createQueryBuilder('vc')
  362.             ->join('vc.characteristic''c'Join::WITH'c.vehicle_type = :type')->setParameter('type'$vehicleTypeData['id'])
  363.             ->join('vc.characteristic_value','cv')
  364.             ->join('vc.variation''v'Join::WITH'v.state = 1')
  365.             ->join('v.vehicle''ve'Join::WITH've.state = 1 AND ve.is_delete <> 1 AND ve.is_used = :is_used')->setParameter('is_used'1)
  366.             ->join('v.vehicle_items','vi'Join::WITH'vi.state = 1')
  367.             ->andWhere('ve.is_not_filled = 0')
  368.             ->andWhere('ve.is_delete != 1');
  369.         if($typeFilter){
  370.             $query->andWhere('c.model_unique IN (:modelUniques)')->setParameter('modelUniques'$typeFilter);
  371.         }
  372.         if ($model) {
  373.             $query->join('ve.model''m')
  374.                 ->andWhere('m.id = :model')
  375.                 ->setParameter('model'$model->getId());
  376.         }
  377.         if ($brand && !$model) {
  378.             $query->join('ve.model''m')
  379.                 ->join('m.brand''b')
  380.                 ->andWhere('b.id = :brand')
  381.                 ->setParameter('brand'$brand->getId());
  382.         }
  383.         if ($locale == 'ru') {
  384.             $query->orderBy('cv.position')->addOrderBy('cv.value_ru');
  385.         }else{
  386.             $query->orderBy('cv.position')->addOrderBy('cv.value_ua');
  387.         }
  388.         $vCharacteristics $query->getQuery()->getResult();
  389.         $query->addSelect('vi.price')
  390.             ->addSelect('vi.mileage')
  391.             ->addSelect('vi.year');
  392.         $maxVehicleResult $query->getQuery()->getResult();
  393.         $filters['limitationData'] = [
  394.             'minPrice' => 0,
  395.             'maxPrice' => $this->roundMaxData(max(array_column($maxVehicleResult'price'))),
  396.             'minYear' => 0,
  397.             'maxYear' => max(array_column($maxVehicleResult'year')),
  398.             'minMileage' => 0,
  399.             'maxMileage' => $this->roundMaxData(max(array_column($maxVehicleResult'mileage'))),
  400.         ];
  401.         /** @var VariationCharacteristic $vCharacteristic */
  402.         foreach ($vCharacteristics as $vCharacteristic){
  403.             $characteristic $vCharacteristic->getCharacteristic();
  404.             $characteristicValue $vCharacteristic->getCharacteristicValue();
  405.             if(!$characteristic->getUrl() || $characteristic->getUrl() == ''){
  406.                 continue;
  407.             }
  408.             // Тільки автомат та механіка у типі КПП
  409.             if($characteristic->getUrl() == "kpp" &&
  410.                 ($characteristicValue->getUrl() != "avtomat" && $characteristicValue->getUrl() != "mehanika")){
  411.                 continue;
  412.             }
  413.             if (!isset($filters['characteristic'][$characteristic->getUrl()])) {
  414.                 $filters['characteristic'][$characteristic->getUrl()] = [
  415.                     'id' => $characteristic->getId(),
  416.                     'title' => $characteristic->getTitle($locale),
  417.                     'url' => $characteristic->getUrl(),
  418.                     'values' => [],
  419.                 ];
  420.             }
  421.             if(isset($filters['characteristic'][$characteristic->getUrl()]['values'][$characteristicValue->getId()])){
  422.                 continue;
  423.             }
  424.             if ($characteristic->getUrl()) {
  425.                 $filters['characteristic'][$characteristic->getUrl()]['values'][$characteristicValue->getId()] = [
  426.                     'id' => $characteristicValue->getId(),
  427.                     'title' => $characteristicValue->getValue($locale),
  428.                     'url' => $characteristicValue->getUrl(),
  429.                 ];
  430.             } else {
  431.                 $filters['characteristic'][$characteristic->getUrl()]['values'] = null;
  432.             }
  433.         }
  434.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\RecommendGroup::class)
  435.             ->createQueryBuilder('rg')
  436.             ->select('rg')
  437.             ->join('rg.vehicles''ve')
  438.             ->where('ve.vehicle_type = :type')
  439.             ->andWhere('ve.state = 1')
  440.             ->andWhere('ve.is_delete != 1')
  441.             ->setParameter('type'$vehicleTypeData['id'])
  442.             ->andWhere('rg.state = :rgState')
  443.             ->setParameter('rgState'true)
  444.             ->andWhere('rg.state_slider = :rgStateSlider')
  445.             ->setParameter('rgStateSlider'true)
  446.             ->andWhere('ve.is_used = :is_used')->setParameter('is_used'1);
  447.         $recommendGroup $query->getQuery()->getResult();
  448.         $filters['recommendGroup'] = [
  449.             'url' => 'recommendGroup',
  450.             'values' => [],
  451.         ];
  452.         /** @var RecommendGroup $item */
  453.         foreach ($recommendGroup as $item) {
  454.             $filters['recommendGroup']['values'][$item->getId()] = [
  455.                 'id' => $item->getId(),
  456.                 'title' => $item->getTitle($locale),
  457.                 'url' => $item->getUrl(),
  458.             ];
  459.         }
  460.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\Vehicle::class)
  461.             ->createQueryBuilder('v')
  462.             ->select('b.id as bid''b.url as burl''b.name''m.id''m.url''m.title')
  463.             ->join('v.model''m')
  464.             ->join('m.brand''b')
  465.             ->leftJoin('b.logo''logo')
  466.             ->where('v.vehicle_type = :type')
  467.             ->andWhere('v.state = 1')
  468.             ->andWhere('v.is_delete != 1')
  469.             ->setParameter('type'$vehicleTypeData['id'])
  470.             ->andWhere('v.is_used = :is_used')->setParameter('is_used'1);
  471.         $brands $query->getQuery()->getResult();
  472.         foreach ($brands as $line) {
  473.             if (!isset($filters['brand'][$line['burl']])) {
  474.                 $filters['brand'][$line['burl']] = [
  475.                     'id' => $line['bid'],
  476.                     'title' => $line['name'],
  477.                     'url' => $line['burl'],
  478.                     'count' => 1,
  479.                     'models' => [],
  480.                 ];
  481.             }
  482.             $filters['brand'][$line['burl']]['models'][$line['id']] = [
  483.                 'id' => $line['id'],
  484.                 'url' => $line['url'],
  485.                 'title' => $line['title'],
  486.             ];
  487.         }
  488.         usort($filters['brand'], function ($a$b) {
  489.             if ($a['title'] == $b['title']) {
  490.                 return 1;
  491.             }
  492.             return $a['title'] > $b['title'] ? : -1;
  493.         });
  494.         return $filters;
  495.     }
  496.     public function getFilterHeader(){
  497.         $request $this->requestStack->getCurrentRequest();
  498.         $requestParams $request->query->all();
  499.         $vehicleTypeData $this->getVehicleType();
  500.         $catalogCharacteristic $this->getCharacteristicsByParams($vehicleTypeData['id']);
  501.         $catalogRecommendGroup $this->getRecommendGroupByParams($vehicleTypeData['id']);
  502.         $filters = [];
  503.         foreach ($requestParams as $type => $params) {
  504.             if (!is_array($params)) {
  505.                 $from $this->translator->trans('new_catalog.from', [], 'portal_base') . ' ' $params;
  506.                 $to ' '.$this->translator->trans('new_catalog.to', [], 'portal_base') . ' ' $params;
  507.                 $year $this->translator->trans('new_catalog.year', [], 'portal_base') . ' ';
  508.                 $price $this->translator->trans('new_catalog.price', [], 'portal_base') . ' ';
  509.                 $mileage $this->translator->trans('cars.used.mileage', [], 'portal_base') . ' ';
  510.                 switch ($type) {
  511.                     case $type == 'minYear' && $params 0:
  512.                         $filters['range']['year'] = $year $from;
  513.                         break;
  514.                     case $type == 'maxYear' && $params 0:
  515.                         $filters['range']['year'] =
  516.                             isset($filters['range']['year']) ? $filters['range']['year'] . $to $year $to;
  517.                         break;
  518.                     case $type == 'minPrice' && $params 0:
  519.                         $filters['range']['price'] = $price $from' грн';
  520.                         break;
  521.                     case $type == 'maxPrice' && $params 0:
  522.                         $filters['range']['price'] =
  523.                             isset($filters['range']['price']) ? $filters['range']['price'] . $to' грн' $price $to ' грн';
  524.                         break;
  525.                     case $type == 'minMileage' && $params 0:
  526.                         $filters['range']['mileage'] = $mileage $from' тис.';
  527.                         break;
  528.                     case $type == 'maxMileage' && $params 0:
  529.                         $filters['range']['mileage'] =
  530.                             isset($filters['range']['mileage']) ? $filters['range']['mileage'] . $to' тис.' $mileage $to ' тис.';
  531.                         break;
  532.                 }
  533.                 continue;
  534.             }
  535.             if(empty($params)){
  536.                 continue;
  537.             }
  538.             if($type == 'recommendGroup'){
  539.                 $filters[$type] = array_intersect_key($catalogRecommendGroup$params);
  540.                 continue;
  541.             }
  542.             if($type == 'characteristic'){
  543.                 foreach ($params as $paramType => $param){
  544.                     $result array_intersect_key($catalogCharacteristic$params);
  545.                     if(count($result)) {
  546.                         $filters['characteristic'][$paramType] = array_intersect_key($catalogCharacteristic[$paramType], $param);
  547.                     }
  548.                 }
  549.                 continue;
  550.             }
  551.             $filters[$type] = $params;
  552.         }
  553.         return $filters;
  554.     }
  555.     public function getRouteFilterParams(Dealer $dealer)
  556.     {
  557.         $request $this->requestStack->getCurrentRequest();
  558.         $routeParams $request->attributes->get('_route_params');
  559.         $params = [];
  560.         $typeParams = ['state''type''brand''model''param''price''recommendGroup'];
  561.         foreach ($typeParams as $type){
  562.             switch ($type) {
  563.                 case 'price':
  564.                     if(isset($routeParams['price'])) {
  565.                         $params['maxPrice'] = floor($routeParams[$type] * $dealer->getRate());
  566.                     }
  567.                     break;
  568.                 case 'param':
  569.                     foreach ($routeParams as $key => $value) {
  570.                         if (preg_match('/^param(\d*)$/'$key$matches)) {
  571.                             $index $matches[1];
  572.                             $valueKey $index 'value' $index 'value';
  573.                             if (isset($routeParams[$valueKey])) {
  574.                                 $params['characteristic'][$value][$routeParams[$valueKey]] = true;
  575.                             }
  576.                         }
  577.                     }
  578. //                    if(isset($routeParams['param']) && isset($routeParams['value'])) {
  579. //                        $params['characteristic'][$routeParams['param']][$routeParams['value']] = true;
  580. //                    }
  581.                     break;
  582.                 case 'model':
  583.                 case 'brand':
  584.                 case 'recommendGroup':
  585.                     if(isset($routeParams[$type])) {
  586.                         $params[$type][$routeParams[$type]] = true;
  587.                     }
  588.                     break;
  589.                 default:
  590.                     if(isset($routeParams[$type])){
  591.                         $params[$type] = $routeParams[$type];
  592.                     }
  593.                     break;
  594.             }
  595.         }
  596.         return $params;
  597.     }
  598.     public function showMoreCatalog($countVehicle$countVehicleByPage)
  599.     {
  600.         $request $this->requestStack->getCurrentRequest();
  601.         $currentPage $request->query->get('page') ?: 1;
  602.         return (($countVehicle $countVehicleByPage*$currentPage) > 0);
  603.     }
  604.     public function buildSearchUrl()
  605.     {
  606.         $request $this->requestStack->getCurrentRequest();
  607.         $searchParams $request->query->all();
  608.         $searchParams array_filter($searchParams, fn($value) => $value !== "");
  609.         return $this->router->generate('automarket_catalog_search'$searchParams);
  610.     }
  611.     public function findModelByParams($urlBrands null$urlModels null)
  612.     {
  613.         $filterBrands $this->em->getRepository(\CoreBundle\Entity\Brand::class)->getBrandsByUrl($urlBrands);
  614.         $filterModelIds = [];
  615.         /** @var Brand $brand */
  616.         foreach ($filterBrands as $brand) {
  617.             $models = [];
  618.             $modelSearch = [];
  619.             /** @var Model $model */
  620.             foreach ($brand->getModels() as $model) {
  621.                 if (!$model->getUrl()) {
  622.                     continue;
  623.                 }
  624.                 if (in_array($model->getUrl(), $urlModels)) {
  625.                     $modelSearch[] = $model->getId();
  626.                 }
  627.                 $models[] = $model->getId();
  628.             }
  629.             $filterModelIds = (empty($modelSearch)) ? array_merge($filterModelIds$models) : array_merge($filterModelIds$modelSearch);
  630.         }
  631.         return $filterModelIds;
  632.     }
  633.     public function findVehicleByParams($pageLimit null)
  634.     {
  635.         $request $this->requestStack->getCurrentRequest();
  636.         $routeParams $request->attributes->get('_route_params');
  637.         $routeSearch = ($request->attributes->get('_route') == 'automarket_catalog_search');
  638.         $searchParams $request->query->all();
  639.         $brand $routeParams['brand'] ?? null;
  640.         $model $routeParams['model'] ?? null;
  641.         $price $routeParams['price'] ?? null;
  642.         $year $routeParams['year'] ?? null;
  643.         $param $routeParams['param'] ?? null;
  644.         $param_value $routeParams['value'] ?? null;
  645.         $param2 $routeParams['param2'] ?? null;
  646.         $param_value2 $routeParams['value2'] ?? null;
  647.         $recommendGroup $routeParams['recommendGroup'] ?? null;
  648.         $vehicleTypeData $this->getVehicleType();
  649.         $mounthAgo = (new DateTime())->modify('-30 days')->format('Y-m-d H:i:s');;
  650.         $query $this->em->getRepository(\CoreBundle\Entity\Vehicles\VehicleItem::class)
  651.             ->createQueryBuilder('vi')
  652.             ->addSelect('vi')
  653.             ->addSelect('CASE WHEN ( d.id in (32,33)) THEN (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE (CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate * vi.price ELSE vi.price * d.rate END) END) ELSE ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE vi.price END) END AS price')
  654.             ->addSelect('CASE WHEN ( d.id in (32,33)) THEN (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE (CASE WHEN vi.alt_rate > 0 THEN vi.price ELSE vi.price END) END) ELSE ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price / d.rate ELSE vi.price / d.rate END)END AS priceUsd')
  655.             ->addSelect('CASE WHEN (CASE WHEN ( d.id in (32,33)) THEN ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE ( CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate * vi.price ELSE vi.price * d.rate END) END) ELSE (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE vi.price END) END) = 0 THEN 9999999999 ELSE (CASE WHEN ( d.id in (32,33)) THEN (CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE ( CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate * vi.price ELSE vi.price * d.rate END ) END ) ELSE ( CASE WHEN vi.alt_price > 0 THEN vi.alt_price ELSE vi.price END) END) END AS orderPrice')
  656.             ->join('vi.variation''v')
  657.             ->join('v.vehicle''ve')
  658.             ->join('v.characteristics''vch')
  659.             ->join('vch.characteristic''ch')
  660.             ->join('vch.characteristic_value''chv')
  661.             ->join('ve.dealer''d')
  662.             ->join('ve.model''m')
  663.             ->join('m.brand''b')
  664.             ->leftJoin('ve.recommend_group''rg')
  665.             ->where('ve.vehicle_type = :type')
  666.             //  TODO Навіщо ми перевіряємо vehicleItem state на вживаних авто? У вживаного авто є всього 1 vehicleItem, і ми маємо відображати авто по vehicle state. Якщо все буде ок, повидаляти з усіх запитів
  667.             //  ->andWhere('vi.state = 1')
  668.             ->andWhere('ve.state = 1')
  669.             ->andWhere('ve.is_not_filled = 0')
  670.             ->andWhere('ve.is_delete != 1')
  671.             ->setParameter('type'$vehicleTypeData['id'])
  672.             ->andWhere('ve.is_used = :isUsed')->setParameter('isUsed'true)
  673.             ->andWhere('vi.date_of_sale > :mounthAgo OR vi.date_of_sale IS NULL')
  674.             ->orderBy('vi.sold''ASC')
  675.             ->addOrderBy('vi.deposit''ASC')
  676.             ->setParameter('mounthAgo'$mounthAgo);
  677.         if(!$routeSearch) {
  678.             if ($brand) {
  679.                 $query->andWhere('b.url = :brand')->setParameter('brand'$brand);
  680.             }
  681.             if ($brand && $model) {
  682.                 $query->andWhere('m.url = :model')->setParameter('model'$model);
  683.             }
  684.             if (isset($routeParams['param']) && $routeParams['param'] && isset($routeParams['value']) && $routeParams['value']) {
  685.                 $query->andWhere('ch.url = :param AND chv.url = :paramValue')
  686.                     ->setParameter('param'$routeParams['param'])
  687.                     ->setParameter('paramValue'$routeParams['value']);
  688.             }
  689.             if (isset($routeParams['param2']) && isset($routeParams['value2'])) {
  690.                 $cvIds = [];
  691.                 $cType $this->em->getRepository(\CoreBundle\Entity\Vehicles\Characteristic::class)->findOneBy(['url' => $routeParams['param2']]);
  692.                 $alias 'vc' $cType->getId();
  693.                 $fKey 'charId' $cType->getId();
  694.                 $tKey 'cids' $cType->getId();
  695.                 $query->join('v.characteristics'$alias);
  696.                 $cValue $this->em->getRepository(\CoreBundle\Entity\Vehicles\CharacteristicValue::class)->findOneBy(['url' => $routeParams['value2'], 'characteristic' => $cType]);
  697.                 if ($cValue) {
  698.                     $cvIds[] = $cValue->getId();
  699.                 }
  700.                 if (!empty($cvIds)) {
  701.                     $query->andWhere($alias '.characteristic = :' $fKey)->setParameter($fKey$cType->getId());
  702.                     $query->andWhere($alias '.characteristic_value IN (:' $tKey ')')->setParameter($tKey$cvIds);
  703.                 }
  704.             }
  705.             if ($price) {
  706.                 $query->andHaving('priceUsd <= :price')->setParameter('price'$price);
  707.             }
  708.             if ($year) {
  709.                 $query->andHaving('vi.year <= :year')->setParameter('yearMax'$year);
  710.             }
  711.             if ($recommendGroup) {
  712.                 $query->andWhere('rg.url = :recommendGroup')->setParameter('recommendGroup'$recommendGroup);
  713.             }
  714.         }
  715.         if (count($searchParams)) {
  716.             foreach ($searchParams as $key => $item) {
  717.                 switch ($key) {
  718.                     case 'brand':
  719.                         if (!isset($searchParams['model'])) {
  720.                             $query->andWhere('b.url IN (:brand)')->setParameter('brand'array_keys($item));
  721.                         } else {
  722.                             $filterModelIds $this->findModelByParams(array_keys($item), array_keys($searchParams['model']));
  723.                             $query->andWhere('m.id IN (:modelIds)')->setParameter('modelIds'$filterModelIds);
  724.                         }
  725.                         break;
  726.                     case 'model':
  727.                         if (!isset($searchParams['brand']) || count($searchParams['brand']) == 1) {
  728.                             $query->andWhere('m.url IN (:model)')->setParameter('model'array_keys($item));
  729.                         }
  730.                         break;
  731.                     case 'recommendGroup':
  732.                         $query->andWhere('rg.url IN (:recommendGroup)')->setParameter('recommendGroup'array_keys($item));
  733.                         break;
  734.                     case 'minPrice':
  735.                         if ($item 0) {
  736.                             $query->andHaving('price >= :minPrice')->setParameter('minPrice'$item);
  737.                         }
  738.                         break;
  739.                     case 'maxPrice':
  740.                         if ($item 0) {
  741.                             $query->andHaving('price <= :maxPrice')->setParameter('maxPrice'$item);
  742.                         }
  743.                         break;
  744.                     case 'minYear':
  745.                         if ($item 0) {
  746.                             $query->andHaving('vi.year >= :minYear')->setParameter('minYear'$item);
  747.                         }
  748.                         break;
  749.                     case 'maxYear':
  750.                         if ($item 0) {
  751.                             $query->andHaving('vi.year <= :maxYear')->setParameter('maxYear'$item);
  752.                         }
  753.                         break;
  754.                     case 'minMileage':
  755.                         if ($item 0) {
  756.                             $query->andHaving('vi.mileage >= :minMileage')->setParameter('minMileage'$item 1000);
  757.                         }
  758.                         break;
  759.                     case 'maxMileage':
  760.                         if ($item 0) {
  761.                             $query->andHaving('vi.mileage <= :maxMileage')->setParameter('maxMileage'$item 1000);
  762.                         }
  763.                         break;
  764.                     case 'hasNDS':
  765.                         if ($item == 'true') {
  766.                             $query->andWhere('vi.has_nds = 1');
  767.                         }
  768.                         break;
  769.                     case 'sale':
  770.                         if ($item == 'true') {
  771.                             $query->andWhere('vi.alt_price > 0');
  772.                         }
  773.                         break;
  774.                     case 'isSelect':
  775.                         if ($item == 'true') {
  776.                             $query->andWhere($query->expr()->notIn('ve.dealer'Catalog::NOT_VIDI_SELECT_DEALERS));
  777.                         }
  778.                         break;
  779.                 }
  780.             }
  781.         }
  782.         if (isset($searchParams['characteristic']) && $searchParams['characteristic']) {
  783.             foreach ($searchParams['characteristic'] as $type => $params) {
  784.                 $cvIds = [];
  785.                 $cType $this->em->getRepository(\CoreBundle\Entity\Vehicles\Characteristic::class)->findOneBy(['url' => $type]);
  786.                 $alias 'vc' $cType->getId();
  787.                 $fKey 'charId' $cType->getId();
  788.                 $tKey 'cids' $cType->getId();
  789.                 $query->join('v.characteristics'$alias);
  790.                 foreach (array_keys($params) as $vchUrl) {
  791.                     $cValue $this->em->getRepository(\CoreBundle\Entity\Vehicles\CharacteristicValue::class)->findOneBy(['url' => $vchUrl'characteristic' => $cType]);
  792.                     if ($cValue) {
  793.                         $cvIds[] = $cValue->getId();
  794.                     }
  795.                 }
  796.                 if (!empty($cvIds)) {
  797.                     $query->andWhere($alias '.characteristic = :' $fKey)->setParameter($fKey$cType->getId());
  798.                     $query->andWhere($alias '.characteristic_value IN (:' $tKey ')')->setParameter($tKey$cvIds);
  799.                 }
  800.             }
  801.         }
  802.         $allResult $query->getQuery()->getResult();
  803.         $totalCount count($allResult);
  804.         $prices = [];
  805.         $pricesUsd = [];
  806.         $dollar $this->em->getRepository(Dealer::class)->find(6)->getRate();
  807.         if($totalCount){
  808.             foreach ($allResult as $oneResult) {
  809.                     $prices[] = ceil($oneResult['price']);
  810.                     $pricesUsd[] = ceil($oneResult['price'] / $dollar);
  811.             }
  812.         }
  813.         $dataPrice = [
  814.           'minPrice' => $totalCount min($prices) : 0,
  815.           'maxPrice' => $totalCount max($prices) : 0,
  816.           'minPriceUsd' => $totalCount min($pricesUsd) : 0,
  817.           'maxPriceUsd' => $totalCount max($pricesUsd) : 0,
  818.         ];
  819.         unset($allResult);
  820.         if($pageLimit) {
  821.             $limit $pageLimit;
  822.             $page = isset($searchParams['page']) && $searchParams['page'] != ''  $searchParams['page'] : 1;
  823.             $start = ($page 1) * $limit;
  824.         }
  825.         $query->groupBy('vi');
  826.         if (isset($searchParams['sortOrder'])) {
  827.             $sortData explode('-'$searchParams['sortOrder']);
  828.             $sortField $sortData[0] ?? 'price';
  829.             $sortAD = isset($sortData[1]) && in_array($sortData[1], ['ASC''DESC']) ? $sortData[1] : 'ASC';
  830.             switch ($sortField) {
  831.                 case 'price':
  832.                     $field $sortAD == 'DESC' 'price' 'orderPrice';
  833.                     $query->addOrderBy($field$sortAD);
  834.                     $query->addOrderBy('b.name''ASC');
  835.                     $query->addOrderBy('m.title''ASC');
  836.                     break;
  837.                 case 'year':
  838.                     $query->addOrderBy('vi.year'$sortAD);
  839.                     $query->addOrderBy('b.name''ASC');
  840.                     $query->addOrderBy('m.title''ASC');
  841.                     break;
  842.                 case 'mileage':
  843.                     $query->addOrderBy('vi.mileage'$sortAD);
  844.                     $query->addOrderBy('b.name''ASC');
  845.                     $query->addOrderBy('m.title''ASC');
  846.                     break;
  847.                 case 'addVehicle':
  848.                     $query->addOrderBy('ve.date_create'$sortAD);
  849.                     $query->addOrderBy('b.name''ASC');
  850.                     $query->addOrderBy('m.title''ASC');
  851.                     break;
  852.                 default:
  853.                     $query->addOrderBy('orderPrice''ASC');
  854.                     $query->addOrderBy('b.name''ASC');
  855.                     $query->addOrderBy('m.title''ASC');
  856.                     break;
  857.             }
  858.         } else {
  859.             $query->addOrderBy('orderPrice''ASC');
  860.         }
  861.         if($pageLimit) {
  862.             $query->setFirstResult($start)->setMaxResults($limit);
  863.         }
  864.         $data $query->getQuery()->getResult();
  865.         return [
  866.             'count' => $totalCount,
  867.             'dataPrice' => $dataPrice,
  868.             'data' => $data
  869.         ];
  870.     }
  871.     public function noFindVehicleByParams($pageLimit 21)
  872.     {
  873.         $vehicleTypeData $this->getVehicleType();
  874.         $query $this->em->getRepository(VehicleItem::class)
  875.             ->createQueryBuilder('vi')
  876.             ->addSelect('vi')
  877.             ->addSelect('CASE WHEN (d.id != 6) THEN CASE WHEN vi.alt_price > 0 THEN vi.alt_price / d.rate ELSE CASE WHEN vi.alt_rate > 0 THEN vi.alt_rate ELSE vi.price * d.rate END END ELSE CASE WHEN vi.alt_price > 0 THEN vi.alt_price  / d.rate ELSE vi.price / d.rate END END AS price')
  878.             ->addSelect('case when (case when (ve.is_used = 0 OR d.id != 6) then (case when vi.alt_price > 0 then vi.alt_price else (case when vi.alt_rate > 0  then vi.alt_rate * vi.price else vi.price * d.rate end) end) else (case when vi.alt_price > 0 then vi.alt_price else vi.price end) end) = 0 then 9999999999 else (case when (ve.is_used = 0 OR d.id != 6) then (case when vi.alt_price > 0 then vi.alt_price else (case when vi.alt_rate > 0  then vi.alt_rate * vi.price else vi.price * d.rate end) end) else (case when vi.alt_price > 0 then vi.alt_price else vi.price end) end) end as orderPrice')
  879.             ->join('vi.variation''v')
  880.             ->join('v.vehicle''ve'Join::WITH've.is_used = :isUsed')->setParameter('isUsed'true)
  881.             ->join('ve.dealer''d')
  882.             ->andWhere('ve.vehicle_type = :type')
  883.             //  TODO Навіщо ми перевіряємо vehicleItem state на вживаних авто? У вживаного авто є всього 1 vehicleItem, і ми маємо відображати авто по vehicle state. Якщо все буде ок, повидаляти з усіх запитів
  884.             //  ->andWhere('vi.state = 1')
  885.             ->andWhere('ve.state = 1')
  886.             ->andWhere('ve.is_not_filled = 0')
  887.             ->andWhere('ve.is_delete != 1')
  888.             ->setParameter('type'$vehicleTypeData['id'])
  889.             ->orderBy('v.id''DESC')
  890.             ->setMaxResults($pageLimit);
  891.         return [
  892.             'count' => 0,
  893.             'dataPrice' => ['minPrice' => 0,'maxPrice' => 0,'minPriceUsd' => 0,'maxPriceUsd' =>  0],
  894.             'data' => $query->getQuery()->getResult(),
  895.         ];
  896.     }
  897.     public function getBreadcrumbs()
  898.     {
  899.         $translator $this->translator;
  900.         $router $this->router;
  901.         $request $this->requestStack->getCurrentRequest();
  902.         $routeParams $request->attributes->get('_route_params');
  903.         $vehicleTypeData $this->getVehicleType();
  904.         $catalogCharacteristic $this->getCharacteristicsByParams($vehicleTypeData['id']);
  905.         $catalogRecommendGroup $this->getRecommendGroupByParams($vehicleTypeData['id']);
  906.         $breadcrumbs = [];
  907.         $state $routeParams['state'] ?? null;
  908.         $type $routeParams['type'] ?? null;
  909.         $brand $routeParams['brand'] ?? null;
  910.         $model $routeParams['model'] ?? null;
  911.         $param $routeParams['param'] ?? null;
  912.         $value $routeParams['value'] ?? null;
  913.         $param2 $routeParams['param2'] ?? null;
  914.         $value2 $routeParams['value2'] ?? null;
  915.         $price $routeParams['price'] ?? null;
  916.         $recommendGroup $routeParams['recommendGroup'] ?? null;
  917.         $CharacteristicValue $catalogCharacteristic[$param][$value] ?? null;
  918.         $CharacteristicValue2 $catalogCharacteristic[$param2][$value2] ?? null;
  919.         $recommendGroupValue $catalogRecommendGroup[$recommendGroup] ?? null;
  920.         if($state && $type){
  921.             $breadcrumbs[] = [
  922.               'title' => $translator->trans('catalog.' $state '_' $type, [], 'automarket_base'),
  923.               'url' => $router->generate('automarket_catalog', ['state' => $state'type' => $type]),
  924.             ];
  925.         }
  926.         if($brand){
  927.             $breadcrumbs[] = [
  928.                 'title' => $brand,
  929.                 'url' => $router->generate('automarket_catalog_brand', ['state' => $state'type' => $type'brand' => $brand]),
  930.             ];
  931.         }
  932.         if($brand && $model){
  933.             $breadcrumbs[] = [
  934.                 'title' => $model,
  935.                 'url' => $router->generate('automarket_catalog_brand_model', ['state' => $state'type' => $type'brand' => $brand'model' => $model]),
  936.             ];
  937.         }
  938.         if($recommendGroup){
  939.             $breadcrumbs[] = [
  940.                 'title' => $recommendGroupValue,
  941.                 'url' => $router->generate('automarket_catalog_vehicle_collections', ['state' => $state'type' => $type'recommendGroup' => $recommendGroup]),
  942.             ];
  943.         }
  944.         if($param && $value && !$brand && !$model){
  945.             $breadcrumbs[] = [
  946.                 'title' => $CharacteristicValue,
  947.                 'url' => $router->generate('automarket_catalog_characteristic', ['state' => $state'type' => $type'brand' => $brand'model' => $model'param' => $param'value' => $value]),
  948.             ];
  949.         }
  950.         if($param && $value && $param2 && $value2 && !$brand && !$model){
  951.             $breadcrumbs[] = [
  952.                 'title' => $CharacteristicValue2,
  953.                 'url' => $router->generate('automarket_catalog_characteristic_by_body', ['state' => $state'type' => $type'brand' => $brand'model' => $model'param' => $param'value' => $value'param2' => $param2'value2' => $value2]),
  954.             ];
  955.         }
  956.         if ($param && $value && $brand && !$model) {
  957.             $breadcrumbs[] = [
  958.                 'title' => $CharacteristicValue,
  959.                 'url' => $router->generate('automarket_catalog_brand_characteristic', ['state' => $state'type' => $type'brand' => $brand'param' => $param'value' => $value]),
  960.             ];
  961.         }
  962.         if($param && $value && $brand && $model){
  963.             $breadcrumbs[] = [
  964.                 'title' => $CharacteristicValue,
  965.                 'url' => $router->generate('automarket_catalog_brand_model_characteristic', ['state' => $state'type' => $type'brand' => $brand'model' => $model'param' => $param'value' => $value]),
  966.             ];
  967.         }
  968.         if($price && $param && $value  && $brand && $model){
  969.             $breadcrumbs[] = [
  970.                 'title' => 'до ' $price ' $',
  971.                 'url' => $router->generate('automarket_catalog_brand_model_characteristic_price', ['state' => $state'type' => $type'brand' => $brand'model' => $model'param' => $param'value' => $value'price' => $price]),
  972.             ];
  973.         }elseif($price && $brand && $model){
  974.             $breadcrumbs[] = [
  975.                 'title' => 'до ' $price ' $',
  976.                 'url' => $router->generate('automarket_catalog_brand_model_price', ['state' => $state'type' => $type'brand' => $brand'model' => $model'price' => $price]),
  977.             ];
  978.         }
  979.         return $breadcrumbs;
  980.     }
  981.     public function getSchemaCatalog()
  982.     {
  983.     }
  984. }