src/WebBundle/Repository/FilterRepository.php line 506

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Repository;
  3. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  4. use Doctrine\DBAL\Types\Types;
  5. use Doctrine\ORM\NonUniqueResultException;
  6. use Doctrine\ORM\NoResultException;
  7. use Doctrine\ORM\QueryBuilder;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use Exception;
  10. use FlexApp\Constant\TimeConstant;
  11. use FlexApp\DTO\BrandResponseDTO;
  12. use FlexApp\DTO\FilterCountryResponseDTO;
  13. use FlexApp\DTO\FilterResponseDTO;
  14. use FlexApp\Service\CacheService;
  15. use FlexApp\Service\RedisCachePool;
  16. use FlexApp\ValueObject\LocaleVo;
  17. use Import1CBundle\Helper\v3\BiConst;
  18. use Symfony\Contracts\Translation\TranslatorInterface;
  19. use Throwable;
  20. use WebBundle\Entity\FilterEntity;
  21. use WebBundle\Enum\FilterGroupEnum;
  22. use WebBundle\Helper\App;
  23. use WebBundle\Helper\ArrHelper;
  24. use WebBundle\Helper\HideFactoryCountriesHelper;
  25. use WebBundle\Helper\LocaleHelper;
  26. use WebBundle\Helper\PathHelper;
  27. use WebBundle\Helper\StrHelper;
  28. use WebBundle\Traits\RepoTrait;
  29. class FilterRepository extends ServiceEntityRepository
  30. {
  31.     use RepoTrait;
  32.     private const QUERY_CACHE_LIFETIME 600;
  33.     private CacheService $cacheService;
  34.     public function __construct(ManagerRegistry $registryCacheService $cacheService)
  35.     {
  36.         parent::__construct($registryFilterEntity::class);
  37.         $this->cacheService $cacheService;
  38.     }
  39.     public function joinQuery($alias 'f'): QueryBuilder
  40.     {
  41.         return $this->createQueryBuilder($alias)
  42.             ->SELECT(
  43.                 "$alias, url, page, param, brand, groups, articles, htmlShow, country, nameForMetaTitle, nameForMetaDescr"
  44.             )
  45.             ->leftJoin("$alias.url"'url')
  46.             ->leftJoin("$alias.page"'page')
  47.             ->leftJoin("$alias.param"'param')
  48.             ->leftJoin("$alias.brand"'brand')
  49.             ->leftJoin("brand.user"'user')
  50.             ->leftJoin("$alias.groups"'groups')
  51.             ->leftJoin("$alias.articles"'articles')
  52.             ->leftJoin("$alias.htmlShow"'htmlShow')
  53.             ->leftJoin("$alias.country"'country')
  54.             ->leftJoin("$alias.nameForMetaTitle"'nameForMetaTitle')
  55.             ->leftJoin("$alias.nameForMetaDescr"'nameForMetaDescr');
  56.     }
  57.     /**
  58.      * @param string $filterUrl
  59.      * @param string $locale
  60.      * @return FilterResponseDTO|null
  61.      * @throws \Doctrine\DBAL\Driver\Exception
  62.      * @throws \Doctrine\DBAL\Exception
  63.      */
  64.     public function getByKeyUrlIsLike(string $filterUrlstring $locale): ?FilterResponseDTO
  65.     {
  66.         return $this->getByUrl($filterUrl$localetrue);
  67.     }
  68.     /**
  69.      * @param string $filterUrl
  70.      * @param string $locale
  71.      * @return FilterResponseDTO|null
  72.      * @throws \Doctrine\DBAL\Driver\Exception
  73.      * @throws \Doctrine\DBAL\Exception
  74.      */
  75.     public function getByKeyUrl(string $filterUrlstring $locale): ?FilterResponseDTO
  76.     {
  77.         return $this->getByUrl($filterUrl$locale);
  78.     }
  79.     /**
  80.      * @param int|null $filterId
  81.      * @return array
  82.      * @throws \Doctrine\DBAL\Exception
  83.      */
  84.     public function getIDsForSynchCountFiltersOnlyParent(?int $filterId null): array
  85.     {
  86.         $filterId $filterId "AND (f.parent_id = '$filterId' OR f.id = '$filterId')" '';
  87.         $sql "SELECT DISTINCT f.parent_id
  88.                 FROM filters f
  89.                 WHERE f.parent_id IS NOT NULL $filterId
  90.                 ";
  91.         $conn $this->getEntityManager()->getConnection();
  92.         $ids $conn->fetchAllAssociative($sql);
  93.         if ($ids) {
  94.             $ids array_column($ids'parent_id');
  95.         }
  96.         return $ids;
  97.     }
  98.     /**
  99.      * Получаем subFilter
  100.      * @param bool $new
  101.      * @return array
  102.      * @throws \Doctrine\DBAL\Exception
  103.      */
  104.     public function getFiltersSubRelation(bool $new false): array
  105.     {
  106.         $where $new ' AND p.show_menu != 0 ' ' AND p.show_menu_advanced != 0';
  107.         $sql "SELECT
  108.     f2.id,
  109.     f2.name,
  110.     f2.old_command,
  111.     f2.old_id,
  112.     GROUP_CONCAT(f.id) AS ids,
  113.     GROUP_CONCAT(f.old_id) AS old_ids
  114. FROM
  115.     `filters` f
  116. LEFT JOIN filters f2 ON
  117.     f.parent_id = f2.id
  118. LEFT JOIN filter_params p ON
  119.     f.param_id = p.id
  120. WHERE
  121.     f.parent_id IS NOT NULL AND p.is_enable = 1 $where 
  122. GROUP BY
  123.     f.parent_id;";
  124.         $conn $this->getEntityManager()->getConnection();
  125.         $filterData $conn->fetchAllAssociative($sql);
  126.         $parentMap = [];
  127.         if ($new) {
  128.             foreach ($filterData as $row) {
  129.                 $ids explode(','$row['ids']);
  130.                 $parentMap[$row['id']] = $ids;
  131.             }
  132.         } else {
  133.             foreach ($filterData as $row) {
  134.                 $ids explode(','$row['old_ids']);
  135.                 $parentMap[$row['old_command']][$row['old_id']] = $ids;
  136.             }
  137.         }
  138.         return $parentMap;
  139.     }
  140.     /**
  141.      * Получение списка фильтров для синхронизации количества
  142.      * @param int $filterParentId
  143.      * @return array
  144.      */
  145.     public function getListForSynchCountFiltersOnlyChildren(int $filterParentId): array
  146.     {
  147.         $q $this->createQueryBuilder('f')
  148.             ->select(
  149.                 'f.id id, f.name name, f.oldId oldId, f.oldCommand oldCommand, parent.id pid, param.id fpId, param.count fpCount'
  150.             )
  151.             ->leftJoin('f.param''param')
  152.             ->leftJoin('f.parent''parent')
  153.             ->andWhere('parent.id = :pid')->setParameter('pid'$filterParentId)
  154.             ->andWhere('f.oldCommand != :bm')->setParameter('bm''bm'// исключаем из проверок фильтр БМом
  155.         ;
  156.         $q $q->getQuery();
  157.         return $q->getArrayResult();
  158.     }
  159.     /**setCollections
  160.      * Получение списка фильтров для синхронизации количества
  161.      * WebBundle/Command/SynchronizeCommand::runSynchCountFilters()
  162.      * @param array|null $filterIds
  163.      * @param array|null $fidsExclude
  164.      * @return array|null
  165.      */
  166.     public function getListForSynchCountFilters(?array $filterIds = [], ?array $fidsExclude = []): ?array
  167.     {
  168.         $q $this->createQueryBuilder('f')
  169.             ->select(
  170.                 'f.id id, f.name name, f.oldId oldId, f.oldCommand oldCommand, parent.id pid, param.id fpId, param.count fpCount'
  171.             )
  172.             ->leftJoin('f.param''param')
  173.             ->leftJoin('f.parent''parent')
  174.             ->andWhere('f.oldCommand != :bm')->setParameter('bm''bm'// исключаем из проверок фильтр БМом
  175.         ;
  176.         if ($filterIds) {
  177.             $q->andWhere('f.id IN (:filterId)')->setParameter('filterId'$filterIds);
  178.         }
  179.         if ($fidsExclude) {
  180.             $q->andWhere('f.id NOT IN (:filterIdExclude)')->setParameter('filterIdExclude'$fidsExclude);
  181.         }
  182.         $q $q->getQuery();
  183.         return $q->getArrayResult();
  184.     }
  185.     public function getListForOneC(): array
  186.     {
  187.         $q $this->joinQuery('f');
  188.         $r $q->getQuery();
  189.         $cacheName $this->buildCacheName('filter', ['getListForOneC']);
  190.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  191.         return $r->getArrayResult();
  192.     }
  193.     /**
  194.      * @param array $oldIds
  195.      * @param string $oldCommand
  196.      * @param string $locale
  197.      * @return array|FilterResponseDTO[]
  198.      * @throws \Doctrine\DBAL\Driver\Exception
  199.      * @throws \Doctrine\DBAL\Exception
  200.      */
  201.     public function getByOldCommand(array $oldIdsstring $oldCommandstring $locale): array
  202.     {
  203.         $oldIds array_map('intval'$oldIds);
  204.         $oldIds array_unique($oldIds);
  205.         $oldIds array_filter($oldIds);
  206.         if ($oldIds) {
  207.             $fidsStr implode(','$oldIds);
  208.             $fidsStr "f.old_id IN ($fidsStr) AND";
  209.         } else {
  210.             $fidsStr '';
  211.         }
  212.         $sql "SELECT f.id AS `id` FROM filters f WHERE $fidsStr f.old_command = '$oldCommand'";
  213.         return $this->getKeysBySql($sql$locale);
  214.     }
  215.     /**
  216.      * @param string $filterAltName
  217.      * @param string $locale
  218.      * @return FilterResponseDTO[]
  219.      * @throws \Doctrine\DBAL\Driver\Exception
  220.      * @throws \Doctrine\DBAL\Exception
  221.      */
  222.     public function getFilterDTOByAltName(string $filterAltNamestring $locale): array
  223.     {
  224.         $sql "SELECT f.id AS `id` FROM filters f WHERE f.alt_name = '$filterAltName'";
  225.         return $this->getKeysBySql($sql$locale);
  226.     }
  227.     /**
  228.      * Получаем key для URL для дизайнерского стиля
  229.      * @param null $lc
  230.      * @return mixed|null
  231.      */
  232.     public function getKeyDesignerStyle($lc null)
  233.     {
  234.         $lc $lc ?: LocaleHelper::getCurLocale();
  235.         $q $this->createQueryBuilder('f');
  236.         $q->select("url.$lc")
  237.             ->leftJoin('f.url''url')
  238.             ->andWhere("f.altName = :filterAltName")
  239.             ->setParameter('filterAltName''designer')
  240.             ->setMaxResults(1);
  241.         $cacheName $this->buildCacheName('filter_designer_style', [$lc]);
  242.         $r $q->getQuery()->useQueryCache(true)->enableResultCache(TimeConstant::WEEK$cacheName);
  243.         try {
  244.             $item $r->getSingleResult();
  245.             $item $item[$lc];
  246.         } catch (Exception $e) {
  247.             return null;
  248.         }
  249.         return $item;
  250.     }
  251.     /**
  252.      * @param null $filterAltName
  253.      * @param null $groupAltName
  254.      * @param bool $isLike
  255.      * @return mixed
  256.      */
  257.     public function getByAltName($filterAltName null$groupAltName nullbool $isLike false)
  258.     {
  259.         $aParams = [];
  260.         $operate $isLike 'LIKE' '=';
  261.         $q $this->createQueryBuilder('f');
  262.         $q->select('f, groups, page, url, nameForMetaTitle, nameForMetaDescr')
  263.             ->leftJoin('f.groups''groups')
  264.             ->leftJoin('f.page''page')
  265.             ->leftJoin('f.url''url')
  266.             ->leftJoin('f.nameForMetaTitle''nameForMetaTitle')
  267.             ->leftJoin('f.nameForMetaDescr''nameForMetaDescr');
  268.         if ($filterAltName) {
  269.             $q->andWhere("f.altName $operate :filterAltName");
  270.             if ($isLike) {
  271.                 $filterAltName '%' $filterAltName '%';
  272.             }
  273.             $aParams['filterAltName'] = $filterAltName;
  274.         }
  275.         if ($groupAltName) {
  276.             $q->andWhere("groups.altName $operate :groupAltName");
  277.             if ($isLike) {
  278.                 $groupAltName '%' $groupAltName '%';
  279.             }
  280.             $aParams['groupAltName'] = $groupAltName;
  281.         }
  282.         $q->setParameters($aParams);
  283.         $r $q->getQuery();
  284.         $cacheName $this->buildCacheName('filter_getByAltName', [$filterAltName$groupAltName]);
  285.         $r->useQueryCache(true)->enableResultCache(TimeConstant::DAY$cacheName);
  286.         return $r->getResult();
  287.     }
  288.     /**
  289.      * @param int $oldId
  290.      * @return array
  291.      * @throws \Doctrine\DBAL\Exception
  292.      */
  293.     public function getFilterIdsByOldId(int $oldId): array
  294.     {
  295.         $sql "SELECT f.id
  296.                 FROM filters f
  297.                 WHERE f.old_id = $oldId
  298.                 ";
  299.         $memcache $this->cacheService->getMemcache();
  300.         $memcacheKey md5($sql);
  301.         $ids $memcache->get($memcacheKey);
  302.         if ($ids) {
  303.             return $ids;
  304.         }
  305.         $conn $this->getEntityManager()->getConnection();
  306.         $ids $conn->fetchAllAssociative($sql);
  307.         $memcache->set($memcacheKey$ids);
  308.         return $ids;
  309.     }
  310.     /**
  311.      * Получение одного ID по OldID
  312.      * @param int $oldId
  313.      * @param string $oldCommand
  314.      * @return int|null
  315.      */
  316.     public function getFilterIdByOldId(int $oldIdstring $oldCommand): ?int
  317.     {
  318.         $sql "SELECT f.id FROM filters f WHERE f.old_id = '$oldId' AND f.old_command = '$oldCommand' LIMIT 1";
  319.         $memcache $this->cacheService->getMemcache();
  320.         $memcacheKey md5($sql);
  321.         $id $memcache->get($memcacheKey);
  322.         if ($id) {
  323.             return $id;
  324.         }
  325.         try {
  326.             $conn $this->getEntityManager()->getConnection();
  327.             $id $conn->executeQuery($sql)->fetchOne();
  328.         } catch (Throwable $e) {
  329.             return null;
  330.         }
  331.         if ($id) {
  332.             $id = (int) $id;
  333.             $memcache->set($memcacheKey$id);
  334.         }
  335.         return $id ?: null;
  336.     }
  337.     /**
  338.      * Получение массива ID по массиву OldID
  339.      * @param array $oldIds
  340.      * @param string $oldCommand
  341.      * @return array
  342.      * @throws \Doctrine\DBAL\Exception
  343.      */
  344.     public function getFilterIdsByOldIds(array $oldIdsstring $oldCommand): array
  345.     {
  346.         $conn $this->getEntityManager()->getConnection();
  347.         $isDesigner $oldCommand == 'getDesigner';
  348.         $oldCommand $conn->quote($oldCommand);
  349.         $oldIds array_map('intval'array_filter($oldIds'is_numeric'));
  350.         $oldIds implode("', '"$oldIds);
  351.         $oldIds "'$oldIds'";
  352.         $sql "SELECT f.id FROM filters f WHERE f.old_id IN ($oldIds) AND f.old_command = $oldCommand;";
  353.         // для дизайнеров дополнительно ищем по f.id
  354.         if ($isDesigner) {
  355.             $sql "SELECT f.id FROM filters f WHERE (f.old_id IN ($oldIds) OR f.id IN ($oldIds)) AND f.old_command = $oldCommand;";
  356.         }
  357.         $memcache $this->cacheService->getMemcache();
  358.         $memcacheKey md5($sql);
  359.         $ids $memcache->get($memcacheKey);
  360.         if ($ids) {
  361.             return $ids;
  362.         }
  363.         $ids $conn->fetchAllAssociative($sql);
  364.         if ($ids) {
  365.             $ids array_column($ids'id');
  366.         } else {
  367.             $ids = [];
  368.         }
  369.         $memcache->set($memcacheKey$ids);
  370.         return $ids;
  371.     }
  372.     /**
  373.      * Поиск фильтра по url значению
  374.      * @code (
  375.      *     $oRepoFilters->getByKeyUrl('bathroom');
  376.      *     $oRepoFilters->getByKeyUrl('bathroom', 'en');
  377.      * )
  378.      * @param string $filterSlug URL имя фильтра
  379.      * @param string $lc Локаль
  380.      * @param bool $isLike
  381.      * @return FilterResponseDTO|null
  382.      * @throws \Doctrine\DBAL\Driver\Exception
  383.      * @throws \Doctrine\DBAL\Exception
  384.      */
  385.     private function getByUrl(string $filterSlugstring $lcbool $isLike false): ?FilterResponseDTO
  386.     {
  387.         $aLocales LocaleHelper::getListAvailable();
  388.         $aLocales array_column($aLocales'code');
  389.         $andWhere '';
  390.         if ($isLike) {
  391.             $filterSlug '%' $filterSlug '%';
  392.         }
  393.         foreach ($aLocales as $loc) {
  394.             if ($isLike) {
  395.                 $andWhere .= "url.$loc LIKE :slug OR ";
  396.             } else {
  397.                 $andWhere .= "url.$loc = :slug OR ";
  398.             }
  399.         }
  400.         $andWhere trim(trim($andWhere), 'OR');
  401.         $sql $this->buildSQLSelectForFilterResponseDTO($lc);
  402.         $sql "$sql WHERE $andWhere";
  403.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  404.         $memcache $this->cacheService->getMemcache();
  405.         $memcacheKey $filterSlug md5($sql);
  406.         $dtoArray $memcache->get($memcacheKey);
  407.         if ($dtoArray) {
  408.             return $this->buildFilterResponseDTO($dtoArray);
  409.         }
  410.         $conn $this->getEntityManager()->getConnection();
  411.         $stmt $conn->prepare($sql);
  412.         $stmt->bindValue("slug"$filterSlugTypes::STRING);
  413.         $item $stmt->executeQuery()->fetchAllAssociative();
  414.         if (!$item) {
  415.             return null;
  416.         }
  417.         // если значений несколько, значит не корректный запрос по каким-то причинам
  418.         if (count($item) > 1) {
  419.             return null;
  420.         }
  421.         $memcache->set($memcacheKey$item[0]);
  422.         return $this->buildFilterResponseDTO($item[0]);
  423.     }
  424.     /**
  425.      * @param $altNames
  426.      * @return float|int|mixed|string
  427.      */
  428.     public function getByAltNames($altNames)
  429.     {
  430.         $q $this->joinQuery('f');
  431.         $altNames is_string($altNames) ? explode(','$altNames) : $altNames;
  432.         $q->andWhere('f.altName IN (:altNames)');
  433.         $q->addOrderBy('groups.sort''ASC');
  434.         $q->addOrderBy('f.sort''ASC');
  435.         $q->setParameter('altNames'$altNames);
  436.         $r $q->getQuery();
  437.         $cacheName $this->buildCacheName('filter_getByAltNames'$altNames);
  438.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  439.         return $r->getResult();
  440.     }
  441.     /**
  442.      * @param array $ids
  443.      * @param string $lc
  444.      * @return array|FilterResponseDTO[]
  445.      * @throws \Doctrine\DBAL\Driver\Exception
  446.      * @throws \Doctrine\DBAL\Exception
  447.      */
  448.     public function getSortedByIds(array $idsstring $lc)
  449.     {
  450.         if (!$ids) {
  451.             return [];
  452.         }
  453.         $conn $this->getEntityManager()->getConnection();
  454.         $inQuery implode(','array_fill(0count($ids), '?'));
  455.         $sql $this->buildSQLSelectForFilterResponseDTO($lc);
  456.         $sql "$sql WHERE f.id IN ($inQuery) ORDER BY gr.sort, f.sort";
  457.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  458.         $memcache $this->cacheService->getMemcache();
  459.         $memcacheKey md5($sql) . implode('.'$ids);
  460.         $rows $memcache->get($memcacheKey);
  461.         if ($rows) {
  462.             return $rows;
  463.         }
  464.         $stmt $conn->prepare($sql);
  465.         foreach ($ids as $i => $id) {
  466.             $stmt->bindValue(($i 1), $id);
  467.         }
  468.         $items $stmt->executeQuery()->fetchAllAssociative();
  469.         $rows = [];
  470.         foreach ($items as $item) {
  471.             $row $this->buildFilterResponseDTO($item);
  472.             if ($row) {
  473.                 $rows[] = $row;
  474.             }
  475.         }
  476.         $memcache->set($memcacheKey$rows);
  477.         return $rows;
  478.     }
  479.     /**
  480.      * Осноной запрос получения фильтров из базы по ID с сортировкой по Filter SORT и FilterGroup SORT
  481.      * @param      $id
  482.      * @param bool $toArray
  483.      * @return array|null
  484.      */
  485.     public function getByIds($idbool $toArray false)
  486.     {
  487.         $q $this->joinQuery('f');
  488.         $ids is_string($id) ? explode(','$id) : $id;
  489.         if (count($ids) == 1) {
  490.             $q->andWhere('f.id = :ids');
  491.         } else {
  492.             $q->andWhere('f.id IN (:ids)');
  493.         }
  494.         $q->andWhere('f.id IN (:ids)');
  495.         $q->addOrderBy('groups.sort''ASC');
  496.         $q->addOrderBy('f.sort''ASC');
  497.         $q->setParameter('ids'$ids);
  498.         $r $q->getQuery();
  499.         $cacheName $this->buildCacheName('filter_getByIds'$id);
  500.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  501.         if ($toArray) {
  502.             $items $r->getArrayResult();
  503.         } else {
  504.             $items $r->getResult();
  505.         }
  506.         return $items;
  507.     }
  508.     /**
  509.      * Осноной запрос получения фильтров из базы по ID с сортировкой по Filter SORT и FilterGroup SORT
  510.      * @param $altName
  511.      * @return array|null
  512.      */
  513.     public function getByGroupAlias($altName)
  514.     {
  515.         $q $this->joinQuery('f');
  516.         $q->andWhere('groups.altName = :altName');
  517.         $q->addOrderBy('groups.sort''ASC');
  518.         $q->setParameter('altName'$altName);
  519.         $r $q->getQuery();
  520.         $cacheName $this->buildCacheName('filter_getByGroupAlias'$altName);
  521.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  522.         $items $r->getResult();
  523.         return (count($items) == 1) ? $items[0] : $items;
  524.     }
  525.     public function getListDesignersByGroupAlias($altName)
  526.     {
  527.         $q $this->joinQuery('f');
  528.         $q->andWhere('groups.altName = :altName');
  529.         $q->andWhere('param.count > 0');
  530.         $q->addOrderBy('f.name''ASC');
  531.         $q->addOrderBy('groups.sort''ASC');
  532.         $q->setParameter('altName'$altName);
  533.         $r $q->getQuery();
  534.         $cacheName $this->buildCacheName('filter_getListDesignersByGroupAlias'$altName);
  535.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  536.         return $r->getResult();
  537.     }
  538.     /**
  539.      * Формирование массива ссылок на фильтры в футере
  540.      * @return array
  541.      * @throws Exception
  542.      */
  543.     public function getForFooterByGroupAlias(): array
  544.     {
  545.         $memcache $this->cacheService->getMemcache();
  546.         $lcFull App::getCurLocale(true);
  547.         $list $memcache->get('footer.links.filter.' App::isDev() . $lcFull);
  548.         if (!$list) {
  549.             $ids = [1004010136101321011110147106171064610146];
  550.             $idsStr '10040,10136,10132,10111,10147,10617,10646,10146';
  551.             $locales LocaleHelper::getListAvailable();
  552.             $router App::getContainer()->get('router');
  553.             $translator App::getTranslator();
  554.             $urlStrSql = [];
  555.             foreach ($locales as $item) {
  556.                 $urlStrSql[] = "url.{$item['code']} AS `url.{$item['code']}`";
  557.             }
  558.             $urlStrSql implode(', '$urlStrSql);
  559.             $sql "SELECT
  560.                 f.id,
  561.                 f.left_menu AS leftMenu, $urlStrSql
  562.                 FROM filters f
  563.                 LEFT JOIN `locale_url` `url` ON `url`.filter_id = f.id
  564.                 WHERE f.id IN ($idsStr)
  565.                 ";
  566.             $sql preg_replace('/[\s\n\r]+/'' '$sql);
  567.             $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  568.             // в многомерные массивы переводим
  569.             foreach ($items as $i => $item) {
  570.                 foreach ($item as $k => $v) {
  571.                     if (preg_match("~(.*)\.(.*)~ui"$k$out)) {
  572.                         $k1 $out[1];
  573.                         $k2 $out[2];
  574.                         if (empty($item[$k1])) {
  575.                             $item[$k1] = [];
  576.                         }
  577.                         $item[$k1][$k2] = $v;
  578.                         unset($item[$k]);
  579.                     }
  580.                 }
  581.                 $items[$i] = $item;
  582.             }
  583.             $ids array_flip($ids);
  584.             $lc_ App::getCurLocale();
  585.             // выставляем порядок и сразу формируем имя и урл
  586.             foreach ($items as $i => $item) {
  587.                 $key $item['leftMenu'] . '_footer';
  588.                 //$key = $item['leftMenu'];
  589.                 $name $translator->trans($key, [], null$lc_);
  590.                 $ids[$item['id']] = [
  591.                     'name' => $name,
  592.                     'url' => urldecode(
  593.                         $router->generate(
  594.                             'app_catalog',
  595.                             [
  596.                                 'key' => $item['url'][$lc_],
  597.                                 '_locale' => $lcFull,
  598.                             ]
  599.                         )
  600.                     ),
  601.                 ];
  602.             }
  603.             $list $ids;
  604.             $memcache->add('footer.links.filter.' App::isDev() . $lcFull$listfalse3600 24 30);
  605.         }
  606.         return $list;
  607.     }
  608.     /**
  609.      * Получение фабрики через фильтры.
  610.      * @param array $param
  611.      * @return array|null
  612.      * @throws NonUniqueResultException
  613.      * @throws Exception
  614.      * @see WebBundle/Repository/FactoryRepository::getFactory()
  615.      */
  616.     public function getBrand(array $param = [])
  617.     {
  618.         if (!empty($param['count'])) {
  619.             $q $this->createQueryBuilder('f')
  620.                 ->select('COUNT(f.id)')
  621.                 ->leftJoin('f.brand''brand')
  622.                 ->leftJoin('f.param''param');
  623.         } else {
  624.             $q $this->joinQuery('f');
  625.         }
  626.         $q
  627.             ->andWhere('f.brand IS NOT NULL')
  628.             ->andWhere('f.id != 10639')// 10639 это тестовая фабрика, выкидываем ее
  629.             ->andWhere('brand.status = :status')
  630.             ->andWhere('param.isEnabled = true')
  631.             ->andWhere('param.count >= 0')
  632.             ->andWhere('brand.unid IS NOT NULL')
  633.             ->setParameter('status'BiConst::STATE_PUBLISHED)
  634.             ->orderBy('f.name');
  635.         if (!empty($param['url'])) {
  636.             $q->andWhere('f.url = :url')
  637.                 ->setParameter('url'$param['url']);
  638.         }
  639.         if (!empty($param['name'])) {
  640.             $q->andWhere('f.name = :name')
  641.                 ->setParameter('name'$param['name']);
  642.         }
  643.         if (!empty($param['id'])) {
  644.             $q->andWhere('f.id = :filterId');
  645.             $q->setParameter('filterId'$param['id']);
  646.         }
  647.         if (!App::isRole('ROLE_TEST')) {
  648.             $q->andWhere('brand.testAccess IS NULL');
  649.         }
  650.         $r $q->getQuery();
  651.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
  652.         if (!empty($param['count'])) {
  653.             $items $r->getSingleScalarResult();
  654.         } else {
  655.             if (empty($param['asArray'])) {
  656.                 $items $r->getResult();
  657.             } else {
  658.                 $items $r->getArrayResult();
  659.             }
  660.         }
  661.         return $items;
  662.     }
  663.     /**
  664.      * Хелпер по получению записей брендов
  665.      * @param array $param
  666.      * @return array|null
  667.      */
  668.     public function getBrands(array $param = [])
  669.     {
  670.         $parameters = [];
  671.         $q $this->joinQuery('f');
  672.         $q
  673.             ->andWhere("groups.altName = 'brand'")
  674.             //->andWhere('f.brand IS NOT NULL')
  675.             //->addSelect('country')
  676.             //->leftJoin('brand.country', 'country')
  677.         ;
  678.         if (!is_array($param)) {
  679.             $paramId intval($param);
  680.             if ($paramId) {
  681.                 $param = ['id' => $paramId];
  682.             }
  683.         }
  684.         if (!empty($param['id'])) {
  685.             $q->andWhere('f.id = :brandId');
  686.             $parameters['brandId'] = $param['id'];
  687.         }
  688.         if (isset($param['noBrand'])) {
  689.             $q->andWhere('f.brand IS NULL');
  690.         }
  691.         if (!empty($param['factoryId'])) {
  692.             $q->andWhere('f.brand = :factoryId');
  693.             $parameters['factoryId'] = $param['factoryId'];
  694.         }
  695.         if (!empty($param['name'])) {
  696.             $q->andWhere('f.name = :name');
  697.             $parameters['name'] = $param['name'];
  698.         }
  699.         if (count($parameters) > 0) {
  700.             $q->setParameters($parameters);
  701.         }
  702.         $r $q->getQuery();
  703.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
  704.         if (empty($param['asArray'])) {
  705.             $items $r->getResult();
  706.         } else {
  707.             $items $r->getArrayResult();
  708.         }
  709.         return $items;
  710.     }
  711.     /**
  712.      * Получение списка фильтров для меню фильтрации
  713.      * @return array|null
  714.      */
  715.     public function getArrListForFilterMenu()
  716.     {
  717.         $q $this->joinQuery('f');
  718.         $q
  719.             ->andWhere('param.isEnabled = 1')
  720.             //->andWhere('param.showMenuAdvanced = 1')
  721.             //->andWhere('param.count > 0')
  722.             //->andWhere("(param.showMenuAdvanced = 1 AND f.oldCommand != 'factory')")
  723.             ->orderBy('f.sort ASC, f.name');
  724.         $r $q->getQuery();
  725.         $r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
  726.         return $r->getResult();
  727.     }
  728.     /**
  729.      * Выборка для расширенного меню фильтров
  730.      * @param $lc
  731.      * @return array
  732.      * @throws \Doctrine\DBAL\Exception
  733.      */
  734.     public function getArrListForFilterMenuNew($lc): array
  735.     {
  736.         $sql "SELECT
  737.                 f.id,
  738.                 f.alt_name AS `altName`,
  739.                 f.sort AS `sort`,
  740.                 f.parent_id AS `pid`,
  741.                 f.old_command AS `oldCommand`,
  742.                 fp.name_menu_$lc AS `name`,
  743.                    u.$lc AS `url`,
  744.                 p.count AS `count`,
  745.                 p.hex_code AS `hexCode`,
  746.                 p.show_menu_advanced AS `showMenuAdvanced`,
  747.                 g.id AS `group.id`,
  748.                 g.alt_name AS `group.altName`,
  749.                 gname.$lc AS `group.name`,
  750.                 tooltip.$lc AS `tooltip`,
  751.                 c.id AS `country.id`,
  752.                 c.old_id AS `country.code`,
  753.                    c.alt_name AS `country.altName`,
  754.                 cp.name_menu_$lc AS `country.name`,
  755.                 b.id AS `brand.id`,
  756.                 b.name AS `brand.name`
  757.             FROM
  758.                 filters f
  759.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  760.             LEFT JOIN filter_params p ON p.id = f.param_id
  761.             LEFT JOIN filter_groups g ON g.id = f.group_id
  762.             LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
  763.             LEFT JOIN locale_text tooltip ON tooltip.filter_tooltip = f.id
  764.             LEFT JOIN filters c ON c.id = f.country_id
  765.             LEFT JOIN filter_pages cp ON cp.id = c.page_id
  766.             LEFT JOIN locale_url u ON u.filter_id = f.id
  767.             LEFT JOIN factory b ON b.id = f.brand
  768.             WHERE (g.alt_name <> 'brand' AND p.show_menu_advanced = 1 OR g.alt_name = 'brand' AND b.status = 1) AND
  769.             (p.count > 0 OR g.alt_name = 'brand' OR g.alt_name = 'reviews') AND
  770.             p.is_enable = 1 AND p.hide != 1 AND p.hide_all != 1 AND f.id != '10639'
  771.             ORDER BY f.sort, f.name";
  772.         $memcache $this->cacheService->getMemcache();
  773.         $memcacheKey md5($sql);
  774.         $rows $memcache->get($memcacheKey);
  775.         if ($rows) {
  776.             return $rows;
  777.         }
  778.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  779.         $rows = [];
  780.         foreach ($items as $item) {
  781.             $name $item['name'];
  782.             $group = [
  783.                 'id' => intval($item['group.id']),
  784.                 'name' => $item['group.name'],
  785.                 'altName' => $item['group.altName'],
  786.             ];
  787.             // выносим в отдельную категорию крупный размер плитки
  788.             if ($item['oldCommand'] == 'size_big') {
  789.                 $group = [
  790.                     'id' => 0,
  791.                     'name' => 'Other',
  792.                     'altName' => 'other',
  793.                 ];
  794.             }
  795.             $country null;
  796.             if (!empty($item['country.id'])) {
  797.                 $country = [
  798.                     'id' => intval($item['country.id']),
  799.                     'code' => intval($item['country.code']),
  800.                     'name' => $item['country.name'],
  801.                     'altName' => $item['country.altName'],
  802.                 ];
  803.             }
  804.             $brand null;
  805.             if (!empty($item['brand.id'])) {
  806.                 $brand = [
  807.                     'id' => intval($item['brand.id']),
  808.                     'name' => $item['brand.name'],
  809.                 ];
  810.                 // меняем основное имя на имя фабрики, на всякий случай
  811.                 $name $item['brand.name'];
  812.             }
  813.             // ID родительского фильтра
  814.             $pid intval($item['pid']);
  815.             $pid $pid ?: null;
  816.             // исключил все случайно попадающие награды в список фильтров
  817.             if ($group['altName'] == 'rewards') {
  818.                 if ($item['id'] != '10546') {
  819.                     continue;
  820.                 }
  821.             }
  822.             $row = [
  823.                 'id' => intval($item['id']),
  824.                 'pid' => $pid,
  825.                 'name' => $name,
  826.                 'altName' => $item['altName'],
  827.                 'tooltip' => $item['tooltip'],
  828.                 'oldCommand' => $item['oldCommand'],
  829.                 'key' => $item['url'],
  830.                 'hexCode' => $item['hexCode'],
  831.                 'count' => intval($item['count']),
  832.                 'sort' => intval($item['sort']),
  833.                 'showMenuAdvanced' => boolval($item['showMenuAdvanced']),
  834.                 'group' => $group,
  835.                 'brand' => $brand,
  836.                 'country' => $country,
  837.                 'collection' => [],
  838.                 'selected' => [],
  839.                 'sub' => [],
  840.                 'groupList' => [],
  841.             ];
  842.             $rows[$row['id']] = $row;
  843.         }
  844.         $memcache->set($memcacheKey$rows);
  845.         return $rows;
  846.     }
  847.     /**
  848.      * Получаем массив всех фильтров для меню
  849.      * @param null $groups
  850.      * @param      $lc
  851.      * @param bool $ignoreEnabled
  852.      * @return array|null
  853.      * @throws Exception
  854.      */
  855.     public function getArrListForMenu($groups$lcbool $ignoreEnabled false): ?array
  856.     {
  857.         $lcUc ucfirst($lc);
  858.         $selectByLc "url.$lc url$lcUc, page.nameMenu$lcUc pageNameMenu$lcUc,";
  859.         // костыль для фильтра цен, что бы показывать верно для разных стран
  860.         $lcPrice LocaleHelper::getLocaleForPriceFilter($lc);
  861.         if ($lc != $lcPrice) {
  862.             $lcUcPrice ucfirst($lcPrice);
  863.             $selectByLc .= "url.$lcPrice url$lcUcPrice, page.nameMenu$lcUcPrice pageNameMenu$lcUcPrice,";
  864.         }
  865.         $q $this->createQueryBuilder('f')
  866.             ->select(
  867.                 "
  868.             f,
  869.             f.id,
  870.             f.oldCommand,
  871.             f.oldId,
  872.             f.leftMenu,
  873.             parent.id pid,
  874.             f.important,
  875.             $selectByLc
  876.             groups.altName groupsAltName,
  877.             param.count paramCount,
  878.             country
  879.             "
  880.             )
  881.             ->leftJoin('f.url''url')
  882.             ->leftJoin('f.page''page')
  883.             ->leftJoin('f.param''param')
  884.             ->leftJoin('f.groups''groups')
  885.             ->leftJoin('f.country''country')
  886.             ->leftJoin('f.parent''parent');
  887.         if (!$ignoreEnabled) {
  888.             $q
  889.                 ->andWhere('param.isEnabled = 1')
  890.                 ->andWhere('param.showMenu = 1 OR param.showMenuAdvanced = 1')
  891.                 ->andWhere('url.' $lc '  is not null')
  892.                 ->andWhere('param.count > 0');
  893.         }
  894.         $q->orderBy('f.sort ASC, f.name');
  895.         if ($groups) {
  896.             $groups is_array($groups) ? $groups : [$groups];
  897.             $q->andWhere('groups.altName IN (:groups)')
  898.                 ->setParameter('groups'$groups);
  899.         }
  900.         $r $q->getQuery();
  901.         $cacheName $this->buildCacheName('filter_getArrListForMenu2_' $lc $lcPrice$groups);
  902.         $r->useQueryCache(true);
  903.         if (!App::isDev() or !$ignoreEnabled) {
  904.             $r->enableResultCache(TimeConstant::DAY$cacheName);
  905.         }
  906.         $res = [];
  907.         $items $r->getArrayResult();
  908.         /** @var FilterEntity $item */
  909.         foreach ($items as $item) {
  910.             $f $item[0];
  911.             unset($item[0]);
  912.             $item['country'] = $f['country'];
  913.             $res[$item['groupsAltName']][] = $item;
  914.         }
  915.         return $res;
  916.     }
  917.     /**
  918.      * Получаем массив всех детей по рабителю для фейк тегов
  919.      * @param null $groups
  920.      * @param      $lc
  921.      * @param bool $ignoreEnabled
  922.      * @return array|null
  923.      * @throws Exception
  924.      */
  925.     public function getArrListSubForMenu($pid$lcbool $ignoreEnabled false): ?array
  926.     {
  927.         $lcUc ucfirst($lc);
  928.         $selectByLc "url.$lc url$lcUc, page.nameMenu$lcUc pageNameMenu$lcUc,";
  929.         // костыль для фильтра цен, что бы показывать верно для разных стран
  930.         $lcPrice LocaleHelper::getLocaleForPriceFilter($lc);
  931.         if ($lc != $lcPrice) {
  932.             $lcUcPrice ucfirst($lcPrice);
  933.             $selectByLc .= "url.$lcPrice url$lcUcPrice, page.nameMenu$lcUcPrice pageNameMenu$lcUcPrice,";
  934.         }
  935.         $q $this->createQueryBuilder('f')
  936.             ->select(
  937.                 "
  938.             $selectByLc
  939.             f
  940.             "
  941.             )
  942.             ->leftJoin('f.url''url')
  943.             ->leftJoin('f.page''page')
  944.             ->leftJoin('f.param''param')
  945.             ->leftJoin('f.groups''groups')
  946.             ->leftJoin('f.country''country')
  947.             ->leftJoin('f.parent''parent');
  948.         if (!$ignoreEnabled) {
  949.             $q
  950.                 ->andWhere('param.isEnabled = 1')
  951.                 ->andWhere('parent.id = ' $pid)
  952.                 ->andWhere('param.showMenu = 1 OR param.showMenuAdvanced = 1')
  953.                 ->andWhere('url.' $lc '  is not null')
  954.                 ->andWhere('param.count > 0');
  955.         }
  956.         $q->orderBy('f.sort ASC, f.name');
  957.         $r $q->getQuery();
  958.         $cacheName $this->buildCacheName('filter_getArrListSubMenu_' $lc $lcPrice$pid);
  959.        // $r->useQueryCache(true);
  960.         if (!App::isDev() or !$ignoreEnabled) {
  961.             $r->enableResultCache(TimeConstant::DAY$cacheName);
  962.         }
  963.         $res = [];
  964.         $items $r->getArrayResult();
  965.         /** @var FilterEntity $item */
  966.         foreach ($items as $item) {
  967.             $f $item[0];
  968.             unset($item[0]);
  969.             $item['url'] = $item["url$lcUc"];
  970.             $item['pageNameMenu'] = $item["pageNameMenu$lcUc"];
  971.             $res[] = $item;
  972.         }
  973.         return $res;
  974.     }
  975.     public function getFilterIdForSettingsCollectionByLeft($leftMenu)
  976.     {
  977.         $q $this->createQueryBuilder('f')
  978.             ->select('f.id, f.name')
  979.             ->leftJoin('f.url''url')
  980.             ->leftJoin('f.page''page')
  981.             ->andWhere('f.leftMenu = :leftMenu')
  982.             ->setParameter('leftMenu'$leftMenu)
  983.             ->getQuery()
  984.             ->enableResultCache(TimeConstant::DAY);
  985.         $id $q->getArrayResult();
  986.         return $id $id[0] : null;
  987.     }
  988.     public function getFilterIdForSettingsColletionByIdDesigner(int $id)
  989.     {
  990.         $q $this->createQueryBuilder('f')
  991.             ->select('f.id, f.name')
  992.             ->leftJoin('f.url''url')
  993.             ->leftJoin('f.page''page')
  994.             ->andWhere('f.id = :id')->setParameter('id'$id)
  995.             ->andWhere('f.oldCommand != :oldCommand')->setParameter('oldCommand''factory');
  996.         $q $q->getQuery()->enableResultCache(TimeConstant::DAY);
  997.         $id $q->getArrayResult();
  998.         return $id $id[0] : null;
  999.     }
  1000.     /**
  1001.      * Получаем массив данных фильтра для свойств коллекции
  1002.      * URL и имя формируется сразу по локали
  1003.      * @param      $oldId
  1004.      * @param      $oldCommand
  1005.      * @param null $locale
  1006.      * @return mixed|null
  1007.      * @throws Exception
  1008.      */
  1009.     public function findFilterForSettingsColletion($oldId$oldCommand$locale null)
  1010.     {
  1011.         $locale $locale ?: App::getCurLocale();
  1012.         $localeUc ucfirst($locale);
  1013.         $key 'filter_' $oldId '_' $oldCommand '_' $locale;
  1014.         $res App::getMemcache()->get($key);
  1015.         if (!$res) {
  1016.             $q $this->createQueryBuilder('f');
  1017.             $q->select('f, f.id, f.oldId, f.oldCommand, f.altName, f.rank, url, page');
  1018.             $q
  1019.                 ->leftJoin('f.url''url')
  1020.                 ->leftJoin('f.page''page');
  1021.             $q
  1022.                 ->andWhere("f.oldId = :old_id")
  1023.                 ->setParameter('old_id'$oldId)
  1024.                 ->andWhere("f.oldCommand = :old_command")
  1025.                 ->setParameter('old_command'$oldCommand);
  1026.             $q->setMaxResults(1);
  1027.             $r $q->getQuery()->enableResultCache(TimeConstant::DAY);
  1028.             $item ArrHelper::get($r->getArrayResult(), '0');
  1029.             if (!$item) {
  1030.                 return null;
  1031.             }
  1032.             $item['url'] = ArrHelper::get($item"0.url.$locale");
  1033.             $item['name'] = ArrHelper::get($item"0.page.nameMany$localeUc");
  1034.             unset($item[0]);
  1035.             if (!defined('DB_NOT_CASHED')) {
  1036.                 App::getMemcache()->set($key$itemfalse, (int) TimeConstant::WEEK); // неделя
  1037.             }
  1038.             $res $item;
  1039.         }
  1040.         return $res;
  1041.     }
  1042.     /**
  1043.      * Получаем список активных фильтров для просчета ранга
  1044.      * @return array|null
  1045.      */
  1046.     public function getForCalcRank()
  1047.     {
  1048.         $q $this->createQueryBuilder('f');
  1049.         $q->select('f.id, f.name, f.rank, param.count, groups.id gid')
  1050.             ->leftJoin('f.groups''groups')
  1051.             ->leftJoin('f.param''param')
  1052.             ->andWhere("groups.id != 406")// исключаем бренды
  1053.             //->andWhere("groups.id != 411")// исключаем дизайнеров
  1054.             ->andWhere("groups.id != 408")// исключаем Размер
  1055.             ->andWhere("groups.id != 412")// исключаем top
  1056.             ->andWhere("groups.id != 415")// исключаем page
  1057.             ->andWhere("groups.id != 416")// исключаем БМ
  1058.             ->andWhere("groups.id != 407")// исключаем Сортировка
  1059.             ->andWhere("groups.id != 399")// исключаем распродажа
  1060.             ->andWhere("param.isEnabled = 1")//->andWhere("param.showMenu = 1")
  1061.         ;
  1062.         $result $q->getQuery()->enableResultCache(TimeConstant::DAY);
  1063.         $res = [];
  1064.         foreach ($result->getArrayResult() as $i => $item) {
  1065.             $res[$item['id']] = $item;
  1066.         }
  1067.         return $res;
  1068.     }
  1069.     /**
  1070.      * @param string $key
  1071.      * @return FilterEntity|null
  1072.      */
  1073.     public function admGetExhibitionByKeyForConsole(string $key)
  1074.     {
  1075.         $q $this->createQueryBuilder('f');
  1076.         $q->select('f, groups, param, page')
  1077.             ->leftJoin('f.groups''groups')
  1078.             ->leftJoin('f.param''param')
  1079.             ->leftJoin('f.page''page')
  1080.             ->andWhere("f.name LIKE '$key%'")
  1081.             ->andWhere('param.isEnabled = 1')
  1082.             ->andWhere('groups.id = 420 OR groups.id = 417')
  1083.             ->orderBy('f.id''DESC')
  1084.             ->setMaxResults(1);
  1085.         try {
  1086.             return $q->getQuery()->getSingleResult();
  1087.         } catch (NoResultException NonUniqueResultException $e) {
  1088.             return null;
  1089.         }
  1090.     }
  1091.     /**
  1092.      * Получаем последний ID для сфинкса из группы
  1093.      * @param int $groupId
  1094.      * @return int
  1095.      * @throws Throwable
  1096.      */
  1097.     public function admGetExhibitionLastOldIdForConsole(int $groupId): int
  1098.     {
  1099.         $sql "SELECT  f.old_id AS `oldId`
  1100.                 FROM filters f
  1101.                 WHERE f.group_id = $groupId
  1102.                 ORDER BY f.old_id DESC LIMIT 1";
  1103.         $oldId $this->getEntityManager()
  1104.             ->getConnection()
  1105.             ->executeQuery($sql)
  1106.             ->fetchOne();
  1107.         return intval($oldId);
  1108.     }
  1109.     /**
  1110.      * Получение последнего дизайнера, для использования в качестве шаблона для создания нового
  1111.      * @return FilterEntity|null
  1112.      */
  1113.     public function admLastDesigner(): ?FilterEntity
  1114.     {
  1115.         $q $this->createQueryBuilder('f');
  1116.         $q->select('f, groups, param, page')
  1117.             ->leftJoin('f.groups''groups')
  1118.             ->leftJoin('f.param''param')
  1119.             ->leftJoin('f.page''page')
  1120.             ->andWhere("f.parentKey = 'designer'")
  1121.             ->andWhere('param.isEnabled = 1')
  1122.             ->orderBy('f.id''DESC')
  1123.             ->setMaxResults(1);
  1124.         try {
  1125.             return $q->getQuery()->getSingleResult();
  1126.         } catch (NoResultException NonUniqueResultException $e) {
  1127.             return null;
  1128.         }
  1129.     }
  1130.     /**
  1131.      * Поиск последней заполненной переводами записи награды.
  1132.      */
  1133.     public function getLastRewards(): ?FilterEntity
  1134.     {
  1135.         $q $this->createQueryBuilder('f');
  1136.         $q->select('f, groups, param, page')
  1137.             ->innerJoin('f.groups''groups')
  1138.             ->leftJoin('f.param''param')
  1139.             ->innerJoin('f.page''page')
  1140.             ->where('groups.id = :groupId')
  1141.             ->andWhere('param.isEnabled = 1')
  1142.             ->andWhere('page.nameSingleEn IS NOT NULL AND page.nameSingleEn != :empty')
  1143.             ->andWhere('page.descriptionEn IS NOT NULL AND page.descriptionEn != :empty')
  1144.             ->orderBy('f.id''DESC')
  1145.             ->setMaxResults(1)
  1146.             ->setParameters([
  1147.                 'groupId' => FilterGroupEnum::REWARD,
  1148.                 'empty' => ''
  1149.             ]);
  1150.         $query $q->getQuery();
  1151.         $query->useQueryCache(true);
  1152.         $query->setQueryCacheLifetime(self::QUERY_CACHE_LIFETIME);
  1153.         try {
  1154.             return $query->getSingleResult();
  1155.         } catch (NoResultException NonUniqueResultException $e) {
  1156.             return null;
  1157.         }
  1158.     }
  1159.     /**
  1160.      * Получение списка наград для выпадающего списка
  1161.      * @return array
  1162.      */
  1163.     public function admGetAwardsForSelectMenu(): array
  1164.     {
  1165.         $q $this->createQueryBuilder('f');
  1166.         $q->select('f.id, f.name')
  1167.             ->leftJoin('f.groups''groups')
  1168.             ->andWhere("groups.altName = 'rewards'")
  1169.             ->andWhere("f.oldId != 1"// исключаем фильтр общий Премированные
  1170.         ;
  1171.         $res = [];
  1172.         $out $q->getQuery()->getArrayResult();
  1173.         foreach ($out as $i => $item) {
  1174.             $res[(string) $item['id']] = $item['name'];
  1175.         }
  1176.         return $res;
  1177.     }
  1178.     /**
  1179.      * Список выставок для БИ и админки
  1180.      * @return array
  1181.      */
  1182.     public function admGetExhibitionForSelectMenu(): array
  1183.     {
  1184.         $q $this->createQueryBuilder('f');
  1185.         $q->select('f.oldId id, f.name')
  1186.             ->leftJoin('f.groups''groups')
  1187.             ->andWhere("groups.altName = 'exhibition'");
  1188.         $res = [];
  1189.         $out $q->getQuery()->getArrayResult();
  1190.         foreach ($out as $i => $item) {
  1191.             $res[(string) $item['id']] = $item['name'];
  1192.         }
  1193.         return $res;
  1194.     }
  1195.     /**
  1196.      * @param $exhibition
  1197.      * @return array
  1198.      */
  1199.     public function admGetExhibitionForBI($exhibition): array
  1200.     {
  1201.         $q $this->createQueryBuilder('f');
  1202.         $q->select('f.id, f.name, f.iconUrl')
  1203.             ->leftJoin('f.groups''groups')
  1204.             ->leftJoin('f.param''param')
  1205.             ->andWhere("groups.altName = 'exhibition'")
  1206.             ->andWhere("f.oldId in (:exhibition)")
  1207.             ->setParameter('exhibition'$exhibition);
  1208.         $res = [];
  1209.         $out $q->getQuery()->getArrayResult();
  1210.         foreach ($out as $i => $item) {
  1211.             $link $item['iconUrl'];
  1212.             $res[(string) $item['id']] = (!empty($link)) ? $item['name'] . '(<a href="' $link '" target="_blank" rel="noopener noreferrer">' $link '</a>)' $item['name'];
  1213.         }
  1214.         return $res;
  1215.     }
  1216.     public function admGetAwardsForBi($awards): array
  1217.     {
  1218.         $q $this->createQueryBuilder('f');
  1219.         $q->select('f.id, f.name, f.iconUrl')
  1220.             ->leftJoin('f.groups''groups')
  1221.             ->andWhere("groups.altName = 'rewards'")
  1222.             ->andWhere("f.oldId != 1"// исключаем фильтр общий Премированные
  1223.             ->andWhere("f.id in (:awards)")
  1224.             ->setParameter('awards'$awards);
  1225.         $res = [];
  1226.         $out $q->getQuery()->getArrayResult();
  1227.         foreach ($out as $i => $item) {
  1228.             $link $item['iconUrl'];
  1229.             $res[(string) $item['id']] = (!empty($link)) ? $item['name'] . '(<a href="' $link '" target="_blank" rel="noopener noreferrer">' $link '</a>)' $item['name'];
  1230.         }
  1231.         return $res;
  1232.     }
  1233.     public function admGetForJsTree(): array
  1234.     {
  1235.         $q $this->createQueryBuilder('f');
  1236.         $q->select('f.id, f.name, groups.id gr_id, groups.altName gr_name')
  1237.             ->leftJoin('f.groups''groups')
  1238.             ->leftJoin('f.param''param')
  1239.             ->andWhere("groups.id != 411")// исключаем дизайнеров
  1240.             ->andWhere("groups.id != 408")// исключаем Размер
  1241.             //->andWhere("groups.id != 412")// исключаем top
  1242.             ->andWhere("groups.id != 415")// исключаем page
  1243.             ->andWhere("groups.id != 416")// исключаем БМ
  1244.             ->andWhere("groups.id != 407")// исключаем Сортировка
  1245.             ->andWhere("groups.id != 399")// исключаем распродажа
  1246.             ->andWhere("param.isEnabled = true")
  1247.             ->andWhere("param.showMenuAdvanced = true")
  1248.             ->orderBy('gr_name''ASC')
  1249.             ->addOrderBy('f.name''ASC')
  1250.             ->andWhere("groups.id != 406"// исключаем бренды
  1251.             //->andWhere("groups.id = 397") // временно, что бы был один
  1252.         ;
  1253.         $items $q->getQuery()->getArrayResult();
  1254.         $res = [];
  1255.         foreach ($items as $item) {
  1256.             $res[$item['gr_id']][] = $item;
  1257.         }
  1258.         return $res;
  1259.     }
  1260.     public function getSortListCataloge($locale null)
  1261.     {
  1262.         $locale $locale ?: App::getCurLocale();
  1263.         $localeUc ucfirst($locale);
  1264.         $q $this->createQueryBuilder('f')
  1265.             ->select("f.oldId as id, page.nameSingle$localeUc as nameSingle, page.nameMenu$localeUc as nameMenu")
  1266.             ->leftJoin('f.page''page')
  1267.             ->leftJoin('f.groups''gr')
  1268.             ->andWhere('gr.id = 407')
  1269.             ->orderBy('f.sort''ASC');
  1270.         $r $q->getQuery()
  1271.             ->useQueryCache(true);
  1272.         $items $r->getArrayResult();
  1273.         $res = [];
  1274.         foreach ($items as $item) {
  1275.             $res[$item['id']] = $item;
  1276.         }
  1277.         return $res;
  1278.     }
  1279.     public function getAwards(array $id)
  1280.     {
  1281.         $localeUc ucfirst(App::getCurLocale());
  1282.         if (count($id) == 0) {
  1283.             return [];
  1284.         }
  1285.         if (is_array($id)) {
  1286.             $id implode(', '$id);
  1287.             $id "($id)";
  1288.         }
  1289.         $q $this->createQueryBuilder('f')
  1290.             ->select("f.id, f.icon, f.iconUrl, page.nameSingle$localeUc")
  1291.             ->leftJoin('f.page''page')
  1292.             //            ->andWhere('f.icon IS NOT NULL') решили выводить данные https://te.remote.team/#/discus/649252D6-AAD4-D219-FD67-BBF3CDCA1062/
  1293.             ->andWhere("f.id IN $id");
  1294.         $r $q->getQuery()->useQueryCache(true);
  1295.         $items $r->getArrayResult();
  1296.         $res = [];
  1297.         foreach ($items as $item) {
  1298.             $res[$item['id']] = [
  1299.                 'id' => $item['id'],
  1300.                 'icon' => PathHelper::pathGenerate('filter'$item),
  1301.                 'title' => $item["nameSingle$localeUc"],
  1302.                 'url' => $item['iconUrl'],
  1303.             ];
  1304.         }
  1305.         return $res;
  1306.     }
  1307.     /**
  1308.      * Получаем выставки по oldId
  1309.      * @param array $id
  1310.      * @return array
  1311.      * @throws Exception
  1312.      */
  1313.     public function getExhibitions(array $id): array
  1314.     {
  1315.         $lcVo = new LocaleVo();
  1316.         $lc $lcVo->getCode();
  1317.         $lcUc ucfirst($lc);
  1318.         $lcFull $lcVo->getCodeFull();
  1319.         $id array_filter($id);
  1320.         if (count($id) == 0) {
  1321.             return [];
  1322.         }
  1323.         $id implode(', '$id);
  1324.         $id "($id)";
  1325.         $q $this->createQueryBuilder('f')
  1326.             ->select(
  1327.                 "f.id, f.oldId, f.iconUrl, tooltip.$lc as tooltipLc , page.nameMenu$lcUc, url.$lc as urlLocal"
  1328.             )
  1329.             ->leftJoin('f.page''page')
  1330.             ->leftJoin('f.url''url')
  1331.             ->leftJoin('f.param''param')
  1332.             ->leftJoin('f.tooltip''tooltip')
  1333.             ->andWhere('param.isEnabled = 1')
  1334.             ->andWhere('param.count > 0')
  1335.             ->andWhere("f.oldCommand = 'exhibition'")
  1336.             ->andWhere("f.oldId IN $id");
  1337.         $r $q->getQuery()->enableResultCache(TimeConstant::DAY);
  1338.         $router App::getRouter();
  1339.         $items $r->getArrayResult();
  1340.         $res = [];
  1341.         foreach ($items as $item) {
  1342.             $name $item["nameMenu$lcUc"];
  1343.             // показываем бирки только с возрастом не более 2-х лет
  1344.             $year intval(preg_replace('/\D/'''$name));
  1345.             $yearLimit intval(date("Y")) - 2;
  1346.             if ($year <= $yearLimit) {
  1347.                 continue;
  1348.             }
  1349.             $res[$item['id']] = [
  1350.                 'id' => $item['id'],
  1351.                 'sphinxId' => $item['oldId'],
  1352.                 'name' => $name,
  1353.                 'tooltip' => $item['tooltipLc'],
  1354.                 'urlRemote' => $item['iconUrl'],
  1355.                 'urlLocal' => $router->generate('app_catalog', ['key' => $item['urlLocal'], '_locale' => $lcFull]),
  1356.             ];
  1357.         }
  1358.         return $res;
  1359.     }
  1360.     /**
  1361.      * Получаем список url фильтров по языку для sitemap
  1362.      * @param $lang
  1363.      * @return array|null
  1364.      */
  1365.     public function getListUrlFiltersByLang($lang): ?array
  1366.     {
  1367.         $q $this->createQueryBuilder('f')
  1368.             ->select("u.$lang url, f.leftMenu")
  1369.             ->leftJoin('f.url''u')
  1370.             ->leftJoin('f.groups''g')
  1371.             ->leftJoin('f.param''p')
  1372.             ->andWhere('p.hide = 0')
  1373.             ->andWhere('p.count > 0')
  1374.             ->andWhere('g.id NOT IN (:groups)')
  1375.             ->setParameter('groups', [407416417])
  1376.             ->getQuery();
  1377.         $cacheName $this->buildCacheName('filter_getListUrlFiltersByLang'$lang);
  1378.         $q->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY$cacheName);
  1379.         return $q->getArrayResult();
  1380.     }
  1381.     /**
  1382.      * Получение списка для проверки на наличие кириллических символов
  1383.      * @return array
  1384.      */
  1385.     public function getCollectionsAdmForCheckCyrillic(): array
  1386.     {
  1387.         $q $this->createQueryBuilder('f')
  1388.             ->select('f, page')
  1389.             ->leftJoin('f.page''page')
  1390.             ->leftJoin('f.param''param')
  1391.             ->andWhere("param.isEnabled = true");
  1392.         return $q->getQuery()->getArrayResult();
  1393.     }
  1394.     /**
  1395.      * Получение ID фильтра по ID бренда
  1396.      * @param $idBrand
  1397.      * @return mixed|null
  1398.      * @throws NonUniqueResultException
  1399.      */
  1400.     public function getIdFilterByIdBrand($idBrand)
  1401.     {
  1402.         $q $this
  1403.             ->createQueryBuilder('f')
  1404.             ->select('f.id')
  1405.             ->leftJoin('f.brand''brand')
  1406.             ->andWhere('brand.id = :idBrand')
  1407.             ->setParameter('idBrand'$idBrand)
  1408.             ->setMaxResults(1)
  1409.             ->getQuery();
  1410.         try {
  1411.             $id $q->getSingleResult();
  1412.             $id $id['id'];
  1413.         } catch (NoResultException $e) {
  1414.             return null;
  1415.         }
  1416.         return $id;
  1417.     }
  1418.     /**
  1419.      * Проставляем связи фильтра с коллекциями
  1420.      * @param int $fID
  1421.      * @param     $cIDs
  1422.      * @return bool
  1423.      * @throws Throwable
  1424.      */
  1425.     public function setCollections(int $fID$cIDs)
  1426.     {
  1427.         if (!$cIDs) {
  1428.             return false;
  1429.         }
  1430.         $conn $this->getEntityManager()->getConnection();
  1431.         $cIDs is_array($cIDs) ? $cIDs : [$cIDs];
  1432.         // находим коллекции, которых нет больше и удаляем их
  1433.         $cIDstr implode(','$cIDs);
  1434.         $conn->executeStatement(
  1435.             "DELETE FROM `collection_filters` WHERE `collection_id` NOT IN ($cIDstr) AND `filter_id` = '$fID';"
  1436.         );
  1437.         // проставляем связи для всех остальных записей
  1438.         // делаем порциями по почке запросов за раз
  1439.         $maxPortion 100;
  1440.         $sqlUpdate '';
  1441.         $cnt 0;
  1442.         foreach ($cIDs as $cID) {
  1443.             $sqlUpdate .= "INSERT INTO `collection_filters` (`collection_id`,`filter_id`)  VALUES  ('$cID', '$fID') ON DUPLICATE KEY UPDATE collection_id='$cID', filter_id='$fID';";
  1444.             $cnt++;
  1445.             if ($cnt == $maxPortion) {
  1446.                 $sth $conn->prepare($sqlUpdate);
  1447.                 $sth->execute();
  1448.                 $sth->closeCursor();
  1449.                 $cnt 0;
  1450.                 $sqlUpdate '';
  1451.             }
  1452.         }
  1453.         if ($sqlUpdate != '') {
  1454.             $sth $conn->prepare($sqlUpdate);
  1455.             $sth->execute();
  1456.             $sth->closeCursor();
  1457.         }
  1458.         return true;
  1459.     }
  1460.     /**
  1461.      * Получение фильтра для DTO выставки
  1462.      * @param $fids
  1463.      * @param $lc
  1464.      * @return array
  1465.      * @throws \Doctrine\DBAL\Exception
  1466.      */
  1467.     public function getForExhDTO($fids$lc)
  1468.     {
  1469.         if (!$fids) {
  1470.             return [];
  1471.         }
  1472.         $fidsStr implode(','$fids);
  1473.         $sql "SELECT
  1474.                 f.id,
  1475.                 f.alt_name AS `altName`,
  1476.                 f.old_command AS `nameSphinx`,
  1477.                 fp.name_menu_$lc AS `name`,
  1478.                 fp.name_many_$lc AS `nameMany`,
  1479.                 fp.name_single_$lc AS `nameFull`,
  1480.                 p.count AS `count`,
  1481.                 p.hex_code AS `hexCode`,
  1482.                 p.show_menu_advanced AS `showMenuAdvanced`,
  1483.                 p.show_menu AS `showMenu`,
  1484.                 g.alt_name AS `groupAltName`,
  1485.                 gname.$lc AS `groupName`,
  1486.                 c.id AS `countryId`,
  1487.                 c.old_id AS `countryOldId`,
  1488.                 cfp.name_menu_$lc AS `countryName`,
  1489.                 u.$lc AS `slug`
  1490.             FROM
  1491.                 filters f
  1492.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1493.             LEFT JOIN filter_params p ON p.id = f.param_id
  1494.             LEFT JOIN filter_groups g ON g.id = f.group_id
  1495.             LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
  1496.             LEFT JOIN filters c ON c.id = f.country_id
  1497.             LEFT JOIN filter_pages cfp ON cfp.id = c.page_id
  1498.             LEFT JOIN locale_url u ON u.filter_id = f.id
  1499.             WHERE f.id IN ($fidsStr) AND
  1500.             p.count > 0 AND
  1501.             g.alt_name != 'top' AND
  1502.             g.alt_name != 'release_year_collection' AND
  1503.             g.alt_name != 'price' AND
  1504.             g.alt_name != 'brand' AND
  1505.             f.alt_name != 'cataloge' AND
  1506.             g.alt_name != 'using' AND
  1507.             p.is_enable = 1
  1508.             ORDER BY f.sort, f.name";
  1509.         $memcache $this->cacheService->getMemcache();
  1510.         $memcacheKey md5($sql);
  1511.         $items $memcache->get($memcacheKey);
  1512.         if ($items) {
  1513.             return $items;
  1514.         }
  1515.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  1516.         $memcache->set($memcacheKey$items);
  1517.         return $items;
  1518.     }
  1519.     /**
  1520.      * Получение имени для графика статистик в админке
  1521.      * @param array $fids
  1522.      * @param bool $isBrand
  1523.      * @return array
  1524.      */
  1525.     public function getNamesForStatChartAdmin(array $fidsbool $isBrand false)
  1526.     {
  1527.         $fidsStr implode(','$fids);
  1528.         if ($isBrand) {
  1529.             $where "WHERE f.brand IN ($fidsStr)";
  1530.         } else {
  1531.             $where "WHERE f.id IN ($fidsStr)";
  1532.         }
  1533.         $sql "SELECT
  1534.                 f.id,
  1535.                 f.brand,
  1536.                 fp.name_menu_ru AS `name`
  1537.             FROM
  1538.                 filters f
  1539.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1540.             $where
  1541.             ORDER BY fp.name_menu_ru ASC";
  1542.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  1543.         $items $this->getEntityManager()->getConnection()->fetchAll($sql);
  1544.         $r = [];
  1545.         foreach ($items as $item) {
  1546.             $id $isBrand $item['brand'] : $item['id'];
  1547.             $r[$id] = [
  1548.                 'name' => $item['name'],
  1549.                 'data' => [],
  1550.             ];
  1551.         }
  1552.         return $r;
  1553.     }
  1554.     /**
  1555.      * @return array
  1556.      */
  1557.     public function admGetDesigners()
  1558.     {
  1559.         $q $this->createQueryBuilder('f');
  1560.         $q->select('f.id, f.name')
  1561.             ->leftJoin('f.groups''groups')
  1562.             ->andWhere("groups.altName = 'designer'")
  1563.             ->andWhere("f.oldId != 1")
  1564.             ->orderBy('f.name');
  1565.         $res = [];
  1566.         $out $q->getQuery()->getArrayResult();
  1567.         foreach ($out as $i => $item) {
  1568.             $res[$item['name']] = StrHelper::toLower($item['name']);
  1569.         }
  1570.         return $res;
  1571.     }
  1572.     public function admGetDesignersId()
  1573.     {
  1574.         $q $this->createQueryBuilder('f');
  1575.         $q->select('f.id, f.name')
  1576.             ->leftJoin('f.groups''groups')
  1577.             ->andWhere("groups.altName = 'designer'")
  1578.             ->andWhere("f.oldId != 1")
  1579.             ->orderBy('f.name');
  1580.         return $q->getQuery()->getArrayResult();
  1581.     }
  1582.     /**
  1583.      * Выборка фильтров для формирования свойств коллекции
  1584.      * @param $fids
  1585.      * @param null $lc
  1586.      * @return array
  1587.      */
  1588.     public function getForCollSettings($fids$lc null): array
  1589.     {
  1590.         $lc $lc ?: App::getCurLocale();
  1591.         $fidsStr implode(','$fids);
  1592.         $sql "SELECT
  1593.                 f.id,
  1594.                 f.rank AS `rank`,
  1595.                 f.alt_name AS `altName`,
  1596.                 f.old_command AS `sphinxName`,
  1597.                 f.old_id AS `sphinxId`,
  1598.                 fp.name_menu_$lc AS `name`,
  1599.                 fp.name_many_$lc AS `nameMany`,
  1600.                 fp.name_single_$lc AS `nameFull`,
  1601.                 p.count AS `count`,
  1602.                 g.id AS `group.id`,
  1603.                 g.alt_name AS `group.altName`,
  1604.                 gname.$lc AS `group.name`,
  1605.                 url.$lc AS `slug`
  1606.             FROM
  1607.                 filters f
  1608.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1609.             LEFT JOIN filter_params p ON p.id = f.param_id
  1610.             LEFT JOIN filter_groups g ON g.id = f.group_id
  1611.             LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
  1612.             LEFT JOIN locale_url url ON url.filter_id = f.id
  1613.             WHERE
  1614.                 f.id IN ($fidsStr) AND
  1615.                 p.is_enable = 1
  1616.             ORDER BY f.sort, f.name";
  1617.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  1618.         $memcache $this->cacheService->getMemcache();
  1619.         $memcacheKey md5($sql);
  1620.         $items $memcache->get($memcacheKey);
  1621.         if ($items) {
  1622.             return $items;
  1623.         }
  1624.         $items $this->getEntityManager()->getConnection()->fetchAll($sql);
  1625.         $memcache->set($memcacheKey$items);
  1626.         return $items;
  1627.     }
  1628.     /**
  1629.      * Получение данных для формирования имени фильтра в хистри расширенного поиска
  1630.      * @param array $fids
  1631.      * @return array
  1632.      */
  1633.     public function getForFilterNameHistorySearch(array $fids): array
  1634.     {
  1635.         $lc App::getCurLocale();
  1636.         $fids array_unique(array_map('intval'array_filter($fids'is_numeric')));
  1637.         if (empty($fids)) {
  1638.             return [];
  1639.         }
  1640.         $fidsStr implode(','$fids);
  1641.         $sql "SELECT
  1642.                 f.id AS `id`,
  1643.                 f.alt_name AS `altName`,
  1644.                 fpg.name_many_$lc AS `name`,
  1645.                 fpr.code AS `code`,
  1646.                 fg.alt_name AS `groupAltName`,
  1647.                 fg.left_menu AS `groupLeftMenu`
  1648.             FROM
  1649.                 filters f
  1650.             LEFT JOIN filter_groups fg ON fg.id = f.group_id
  1651.             LEFT JOIN filter_pages fpg ON fpg.id = f.page_id
  1652.             LEFT JOIN filter_params fpr ON fpr.id = f.param_id
  1653.             WHERE
  1654.                 f.id IN ($fidsStr)";
  1655.         $memcache $this->cacheService->getMemcache();
  1656.         $memcacheKey md5($sql);
  1657.         $items $memcache->get($memcacheKey);
  1658.         if ($items) {
  1659.             return $items;
  1660.         }
  1661.         $items $this->getEntityManager()->getConnection()->fetchAll($sql);
  1662.         $memcache->set($memcacheKey$items);
  1663.         return $items;
  1664.     }
  1665.     /**
  1666.      * Список для назначения родителя в админке
  1667.      * @param $gid
  1668.      * @param $fid
  1669.      * @return array
  1670.      * @throws \Doctrine\DBAL\Exception
  1671.      */
  1672.     public function admGetListForParent($gid$fid): array
  1673.     {
  1674.         $sql "SELECT
  1675.                 f.id as `id`,
  1676.                    f.name AS `name.ru`,
  1677.                    fp.name_menu_en AS `name.en`
  1678.             FROM
  1679.                 filters f
  1680.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1681.             LEFT JOIN filter_params p ON p.id = f.param_id
  1682.             WHERE f.id != $fid AND f.group_id = $gid AND p.is_enable = 1
  1683.             ORDER BY `name.ru`";
  1684.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  1685.         $rows = [];
  1686.         foreach ($items as $item) {
  1687.             $rows[$item['id']] = "{$item['name.ru']} ({$item['name.en']}) #{$item['id']}";
  1688.         }
  1689.         return $rows;
  1690.     }
  1691.     /**
  1692.      * @param string $leftMenu
  1693.      * @return string|null
  1694.      */
  1695.     public function getKeyByLeftMenu(string $leftMenu): ?string
  1696.     {
  1697.         $lc App::getCurLocale();
  1698.         $sql "SELECT
  1699.                    lurl.$lc AS `url`
  1700.             FROM
  1701.                 filters f
  1702.             LEFT JOIN locale_url lurl ON f.id = lurl.filter_id
  1703.             WHERE f.left_menu = '$leftMenu'
  1704.             LIMIT 1";
  1705.         $memcache $this->cacheService->getMemcache();
  1706.         $memcacheKey md5($sql);
  1707.         $items $memcache->get($memcacheKey);
  1708.         if ($items) {
  1709.             return $items;
  1710.         }
  1711.         try {
  1712.             $items $this->getEntityManager()
  1713.                 ->getConnection()
  1714.                 ->executeQuery($sql)
  1715.                 ->fetchOne() ?: null;
  1716.             $memcache->set($memcacheKey$items);
  1717.             return $items;
  1718.         } catch (Throwable $e) {
  1719.             return null;
  1720.         }
  1721.     }
  1722.     public function getListForTestCountTranslate()
  1723.     {
  1724.         $q $this->createQueryBuilder('f')
  1725.             ->select('f, g, p, descr, htmlShow')
  1726.             ->leftJoin('f.groups''g')
  1727.             ->leftJoin('f.page''p')
  1728.             ->leftJoin('f.htmlShow''htmlShow')
  1729.             ->leftJoin('f.nameForMetaDescr''descr')
  1730.             ->andWhere('g.id != 406')// фабрики
  1731.             ->andWhere('g.id != 411')// дизайнеры
  1732.             ->getQuery();
  1733.         return $q->getArrayResult();
  1734.     }
  1735.     /**
  1736.      * Получение списка ТОП фильтров, для формирования меню карусели на главной
  1737.      * @return array
  1738.      * @throws Exception
  1739.      * @see src/WebBundle/Resources/views/Home/_top-carousel.html.twig
  1740.      */
  1741.     public function getItemsForTopCollectionCarouselMenu(): array
  1742.     {
  1743.         $lc App::getCurLocale();
  1744.         $cacheKey "ItemsForTopCollectionCarouselMenu.$lc";
  1745.         $redisCachePool App::getContainer()->get(RedisCachePool::class)->getPool();
  1746.         $cacheItem $redisCachePool->getItem($cacheKey);
  1747.         if ($cacheItem->isHit()) {
  1748.             return $cacheItem->get();
  1749.         }
  1750.         $translator App::getTranslator();
  1751.         $sql "SELECT
  1752.                lurl.$lc AS `url`,
  1753.                lurl.en AS `key`,
  1754.                f.alt_name AS `alt`,
  1755.                f.id AS `id`
  1756.         FROM
  1757.             filters f
  1758.         LEFT JOIN locale_url lurl ON f.id = lurl.filter_id
  1759.         WHERE f.id in (10592,10591)";
  1760.         $rows $this->getEntityManager()
  1761.             ->getConnection()
  1762.             ->executeQuery($sql)
  1763.             ->fetchAll();
  1764.         $items = [
  1765.             'top-all' => [
  1766.                 'title' => $translator->trans('main_top_all'),
  1767.                 'link' => App::generateUrl('app_catalog'),
  1768.                 'url-json' => App::generateUrl('app_last_collection', ['type' => 'top-all']),
  1769.                 'key' => 'top-all',
  1770.             ],
  1771.         ];
  1772.         if ($rows) {
  1773.             foreach ($rows as $row) {
  1774.                 $items[$row['key']] = [
  1775.                     'title' => $translator->trans("main_{$row['alt']}"),
  1776.                     'link' => App::generateUrl('app_catalog', ['key' => $row['url']]),
  1777.                     'url-json' => App::generateUrl('app_last_collection', ['type' => $row['key']]),
  1778.                     'key' => $row['key'],
  1779.                 ];
  1780.             }
  1781.             $cacheItem->set($items);
  1782.             $redisCachePool->save($cacheItem);
  1783.         }
  1784.         return $items;
  1785.     }
  1786.     /**
  1787.      * Выборка для отдачи списка дизайнеров в меню в каталоге
  1788.      * @param array $onlyIds
  1789.      * @return array
  1790.      * @throws \Doctrine\DBAL\Exception
  1791.      */
  1792.     public function getListDesignersForCataloge(array $onlyIds = []): array
  1793.     {
  1794.         if ($onlyIds) {
  1795.             $onlyIds implode("','"$onlyIds);
  1796.             $onlyIds " AND f.id IN ('$onlyIds')";
  1797.         } else {
  1798.             $onlyIds '';
  1799.         }
  1800.         $sql "SELECT
  1801.                 f.id,
  1802.                 f.rank AS `rank`,
  1803.                 f.old_command AS `oldCommand`,
  1804.                 f.old_id AS `oldId`,
  1805.                 fp.name_menu_en AS `name`,
  1806.                 p.count AS `cnt`,
  1807.                 url.en AS `slug`
  1808.             FROM
  1809.                 filters f
  1810.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1811.             LEFT JOIN filter_params p ON p.id = f.param_id
  1812.             LEFT JOIN locale_url url ON url.filter_id = f.id
  1813.             WHERE p.count > 0 AND p.is_enable = 1 AND f.group_id = 411 $onlyIds
  1814.             ORDER BY f.name";
  1815.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  1816.         $memcache $this->cacheService->getMemcache();
  1817.         $memcacheKey md5($sql);
  1818.         $items $memcache->get($memcacheKey);
  1819.         if ($items) {
  1820.             return $items;
  1821.         }
  1822.         $items $this
  1823.             ->getEntityManager()
  1824.             ->getConnection()
  1825.             ->fetchAllAssociative($sql);
  1826.         $memcache->set($memcacheKey$items);
  1827.         return $items;
  1828.     }
  1829.     /**
  1830.      * @param string $lc
  1831.      * @param TranslatorInterface $translator
  1832.      * @return array
  1833.      */
  1834.     public function getListBrandsForMenu(string $lcTranslatorInterface $translator): array
  1835.     {
  1836.         $status BiConst::STATE_PUBLISHED ', ' BiConst::STATE_WORK_CONTINUED;
  1837.         $hideFactories HideFactoryCountriesHelper::length() > 0
  1838.             join(', 'HideFactoryCountriesHelper::codes())
  1839.             : 0;
  1840.         $sql "SELECT
  1841.                 b.id AS `id`,
  1842.                 url.$lc AS `slug`,
  1843.                 fp.name_menu_en AS `name`,
  1844.                 f.name AS `name2`,
  1845.                 f.id AS `filter_id`,
  1846.                 c.old_id AS `country.id`,
  1847.                 c.left_menu AS `country.alias`,
  1848.                 count(iia.idea_id) AS `totalIdeas`,
  1849.                 b.votes_submit AS `votesSubmit`,
  1850.                 b.votes_stars AS `votesStars`
  1851.             FROM
  1852.                 filters f
  1853.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1854.             LEFT JOIN filter_params p ON p.id = f.param_id
  1855.             LEFT JOIN locale_url url ON url.filter_id = f.id
  1856.             LEFT JOIN factory b ON b.id = f.brand
  1857.             LEFT JOIN filters c ON c.id = f.country_id
  1858.             LEFT JOIN collection coll on b.id = coll.factory and coll.status = 1
  1859.             LEFT JOIN interior inte on coll.id = inte.collection
  1860.             LEFT JOIN idea_interior iia on inte.id = iia.interior_id
  1861.             WHERE f.brand IS NOT NULL
  1862.               AND f.id != '10639'
  1863.               AND p.is_enable = 1
  1864.               AND p.count >= 0
  1865.               AND b.status IN ($status)
  1866.               AND b.unid  IS NOT NULL
  1867.               AND b.id NOT IN ($hideFactories)
  1868.             group by f.id
  1869.             ORDER BY fp.name_menu_en";
  1870.         $memcache $this->cacheService->getMemcache();
  1871.         $memcacheKey md5($sql);
  1872.         $rows $memcache->get($memcacheKey);
  1873.         if ($rows) {
  1874.             return $rows;
  1875.         }
  1876.         $rows $this
  1877.             ->getEntityManager()
  1878.             ->getConnection()
  1879.             ->fetchAll($sql);
  1880.         foreach ($rows as $i => $row) {
  1881.             $row['id'] = intval($row['id']);
  1882.             $row['totalIdeas'] = intval($row['totalIdeas']);
  1883.             $row['votesSubmit'] = intval($row['votesSubmit']);
  1884.             $row['votesStars'] = intval($row['votesStars']);
  1885.             $row['country'] = [
  1886.                 'id' => intval($row['country.id']),
  1887.                 'alias' => trim($translator->trans($row['country.alias'])),
  1888.             ];
  1889.             unset($row['country.id']);
  1890.             unset($row['country.alias']);
  1891.             $rows[$i] = $row;
  1892.         }
  1893.         $memcache->set($memcacheKey$rows);
  1894.         return $rows;
  1895.     }
  1896.     /**
  1897.      * @param int $filterParamId
  1898.      * @param int $count
  1899.      * @return bool
  1900.      * @throws \Doctrine\DBAL\Exception
  1901.      */
  1902.     public function updateCountAndShow(int $filterParamIdint $count)
  1903.     {
  1904.         // исключил из обновы фильтр коммерческая плитка и размеры
  1905.         if (in_array($filterParamId, [1017110405104061040710408])) {
  1906.             return true;
  1907.         }
  1908.         $isEnabled $count 0;
  1909.         $sql "UPDATE `filter_params` SET `count` = '$count', `is_enable` = '$isEnabled' WHERE `id` = '$filterParamId';";
  1910.         $this->getEntityManager()->getConnection()->executeStatement($sql);
  1911.         return true;
  1912.     }
  1913.     /**
  1914.      * Выборка для простановки данных из шаблона переводов
  1915.      * @return FilterEntity[]
  1916.      */
  1917.     public function consoleGetListDesigners(): array
  1918.     {
  1919.         $q $this->createQueryBuilder('f');
  1920.         $q->select('f, groups, param, page')
  1921.             ->leftJoin('f.groups''groups')
  1922.             ->leftJoin('f.param''param')
  1923.             ->leftJoin('f.page''page')
  1924.             ->andWhere("f.parentKey = 'designer'");
  1925.         return $q->getQuery()->getResult();
  1926.     }
  1927.     /**
  1928.      * @deprecated todo на удаление - не используется
  1929.      */
  1930.     public function getDesigners()
  1931.     {
  1932.         $q $this->createQueryBuilder('f');
  1933.         $q
  1934.             ->andWhere("f.oldCommand =getDesigner")
  1935.             ->setParameter('getDesigner''getDesigner')
  1936.             ->orderBy('f.name');
  1937.         return $q->getQuery()->getArrayResult();
  1938.     }
  1939.     /**
  1940.      * Выборка для слайдера
  1941.      * @param string $lc
  1942.      * @param array $filters
  1943.      * @return array
  1944.      * @throws \Doctrine\DBAL\Exception
  1945.      */
  1946.     public function getArrListForSlider(string $lc, array $filters): array
  1947.     {
  1948.         $where = [];
  1949.         foreach ($filters as $group => $ides) {
  1950.             if ($ides[0] != null) {
  1951.                 if (is_int($ides[0])) {
  1952.                     $where[] = 'g.id = ' $group ' AND f.old_id = ' $ides[0] . ' AND f.old_command = "' $ides[1] . '"';
  1953.                 } elseif (is_array($ides[0])) {
  1954.                     $where[] = 'g.id = ' $group ' AND f.old_id IN (' join(','$ides[0]) . ') AND f.old_command = "' $ides[1] . '"';
  1955.                 }
  1956.             }
  1957.         }
  1958.         if (count($where) == 0) {
  1959.             return [];
  1960.         }
  1961.         $sql "SELECT
  1962.                 f.id,
  1963.                 f.alt_name AS `altName`,
  1964.                 fp.name_menu_$lc AS `name`,
  1965.                    u.$lc AS `url`,
  1966.                 p.count AS `count`,
  1967.                 g.id AS `group.id`,
  1968.                 g.alt_name AS `group.altName`,
  1969.                 gname.$lc AS `group.name`
  1970.             FROM
  1971.                 filters f
  1972.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  1973.             LEFT JOIN filter_params p ON p.id = f.param_id
  1974.             LEFT JOIN filter_groups g ON g.id = f.group_id
  1975.             LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
  1976.             LEFT JOIN locale_url u ON u.filter_id = f.id
  1977.             LEFT JOIN factory b ON b.id = f.brand
  1978.             WHERE (g.alt_name <> 'brand' AND p.show_menu_advanced = 1 OR g.alt_name = 'brand' AND b.status = 1) AND
  1979.             (p.count > 0 OR g.alt_name = 'brand' OR g.alt_name = 'reviews') AND
  1980.             p.is_enable = 1 AND p.hide != 1 AND p.hide_all != 1 AND f.id != '10639'
  1981.             ";
  1982.         if ($where != null) {
  1983.             $sql .= ' AND (' join(' OR '$where) . ')';
  1984.         }
  1985.         $memcache $this->cacheService->getMemcache();
  1986.         $memcacheKey md5($sql);
  1987.         $rows $memcache->get($memcacheKey);
  1988.         if ($rows) {
  1989.             return $rows;
  1990.         }
  1991.         $rows $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  1992.         $memcache->set($memcacheKey$rows);
  1993.         return $rows;
  1994.     }
  1995.     public function getFiltersForSearchSphinx(array $keys$lc null)
  1996.     {
  1997.         $keys implode("','"$keys);
  1998.         $sql "SELECT
  1999.                 f.id,
  2000.                 f.old_command AS `oldCommand`,
  2001.                 f.old_id AS `oldId`
  2002.             FROM
  2003.                 filters f
  2004.             LEFT JOIN filter_params p ON p.id = f.param_id
  2005.             LEFT JOIN locale_url url ON url.filter_id = f.id
  2006.             WHERE p.count > 0 AND p.is_enable = 1 AND $lc IN ('$keys')
  2007.             ORDER BY f.name";
  2008.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  2009.         $memcache $this->cacheService->getMemcache();
  2010.         $memcacheKey md5($sql);
  2011.         $items $memcache->get($memcacheKey);
  2012.         if ($items) {
  2013.             return $items;
  2014.         }
  2015.         try {
  2016.             $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  2017.         } catch (\Doctrine\DBAL\Exception $e) {
  2018.             return [];
  2019.         }
  2020.         $res = [];
  2021.         foreach ($items as $item) {
  2022.             if (empty($res[$item['oldCommand']])) {
  2023.                 $res[$item['oldCommand']] = [];
  2024.             }
  2025.             $res[$item['oldCommand']][] = $item['oldId'];
  2026.         }
  2027.         $memcache->set($memcacheKey$res);
  2028.         return $res;
  2029.     }
  2030.     /**
  2031.      * Получение списка фильтров для формирования ссылок под рекламу в гугле
  2032.      * @return array
  2033.      * @throws \Doctrine\DBAL\Exception
  2034.      */
  2035.     public function getListForGoogleAds()
  2036.     {
  2037.         //  -- группы ------------
  2038.         // Фактура 402
  2039.         // Стиль 400
  2040.         // Мотив рисунка 421
  2041.         // Цвет 395
  2042.         // Применение 394
  2043.         // Форма 413 (кроме прямоугольник 10507, квадрат 10845, неправильная форма 10510, Многоугольник 10509 )
  2044.         // Коэффициент антискольжения 422
  2045.         // Производство 396
  2046.         //  -- фильтры ------------
  2047.         // мозаика на сетке/бумаге 10114
  2048.         // фоновая плитка 10167
  2049.         // имитация мозаики 10677
  2050.         // раковина 10162
  2051.         // Виниловая плитка 10757
  2052.         // Назначение напольное 10170
  2053.         // Назначение настенное 10169
  2054.         // Поверхность 3D 10526
  2055.         // Поверхность состаренная 10613
  2056.         // Крупноформатная плитка 10617
  2057.         // Керамогранит утолщенный 10512
  2058.         // Керамогранит тонкий 10411
  2059.         $urlStrSql = [];
  2060.         $nameSingleStrSql = [];
  2061.         $nameManyStrSql = [];
  2062.         $nameGroupStrSql = [];
  2063.         $keyAdwords $titleAdwords $keyAdwCombiFirst $titleAdwCombiFirst $keyAdwCombiOther $titleAdwCombiOther = [];
  2064.         $locales LocaleHelper::getListAvailable();
  2065.         foreach ($locales as $lc) {
  2066.             $urlStrSql[] = "url.{$lc['code']} AS `url.{$lc['code']}`";
  2067.             $nameSingleStrSql[] = "page.name_single_{$lc['code']} AS `nameSingle.{$lc['code']}`";
  2068.             $nameManyStrSql[] = "page.name_many_{$lc['code']} AS `nameMany.{$lc['code']}`";
  2069.             $nameGroupStrSql[] = "fgname.{$lc['code']} AS `groupName.{$lc['code']}`";
  2070.             $keyAdwords[] = "keyAdw.{$lc['code']} AS `keyAdwords.{$lc['code']}`";
  2071.             $titleAdwords[] = "titleAdw.{$lc['code']} AS `titleAdwords.{$lc['code']}`";
  2072.             $keyAdwCombiFirst[] = "keyAdwCombiFirst.{$lc['code']} AS `keyAdwCombiFirst.{$lc['code']}`";
  2073.             $titleAdwCombiFirst[] = "titleAdwCombiFirst.{$lc['code']} AS `titleAdwCombiFirst.{$lc['code']}`";
  2074.             $keyAdwCombiOther[] = "keyAdwCombiOther.{$lc['code']} AS `keyAdwCombiOther.{$lc['code']}`";
  2075.             $titleAdwCombiOther[] = "titleAdwCombiOther.{$lc['code']} AS `titleAdwCombiOther.{$lc['code']}`";
  2076.         }
  2077.         $urlStrSql implode(', '$urlStrSql);
  2078.         $nameSingleStrSql implode(', '$nameSingleStrSql);
  2079.         $nameManyStrSql implode(', '$nameManyStrSql);
  2080.         $nameGroupStrSql implode(', '$nameGroupStrSql);
  2081.         $keyAdwords implode(', '$keyAdwords);
  2082.         $titleAdwords implode(', '$titleAdwords);
  2083.         $keyAdwCombiFirst implode(', '$keyAdwCombiFirst);
  2084.         $titleAdwCombiFirst implode(', '$titleAdwCombiFirst);
  2085.         $keyAdwCombiOther implode(', '$keyAdwCombiOther);
  2086.         $titleAdwCombiOther implode(', '$titleAdwCombiOther);
  2087.         $sql "SELECT
  2088.                 f.id,
  2089.                 fg.alt_name AS `groupAltName`,
  2090.                 page.name_single_ru AS `name.single.ru`,
  2091.                 page.name_many_ru AS `name.many.ru`,
  2092.                 f.group_id AS `groupId`,
  2093.                 f.old_command AS `oldCommand`,
  2094.                 f.old_id AS `oldId`,
  2095.                 $urlStrSql$nameSingleStrSql$nameManyStrSql$nameGroupStrSql$keyAdwords$titleAdwords$keyAdwCombiFirst$titleAdwCombiFirst$keyAdwCombiOther{$titleAdwCombiOther}
  2096.             FROM
  2097.                 filters f
  2098.             LEFT JOIN filter_params par ON par.id = f.param_id
  2099.             LEFT JOIN filter_pages page ON page.id = f.param_id
  2100.             LEFT JOIN locale_url url ON url.filter_id = f.id
  2101.             LEFT JOIN filter_groups fg ON fg.id = f.group_id
  2102.             LEFT JOIN locale_text fgname ON fg.id = fgname.filter_group_name
  2103.             LEFT JOIN locale_text keyAdw ON f.id = keyAdw.filter_key_adwords
  2104.             LEFT JOIN locale_text titleAdw ON f.id = titleAdw.filter_title_adwords
  2105.             LEFT JOIN locale_text keyAdwCombiFirst ON f.id = keyAdwCombiFirst.filter_key_adwords_combi_first
  2106.             LEFT JOIN locale_text titleAdwCombiFirst ON f.id = titleAdwCombiFirst.filter_title_adwords_combi_first
  2107.             LEFT JOIN locale_text keyAdwCombiOther ON f.id = keyAdwCombiOther.filter_key_adwords_combi_other
  2108.             LEFT JOIN locale_text titleAdwCombiOther ON f.id = titleAdwCombiOther.filter_title_adwords_combi_other
  2109.             WHERE par.is_enable = 1 AND par.count > 3
  2110.                 AND (
  2111.                     f.group_id IN (402,400,421,395,394,413,422,396) OR
  2112.                     f.id IN (10114,10677,10162,10757,10170,10169,10526,10613,10617,10512,10411)
  2113.                     )
  2114.                 AND (f.id NOT IN (10507,10845,10510,10509) )
  2115.             ";
  2116.         $sql preg_replace('/[\s\n\r]+/'' '$sql);
  2117.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  2118.         $rows = [];
  2119.         foreach ($items as $item) {
  2120.             $fId $item['id'];
  2121.             $url = [];
  2122.             $nameSingle = [];
  2123.             $nameMany = [];
  2124.             $groupName = [];
  2125.             $keyAdwords $titleAdwords $keyAdwCombiFirst $titleAdwCombiFirst $keyAdwCombiOther $titleAdwCombiOther = [];
  2126.             foreach ($locales as $lc) {
  2127.                 $lcCode $lc['code'];
  2128.                 $url[$lcCode] = $item["url.$lcCode"];
  2129.                 $nameSingle[$lcCode] = $item["nameSingle.$lcCode"];
  2130.                 $nameMany[$lcCode] = $item["nameMany.$lcCode"];
  2131.                 $groupName[$lcCode] = $item["groupName.$lcCode"];
  2132.                 $keyAdwords[$lcCode] = trim($item["keyAdwords.$lcCode"]);
  2133.                 $titleAdwords[$lcCode] = trim($item["titleAdwords.$lcCode"]);
  2134.                 $keyAdwCombiFirst[$lcCode] = trim($item["keyAdwCombiFirst.$lcCode"]);
  2135.                 $titleAdwCombiFirst[$lcCode] = trim($item["titleAdwCombiFirst.$lcCode"]);
  2136.                 $keyAdwCombiOther[$lcCode] = trim($item["keyAdwCombiOther.$lcCode"]);
  2137.                 $titleAdwCombiOther[$lcCode] = trim($item["titleAdwCombiOther.$lcCode"]);
  2138.             }
  2139.             //заменяем первый заговоловок на поле Заголовок из формы рекламы фильтра
  2140.             $titleAdwCombiFirst $titleAdwords;
  2141.             $rows[$fId] = [
  2142.                 'id' => $fId,
  2143.                 'groupId' => $item['groupId'],
  2144.                 'groupAltName' => $item['groupAltName'],
  2145.                 'name.single.ru' => $item['name.single.ru'],
  2146.                 'oldCommand' => $item['oldCommand'],
  2147.                 'oldId' => $item['oldId'],
  2148.                 'url' => $url,
  2149.                 'nameSingle' => $nameSingle,
  2150.                 'nameMany' => $nameMany,
  2151.                 'groupName' => $groupName,
  2152.                 'adwords' => [
  2153.                     'keysOne' => $keyAdwords,
  2154.                     'titleOne' => $titleAdwords,
  2155.                     'keysCombiFirst' => $keyAdwCombiFirst,
  2156.                     'titleCombiFirst' => $titleAdwCombiFirst,
  2157.                     'keysCombiOther' => $keyAdwCombiOther,
  2158.                     'titleCombiOther' => $titleAdwCombiOther,
  2159.                 ],
  2160.             ];
  2161.         }
  2162.         return $rows;
  2163.     }
  2164.     private function buildSQLSelectForFilterResponseDTO(string $lc): string
  2165.     {
  2166.         $lcs LocaleHelper::getListAvailable();
  2167.         $lcs array_column($lcs'code');
  2168.         $urlSelect = [];
  2169.         foreach ($lcs as $lc_) {
  2170.             $urlSelect[] = "url.$lc_ AS `slug.$lc_`";
  2171.         }
  2172.         $urlSelect implode(', '$urlSelect);
  2173.         return "SELECT
  2174.                 f.id,
  2175.                 f.rank AS `rank`,
  2176.                 f.alt_name AS `altName`,
  2177.                 f.old_command AS `sphinxName`,
  2178.                 f.old_id AS `sphinxId`,
  2179.                 htmlshow.$lc AS `isHtmlShow`,
  2180.                 fp.name_menu_$lc AS `nameMenu`,
  2181.                 fp.name_many_$lc AS `nameMany`,
  2182.                 fp.name_single_$lc AS `nameSingle`,
  2183.                 fp.html_$lc AS `html`,
  2184.                 fp.description_$lc AS `description`,
  2185.                 metadesc.$lc AS `metaDescriptionName`,
  2186.                 par.count AS `count`,
  2187.                 par.code AS `code`,
  2188.                 par.is_enable AS `isEnable`,
  2189.                 gr.id AS `groupId`,
  2190.                 gr.alt_name AS `groupAltName`,
  2191.                 gpname.$lc AS `groupName`,
  2192.                 url.$lc AS `slug`, $urlSelect,
  2193.                 b.id AS `brandId`,
  2194.                 b.status AS `brandStatus`,
  2195.                 b.stated_at AS `brandStatedAt`,
  2196.                 b.type AS `brandType`,
  2197.                 b.name AS `brandName`,
  2198.                 f.logo AS `brandLogo`,
  2199.                 f.logo_url AS `brandLogoUrl`,
  2200.                 b.sound AS `brandSound`,
  2201.                 b.video AS `brandVideo`,
  2202.                 cn.id AS `countryId`,
  2203.                 cnfp.name_single_$lc AS `countryName`,
  2204.                 cnurl.$lc AS `countrySlug`,
  2205.                 cnpar.code AS `countryCode`
  2206.             FROM
  2207.                 filters f
  2208.             LEFT JOIN filter_pages fp ON fp.id = f.page_id
  2209.             LEFT JOIN filter_params par ON par.id = f.param_id
  2210.             LEFT JOIN filter_groups gr ON gr.id = f.group_id
  2211.             LEFT JOIN locale_text gpname ON gpname.filter_group_name = gr.id
  2212.             LEFT JOIN locale_text metadesc ON metadesc.filter_name_for_meta_descr_id = f.id
  2213.             LEFT JOIN locale_url url ON url.filter_id = f.id
  2214.             LEFT JOIN locale_bool htmlshow ON htmlshow.filter_html_show_id = f.id
  2215.             LEFT JOIN factory b ON b.id = f.brand
  2216.             LEFT JOIN filters cn ON cn.id = f.country_id
  2217.             LEFT JOIN filter_pages cnfp ON cnfp.id = cn.page_id
  2218.             LEFT JOIN locale_url cnurl ON cnurl.filter_id = cn.id
  2219.             LEFT JOIN filter_params cnpar ON cnpar.id = cn.param_id
  2220.             ";
  2221.     }
  2222.     /**
  2223.      * $this->buildFilterResponseDTO($item);
  2224.      * @param array $data
  2225.      * @return FilterResponseDTO|null
  2226.      */
  2227.     private function buildFilterResponseDTO(array $data): ?FilterResponseDTO
  2228.     {
  2229.         if (!$data['slug']) {
  2230.             return null;
  2231.         }
  2232.         $lcs LocaleHelper::getListAvailable();
  2233.         $lcs array_column($lcs'code');
  2234.         $slugs = [];
  2235.         foreach ($lcs as $lc_) {
  2236.             $slugs[$lc_] = $data["slug.$lc_"];
  2237.         }
  2238.         $country = !$data['countryId']
  2239.             ? null
  2240.             : new FilterCountryResponseDTO(
  2241.                 (int) $data['countryId'],
  2242.                 $data['countryName'],
  2243.                 $data['countrySlug'],
  2244.                 $data['countryCode'],
  2245.             );
  2246.         $brand = !$data['brandId']
  2247.             ? null
  2248.             : new BrandResponseDTO(
  2249.                 (int) $data['brandId'],
  2250.                 (int) $data['brandStatus'],
  2251.                 $data['brandName'],
  2252.                 $data['slug'],
  2253.                 $data['brandLogo'],
  2254.                 $data['brandLogoUrl'],
  2255.                 (int) $data['brandType'],
  2256.                 $data['brandStatedAt'],
  2257.                 $data['brandSound'],
  2258.                 $data['brandVideo'] ? json_decode($data['brandVideo']) : null,
  2259.                 $data['description'],
  2260.                 $country,
  2261.             );
  2262.         return new FilterResponseDTO(
  2263.             (int) $data['id'],
  2264.             $data['altName'],
  2265.             (int) $data['sphinxId'],
  2266.             $data['sphinxName'],
  2267.             $data['nameMenu'],
  2268.             $data['nameMany'],
  2269.             $data['nameSingle'],
  2270.             (bool) $data['isHtmlShow'],
  2271.             $data['metaDescriptionName'],
  2272.             $data['html'],
  2273.             $data['count'],
  2274.             $data['code'],
  2275.             (bool) $data['isEnable'],
  2276.             (int) $data['groupId'],
  2277.             $data['groupName'],
  2278.             $data['groupAltName'],
  2279.             $data['slug'],
  2280.             $slugs,
  2281.             $data['description'],
  2282.             $brand
  2283.         );
  2284.     }
  2285.     /**
  2286.      * @param string $sql
  2287.      * @param string $locale
  2288.      * @return FilterResponseDTO[]
  2289.      * @throws \Doctrine\DBAL\Driver\Exception
  2290.      * @throws \Doctrine\DBAL\Exception
  2291.      */
  2292.     private function getKeysBySql(string $sqlstring $locale): array
  2293.     {
  2294.         $memcache $this->cacheService->getMemcache();
  2295.         $memcacheKey md5($sql) . $locale;
  2296.         $rows $memcache->get($memcacheKey);
  2297.         if ($rows) {
  2298.             return $rows;
  2299.         }
  2300.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
  2301.         $ids array_column($items'id');
  2302.         $rows $this->getSortedByIds($ids$locale);
  2303.         $memcache->set($memcacheKey$rows);
  2304.         return $rows;
  2305.     }
  2306.     /**
  2307.      * Получает фильтры и соответствующие группы по идентификатору группы.
  2308.      *
  2309.      * @param int $groupId Идентификатор группы.
  2310.      * @return array Массив с данными фильтров и групп.
  2311.      */
  2312.     public function getFiltersByGroupId(int $groupId): array
  2313.     {
  2314.         $urlStrSql = [];
  2315.         $keyAdwords $titleAdwords $keyAdwCombiFirst $titleAdwCombiFirst $keyAdwCombiOther $titleAdwCombiOther = [];
  2316.         $locales LocaleHelper::getListAvailable();
  2317.         foreach ($locales as $lc) {
  2318.             $urlStrSql[] = "url.{$lc['code']} AS `url.{$lc['code']}`";
  2319.             $keyAdwords[] = "keyAdw.{$lc['code']} AS `keyAdwords.{$lc['code']}`";
  2320.             $titleAdwords[] = "titleAdw.{$lc['code']} AS `titleAdwords.{$lc['code']}`";
  2321.             $keyAdwCombiFirst[] = "keyAdwCombiFirst.{$lc['code']} AS `keyAdwCombiFirst.{$lc['code']}`";
  2322.             $titleAdwCombiFirst[] = "titleAdwCombiFirst.{$lc['code']} AS `titleAdwCombiFirst.{$lc['code']}`";
  2323.             $keyAdwCombiOther[] = "keyAdwCombiOther.{$lc['code']} AS `keyAdwCombiOther.{$lc['code']}`";
  2324.             $titleAdwCombiOther[] = "titleAdwCombiOther.{$lc['code']} AS `titleAdwCombiOther.{$lc['code']}`";
  2325.         }
  2326.         $urlStrSql implode(', '$urlStrSql);
  2327.         $keyAdwords implode(', '$keyAdwords);
  2328.         $titleAdwords implode(', '$titleAdwords);
  2329.         $keyAdwCombiFirst implode(', '$keyAdwCombiFirst);
  2330.         $titleAdwCombiFirst implode(', '$titleAdwCombiFirst);
  2331.         $keyAdwCombiOther implode(', '$keyAdwCombiOther);
  2332.         $titleAdwCombiOther implode(', '$titleAdwCombiOther);
  2333.         $sql "SELECT
  2334.                 f.id,
  2335.                 f.name AS name,
  2336.                 f.alt_name AS altName,
  2337.                 g.id AS groupId,
  2338.                 p.count AS count,
  2339.                 $urlStrSql,
  2340.                 $keyAdwords,
  2341.                 $titleAdwords,
  2342.                 $keyAdwCombiFirst,
  2343.                 $titleAdwCombiFirst,
  2344.                 $keyAdwCombiOther,
  2345.                 $titleAdwCombiOther
  2346.             FROM
  2347.                 filters f
  2348.             LEFT JOIN filter_groups g ON g.id = f.group_id
  2349.             LEFT JOIN filter_params p ON p.id = f.param_id
  2350.             LEFT JOIN locale_url url ON url.filter_id = f.id
  2351.             LEFT JOIN locale_text keyAdw ON keyAdw.filter_key_adwords = f.id
  2352.             LEFT JOIN locale_text titleAdw ON titleAdw.filter_title_adwords = f.id
  2353.             LEFT JOIN locale_text keyAdwCombiFirst ON keyAdwCombiFirst.filter_key_adwords_combi_first = f.id
  2354.             LEFT JOIN locale_text titleAdwCombiFirst ON titleAdwCombiFirst.filter_title_adwords_combi_first = f.id
  2355.             LEFT JOIN locale_text keyAdwCombiOther ON keyAdwCombiOther.filter_key_adwords_combi_other = f.id
  2356.             LEFT JOIN locale_text titleAdwCombiOther ON titleAdwCombiOther.filter_title_adwords_combi_other = f.id
  2357.             WHERE
  2358.                 g.id = :groupId
  2359.             ORDER BY
  2360.                 p.count DESC
  2361.                ";
  2362.         $items $this->getEntityManager()->getConnection()->fetchAllAssociative($sql, [
  2363.             'groupId' => $groupId
  2364.         ]);
  2365.         return $items;
  2366.     }
  2367. }