<?php
namespace WebBundle\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;
use Exception;
use FlexApp\Constant\TimeConstant;
use FlexApp\DTO\BrandResponseDTO;
use FlexApp\DTO\FilterCountryResponseDTO;
use FlexApp\DTO\FilterResponseDTO;
use FlexApp\Service\CacheService;
use FlexApp\Service\RedisCachePool;
use FlexApp\ValueObject\LocaleVo;
use Import1CBundle\Helper\v3\BiConst;
use Symfony\Contracts\Translation\TranslatorInterface;
use Throwable;
use WebBundle\Entity\FilterEntity;
use WebBundle\Enum\FilterGroupEnum;
use WebBundle\Helper\App;
use WebBundle\Helper\ArrHelper;
use WebBundle\Helper\HideFactoryCountriesHelper;
use WebBundle\Helper\LocaleHelper;
use WebBundle\Helper\PathHelper;
use WebBundle\Helper\StrHelper;
use WebBundle\Traits\RepoTrait;
class FilterRepository extends ServiceEntityRepository
{
use RepoTrait;
private const QUERY_CACHE_LIFETIME = 600;
private CacheService $cacheService;
public function __construct(ManagerRegistry $registry, CacheService $cacheService)
{
parent::__construct($registry, FilterEntity::class);
$this->cacheService = $cacheService;
}
public function joinQuery($alias = 'f'): QueryBuilder
{
return $this->createQueryBuilder($alias)
->SELECT(
"$alias, url, page, param, brand, groups, articles, htmlShow, country, nameForMetaTitle, nameForMetaDescr"
)
->leftJoin("$alias.url", 'url')
->leftJoin("$alias.page", 'page')
->leftJoin("$alias.param", 'param')
->leftJoin("$alias.brand", 'brand')
->leftJoin("brand.user", 'user')
->leftJoin("$alias.groups", 'groups')
->leftJoin("$alias.articles", 'articles')
->leftJoin("$alias.htmlShow", 'htmlShow')
->leftJoin("$alias.country", 'country')
->leftJoin("$alias.nameForMetaTitle", 'nameForMetaTitle')
->leftJoin("$alias.nameForMetaDescr", 'nameForMetaDescr');
}
/**
* @param string $filterUrl
* @param string $locale
* @return FilterResponseDTO|null
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function getByKeyUrlIsLike(string $filterUrl, string $locale): ?FilterResponseDTO
{
return $this->getByUrl($filterUrl, $locale, true);
}
/**
* @param string $filterUrl
* @param string $locale
* @return FilterResponseDTO|null
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function getByKeyUrl(string $filterUrl, string $locale): ?FilterResponseDTO
{
return $this->getByUrl($filterUrl, $locale);
}
/**
* @param int|null $filterId
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getIDsForSynchCountFiltersOnlyParent(?int $filterId = null): array
{
$filterId = $filterId ? "AND (f.parent_id = '$filterId' OR f.id = '$filterId')" : '';
$sql = "SELECT DISTINCT f.parent_id
FROM filters f
WHERE f.parent_id IS NOT NULL $filterId
";
$conn = $this->getEntityManager()->getConnection();
$ids = $conn->fetchAllAssociative($sql);
if ($ids) {
$ids = array_column($ids, 'parent_id');
}
return $ids;
}
/**
* Получаем subFilter
* @param bool $new
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getFiltersSubRelation(bool $new = false): array
{
$where = $new ? ' AND p.show_menu != 0 ' : ' AND p.show_menu_advanced != 0';
$sql = "SELECT
f2.id,
f2.name,
f2.old_command,
f2.old_id,
GROUP_CONCAT(f.id) AS ids,
GROUP_CONCAT(f.old_id) AS old_ids
FROM
`filters` f
LEFT JOIN filters f2 ON
f.parent_id = f2.id
LEFT JOIN filter_params p ON
f.param_id = p.id
WHERE
f.parent_id IS NOT NULL AND p.is_enable = 1 $where
GROUP BY
f.parent_id;";
$conn = $this->getEntityManager()->getConnection();
$filterData = $conn->fetchAllAssociative($sql);
$parentMap = [];
if ($new) {
foreach ($filterData as $row) {
$ids = explode(',', $row['ids']);
$parentMap[$row['id']] = $ids;
}
} else {
foreach ($filterData as $row) {
$ids = explode(',', $row['old_ids']);
$parentMap[$row['old_command']][$row['old_id']] = $ids;
}
}
return $parentMap;
}
/**
* Получение списка фильтров для синхронизации количества
* @param int $filterParentId
* @return array
*/
public function getListForSynchCountFiltersOnlyChildren(int $filterParentId): array
{
$q = $this->createQueryBuilder('f')
->select(
'f.id id, f.name name, f.oldId oldId, f.oldCommand oldCommand, parent.id pid, param.id fpId, param.count fpCount'
)
->leftJoin('f.param', 'param')
->leftJoin('f.parent', 'parent')
->andWhere('parent.id = :pid')->setParameter('pid', $filterParentId)
->andWhere('f.oldCommand != :bm')->setParameter('bm', 'bm') // исключаем из проверок фильтр БМом
;
$q = $q->getQuery();
return $q->getArrayResult();
}
/**setCollections
* Получение списка фильтров для синхронизации количества
* WebBundle/Command/SynchronizeCommand::runSynchCountFilters()
* @param array|null $filterIds
* @param array|null $fidsExclude
* @return array|null
*/
public function getListForSynchCountFilters(?array $filterIds = [], ?array $fidsExclude = []): ?array
{
$q = $this->createQueryBuilder('f')
->select(
'f.id id, f.name name, f.oldId oldId, f.oldCommand oldCommand, parent.id pid, param.id fpId, param.count fpCount'
)
->leftJoin('f.param', 'param')
->leftJoin('f.parent', 'parent')
->andWhere('f.oldCommand != :bm')->setParameter('bm', 'bm') // исключаем из проверок фильтр БМом
;
if ($filterIds) {
$q->andWhere('f.id IN (:filterId)')->setParameter('filterId', $filterIds);
}
if ($fidsExclude) {
$q->andWhere('f.id NOT IN (:filterIdExclude)')->setParameter('filterIdExclude', $fidsExclude);
}
$q = $q->getQuery();
return $q->getArrayResult();
}
public function getListForOneC(): array
{
$q = $this->joinQuery('f');
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter', ['getListForOneC']);
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
return $r->getArrayResult();
}
/**
* @param array $oldIds
* @param string $oldCommand
* @param string $locale
* @return array|FilterResponseDTO[]
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function getByOldCommand(array $oldIds, string $oldCommand, string $locale): array
{
$oldIds = array_map('intval', $oldIds);
$oldIds = array_unique($oldIds);
$oldIds = array_filter($oldIds);
if ($oldIds) {
$fidsStr = implode(',', $oldIds);
$fidsStr = "f.old_id IN ($fidsStr) AND";
} else {
$fidsStr = '';
}
$sql = "SELECT f.id AS `id` FROM filters f WHERE $fidsStr f.old_command = '$oldCommand'";
return $this->getKeysBySql($sql, $locale);
}
/**
* @param string $filterAltName
* @param string $locale
* @return FilterResponseDTO[]
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function getFilterDTOByAltName(string $filterAltName, string $locale): array
{
$sql = "SELECT f.id AS `id` FROM filters f WHERE f.alt_name = '$filterAltName'";
return $this->getKeysBySql($sql, $locale);
}
/**
* Получаем key для URL для дизайнерского стиля
* @param null $lc
* @return mixed|null
*/
public function getKeyDesignerStyle($lc = null)
{
$lc = $lc ?: LocaleHelper::getCurLocale();
$q = $this->createQueryBuilder('f');
$q->select("url.$lc")
->leftJoin('f.url', 'url')
->andWhere("f.altName = :filterAltName")
->setParameter('filterAltName', 'designer')
->setMaxResults(1);
$cacheName = $this->buildCacheName('filter_designer_style', [$lc]);
$r = $q->getQuery()->useQueryCache(true)->enableResultCache(TimeConstant::WEEK, $cacheName);
try {
$item = $r->getSingleResult();
$item = $item[$lc];
} catch (Exception $e) {
return null;
}
return $item;
}
/**
* @param null $filterAltName
* @param null $groupAltName
* @param bool $isLike
* @return mixed
*/
public function getByAltName($filterAltName = null, $groupAltName = null, bool $isLike = false)
{
$aParams = [];
$operate = $isLike ? 'LIKE' : '=';
$q = $this->createQueryBuilder('f');
$q->select('f, groups, page, url, nameForMetaTitle, nameForMetaDescr')
->leftJoin('f.groups', 'groups')
->leftJoin('f.page', 'page')
->leftJoin('f.url', 'url')
->leftJoin('f.nameForMetaTitle', 'nameForMetaTitle')
->leftJoin('f.nameForMetaDescr', 'nameForMetaDescr');
if ($filterAltName) {
$q->andWhere("f.altName $operate :filterAltName");
if ($isLike) {
$filterAltName = '%' . $filterAltName . '%';
}
$aParams['filterAltName'] = $filterAltName;
}
if ($groupAltName) {
$q->andWhere("groups.altName $operate :groupAltName");
if ($isLike) {
$groupAltName = '%' . $groupAltName . '%';
}
$aParams['groupAltName'] = $groupAltName;
}
$q->setParameters($aParams);
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getByAltName', [$filterAltName, $groupAltName]);
$r->useQueryCache(true)->enableResultCache(TimeConstant::DAY, $cacheName);
return $r->getResult();
}
/**
* @param int $oldId
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getFilterIdsByOldId(int $oldId): array
{
$sql = "SELECT f.id
FROM filters f
WHERE f.old_id = $oldId
";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$ids = $memcache->get($memcacheKey);
if ($ids) {
return $ids;
}
$conn = $this->getEntityManager()->getConnection();
$ids = $conn->fetchAllAssociative($sql);
$memcache->set($memcacheKey, $ids);
return $ids;
}
/**
* Получение одного ID по OldID
* @param int $oldId
* @param string $oldCommand
* @return int|null
*/
public function getFilterIdByOldId(int $oldId, string $oldCommand): ?int
{
$sql = "SELECT f.id FROM filters f WHERE f.old_id = '$oldId' AND f.old_command = '$oldCommand' LIMIT 1";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$id = $memcache->get($memcacheKey);
if ($id) {
return $id;
}
try {
$conn = $this->getEntityManager()->getConnection();
$id = $conn->executeQuery($sql)->fetchOne();
} catch (Throwable $e) {
return null;
}
if ($id) {
$id = (int) $id;
$memcache->set($memcacheKey, $id);
}
return $id ?: null;
}
/**
* Получение массива ID по массиву OldID
* @param array $oldIds
* @param string $oldCommand
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getFilterIdsByOldIds(array $oldIds, string $oldCommand): array
{
$conn = $this->getEntityManager()->getConnection();
$isDesigner = $oldCommand == 'getDesigner';
$oldCommand = $conn->quote($oldCommand);
$oldIds = array_map('intval', array_filter($oldIds, 'is_numeric'));
$oldIds = implode("', '", $oldIds);
$oldIds = "'$oldIds'";
$sql = "SELECT f.id FROM filters f WHERE f.old_id IN ($oldIds) AND f.old_command = $oldCommand;";
// для дизайнеров дополнительно ищем по f.id
if ($isDesigner) {
$sql = "SELECT f.id FROM filters f WHERE (f.old_id IN ($oldIds) OR f.id IN ($oldIds)) AND f.old_command = $oldCommand;";
}
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$ids = $memcache->get($memcacheKey);
if ($ids) {
return $ids;
}
$ids = $conn->fetchAllAssociative($sql);
if ($ids) {
$ids = array_column($ids, 'id');
} else {
$ids = [];
}
$memcache->set($memcacheKey, $ids);
return $ids;
}
/**
* Поиск фильтра по url значению
* @code (
* $oRepoFilters->getByKeyUrl('bathroom');
* $oRepoFilters->getByKeyUrl('bathroom', 'en');
* )
* @param string $filterSlug URL имя фильтра
* @param string $lc Локаль
* @param bool $isLike
* @return FilterResponseDTO|null
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
private function getByUrl(string $filterSlug, string $lc, bool $isLike = false): ?FilterResponseDTO
{
$aLocales = LocaleHelper::getListAvailable();
$aLocales = array_column($aLocales, 'code');
$andWhere = '';
if ($isLike) {
$filterSlug = '%' . $filterSlug . '%';
}
foreach ($aLocales as $loc) {
if ($isLike) {
$andWhere .= "url.$loc LIKE :slug OR ";
} else {
$andWhere .= "url.$loc = :slug OR ";
}
}
$andWhere = trim(trim($andWhere), 'OR');
$sql = $this->buildSQLSelectForFilterResponseDTO($lc);
$sql = "$sql WHERE $andWhere";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$memcache = $this->cacheService->getMemcache();
$memcacheKey = $filterSlug . md5($sql);
$dtoArray = $memcache->get($memcacheKey);
if ($dtoArray) {
return $this->buildFilterResponseDTO($dtoArray);
}
$conn = $this->getEntityManager()->getConnection();
$stmt = $conn->prepare($sql);
$stmt->bindValue("slug", $filterSlug, Types::STRING);
$item = $stmt->executeQuery()->fetchAllAssociative();
if (!$item) {
return null;
}
// если значений несколько, значит не корректный запрос по каким-то причинам
if (count($item) > 1) {
return null;
}
$memcache->set($memcacheKey, $item[0]);
return $this->buildFilterResponseDTO($item[0]);
}
/**
* @param $altNames
* @return float|int|mixed|string
*/
public function getByAltNames($altNames)
{
$q = $this->joinQuery('f');
$altNames = is_string($altNames) ? explode(',', $altNames) : $altNames;
$q->andWhere('f.altName IN (:altNames)');
$q->addOrderBy('groups.sort', 'ASC');
$q->addOrderBy('f.sort', 'ASC');
$q->setParameter('altNames', $altNames);
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getByAltNames', $altNames);
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
return $r->getResult();
}
/**
* @param array $ids
* @param string $lc
* @return array|FilterResponseDTO[]
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function getSortedByIds(array $ids, string $lc)
{
if (!$ids) {
return [];
}
$conn = $this->getEntityManager()->getConnection();
$inQuery = implode(',', array_fill(0, count($ids), '?'));
$sql = $this->buildSQLSelectForFilterResponseDTO($lc);
$sql = "$sql WHERE f.id IN ($inQuery) ORDER BY gr.sort, f.sort";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql) . implode('.', $ids);
$rows = $memcache->get($memcacheKey);
if ($rows) {
return $rows;
}
$stmt = $conn->prepare($sql);
foreach ($ids as $i => $id) {
$stmt->bindValue(($i + 1), $id);
}
$items = $stmt->executeQuery()->fetchAllAssociative();
$rows = [];
foreach ($items as $item) {
$row = $this->buildFilterResponseDTO($item);
if ($row) {
$rows[] = $row;
}
}
$memcache->set($memcacheKey, $rows);
return $rows;
}
/**
* Осноной запрос получения фильтров из базы по ID с сортировкой по Filter SORT и FilterGroup SORT
* @param $id
* @param bool $toArray
* @return array|null
*/
public function getByIds($id, bool $toArray = false)
{
$q = $this->joinQuery('f');
$ids = is_string($id) ? explode(',', $id) : $id;
if (count($ids) == 1) {
$q->andWhere('f.id = :ids');
} else {
$q->andWhere('f.id IN (:ids)');
}
$q->andWhere('f.id IN (:ids)');
$q->addOrderBy('groups.sort', 'ASC');
$q->addOrderBy('f.sort', 'ASC');
$q->setParameter('ids', $ids);
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getByIds', $id);
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
if ($toArray) {
$items = $r->getArrayResult();
} else {
$items = $r->getResult();
}
return $items;
}
/**
* Осноной запрос получения фильтров из базы по ID с сортировкой по Filter SORT и FilterGroup SORT
* @param $altName
* @return array|null
*/
public function getByGroupAlias($altName)
{
$q = $this->joinQuery('f');
$q->andWhere('groups.altName = :altName');
$q->addOrderBy('groups.sort', 'ASC');
$q->setParameter('altName', $altName);
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getByGroupAlias', $altName);
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
$items = $r->getResult();
return (count($items) == 1) ? $items[0] : $items;
}
public function getListDesignersByGroupAlias($altName)
{
$q = $this->joinQuery('f');
$q->andWhere('groups.altName = :altName');
$q->andWhere('param.count > 0');
$q->addOrderBy('f.name', 'ASC');
$q->addOrderBy('groups.sort', 'ASC');
$q->setParameter('altName', $altName);
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getListDesignersByGroupAlias', $altName);
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
return $r->getResult();
}
/**
* Формирование массива ссылок на фильтры в футере
* @return array
* @throws Exception
*/
public function getForFooterByGroupAlias(): array
{
$memcache = $this->cacheService->getMemcache();
$lcFull = App::getCurLocale(true);
$list = $memcache->get('footer.links.filter.' . App::isDev() . $lcFull);
if (!$list) {
$ids = [10040, 10136, 10132, 10111, 10147, 10617, 10646, 10146];
$idsStr = '10040,10136,10132,10111,10147,10617,10646,10146';
$locales = LocaleHelper::getListAvailable();
$router = App::getContainer()->get('router');
$translator = App::getTranslator();
$urlStrSql = [];
foreach ($locales as $item) {
$urlStrSql[] = "url.{$item['code']} AS `url.{$item['code']}`";
}
$urlStrSql = implode(', ', $urlStrSql);
$sql = "SELECT
f.id,
f.left_menu AS leftMenu, $urlStrSql
FROM filters f
LEFT JOIN `locale_url` `url` ON `url`.filter_id = f.id
WHERE f.id IN ($idsStr)
";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
// в многомерные массивы переводим
foreach ($items as $i => $item) {
foreach ($item as $k => $v) {
if (preg_match("~(.*)\.(.*)~ui", $k, $out)) {
$k1 = $out[1];
$k2 = $out[2];
if (empty($item[$k1])) {
$item[$k1] = [];
}
$item[$k1][$k2] = $v;
unset($item[$k]);
}
}
$items[$i] = $item;
}
$ids = array_flip($ids);
$lc_ = App::getCurLocale();
// выставляем порядок и сразу формируем имя и урл
foreach ($items as $i => $item) {
$key = $item['leftMenu'] . '_footer';
//$key = $item['leftMenu'];
$name = $translator->trans($key, [], null, $lc_);
$ids[$item['id']] = [
'name' => $name,
'url' => urldecode(
$router->generate(
'app_catalog',
[
'key' => $item['url'][$lc_],
'_locale' => $lcFull,
]
)
),
];
}
$list = $ids;
$memcache->add('footer.links.filter.' . App::isDev() . $lcFull, $list, false, 3600 * 24 * 30);
}
return $list;
}
/**
* Получение фабрики через фильтры.
* @param array $param
* @return array|null
* @throws NonUniqueResultException
* @throws Exception
* @see WebBundle/Repository/FactoryRepository::getFactory()
*/
public function getBrand(array $param = [])
{
if (!empty($param['count'])) {
$q = $this->createQueryBuilder('f')
->select('COUNT(f.id)')
->leftJoin('f.brand', 'brand')
->leftJoin('f.param', 'param');
} else {
$q = $this->joinQuery('f');
}
$q
->andWhere('f.brand IS NOT NULL')
->andWhere('f.id != 10639')// 10639 это тестовая фабрика, выкидываем ее
->andWhere('brand.status = :status')
->andWhere('param.isEnabled = true')
->andWhere('param.count >= 0')
->andWhere('brand.unid IS NOT NULL')
->setParameter('status', BiConst::STATE_PUBLISHED)
->orderBy('f.name');
if (!empty($param['url'])) {
$q->andWhere('f.url = :url')
->setParameter('url', $param['url']);
}
if (!empty($param['name'])) {
$q->andWhere('f.name = :name')
->setParameter('name', $param['name']);
}
if (!empty($param['id'])) {
$q->andWhere('f.id = :filterId');
$q->setParameter('filterId', $param['id']);
}
if (!App::isRole('ROLE_TEST')) {
$q->andWhere('brand.testAccess IS NULL');
}
$r = $q->getQuery();
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
if (!empty($param['count'])) {
$items = $r->getSingleScalarResult();
} else {
if (empty($param['asArray'])) {
$items = $r->getResult();
} else {
$items = $r->getArrayResult();
}
}
return $items;
}
/**
* Хелпер по получению записей брендов
* @param array $param
* @return array|null
*/
public function getBrands(array $param = [])
{
$parameters = [];
$q = $this->joinQuery('f');
$q
->andWhere("groups.altName = 'brand'")
//->andWhere('f.brand IS NOT NULL')
//->addSelect('country')
//->leftJoin('brand.country', 'country')
;
if (!is_array($param)) {
$paramId = intval($param);
if ($paramId) {
$param = ['id' => $paramId];
}
}
if (!empty($param['id'])) {
$q->andWhere('f.id = :brandId');
$parameters['brandId'] = $param['id'];
}
if (isset($param['noBrand'])) {
$q->andWhere('f.brand IS NULL');
}
if (!empty($param['factoryId'])) {
$q->andWhere('f.brand = :factoryId');
$parameters['factoryId'] = $param['factoryId'];
}
if (!empty($param['name'])) {
$q->andWhere('f.name = :name');
$parameters['name'] = $param['name'];
}
if (count($parameters) > 0) {
$q->setParameters($parameters);
}
$r = $q->getQuery();
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
if (empty($param['asArray'])) {
$items = $r->getResult();
} else {
$items = $r->getArrayResult();
}
return $items;
}
/**
* Получение списка фильтров для меню фильтрации
* @return array|null
*/
public function getArrListForFilterMenu()
{
$q = $this->joinQuery('f');
$q
->andWhere('param.isEnabled = 1')
//->andWhere('param.showMenuAdvanced = 1')
//->andWhere('param.count > 0')
//->andWhere("(param.showMenuAdvanced = 1 AND f.oldCommand != 'factory')")
->orderBy('f.sort ASC, f.name');
$r = $q->getQuery();
$r->useQueryCache(true)->enableResultCache((int) TimeConstant::HOUR); // час
return $r->getResult();
}
/**
* Выборка для расширенного меню фильтров
* @param $lc
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getArrListForFilterMenuNew($lc): array
{
$sql = "SELECT
f.id,
f.alt_name AS `altName`,
f.sort AS `sort`,
f.parent_id AS `pid`,
f.old_command AS `oldCommand`,
fp.name_menu_$lc AS `name`,
u.$lc AS `url`,
p.count AS `count`,
p.hex_code AS `hexCode`,
p.show_menu_advanced AS `showMenuAdvanced`,
g.id AS `group.id`,
g.alt_name AS `group.altName`,
gname.$lc AS `group.name`,
tooltip.$lc AS `tooltip`,
c.id AS `country.id`,
c.old_id AS `country.code`,
c.alt_name AS `country.altName`,
cp.name_menu_$lc AS `country.name`,
b.id AS `brand.id`,
b.name AS `brand.name`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN filter_groups g ON g.id = f.group_id
LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
LEFT JOIN locale_text tooltip ON tooltip.filter_tooltip = f.id
LEFT JOIN filters c ON c.id = f.country_id
LEFT JOIN filter_pages cp ON cp.id = c.page_id
LEFT JOIN locale_url u ON u.filter_id = f.id
LEFT JOIN factory b ON b.id = f.brand
WHERE (g.alt_name <> 'brand' AND p.show_menu_advanced = 1 OR g.alt_name = 'brand' AND b.status = 1) AND
(p.count > 0 OR g.alt_name = 'brand' OR g.alt_name = 'reviews') AND
p.is_enable = 1 AND p.hide != 1 AND p.hide_all != 1 AND f.id != '10639'
ORDER BY f.sort, f.name";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$rows = $memcache->get($memcacheKey);
if ($rows) {
return $rows;
}
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$rows = [];
foreach ($items as $item) {
$name = $item['name'];
$group = [
'id' => intval($item['group.id']),
'name' => $item['group.name'],
'altName' => $item['group.altName'],
];
// выносим в отдельную категорию крупный размер плитки
if ($item['oldCommand'] == 'size_big') {
$group = [
'id' => 0,
'name' => 'Other',
'altName' => 'other',
];
}
$country = null;
if (!empty($item['country.id'])) {
$country = [
'id' => intval($item['country.id']),
'code' => intval($item['country.code']),
'name' => $item['country.name'],
'altName' => $item['country.altName'],
];
}
$brand = null;
if (!empty($item['brand.id'])) {
$brand = [
'id' => intval($item['brand.id']),
'name' => $item['brand.name'],
];
// меняем основное имя на имя фабрики, на всякий случай
$name = $item['brand.name'];
}
// ID родительского фильтра
$pid = intval($item['pid']);
$pid = $pid ?: null;
// исключил все случайно попадающие награды в список фильтров
if ($group['altName'] == 'rewards') {
if ($item['id'] != '10546') {
continue;
}
}
$row = [
'id' => intval($item['id']),
'pid' => $pid,
'name' => $name,
'altName' => $item['altName'],
'tooltip' => $item['tooltip'],
'oldCommand' => $item['oldCommand'],
'key' => $item['url'],
'hexCode' => $item['hexCode'],
'count' => intval($item['count']),
'sort' => intval($item['sort']),
'showMenuAdvanced' => boolval($item['showMenuAdvanced']),
'group' => $group,
'brand' => $brand,
'country' => $country,
'collection' => [],
'selected' => [],
'sub' => [],
'groupList' => [],
];
$rows[$row['id']] = $row;
}
$memcache->set($memcacheKey, $rows);
return $rows;
}
/**
* Получаем массив всех фильтров для меню
* @param null $groups
* @param $lc
* @param bool $ignoreEnabled
* @return array|null
* @throws Exception
*/
public function getArrListForMenu($groups, $lc, bool $ignoreEnabled = false): ?array
{
$lcUc = ucfirst($lc);
$selectByLc = "url.$lc url$lcUc, page.nameMenu$lcUc pageNameMenu$lcUc,";
// костыль для фильтра цен, что бы показывать верно для разных стран
$lcPrice = LocaleHelper::getLocaleForPriceFilter($lc);
if ($lc != $lcPrice) {
$lcUcPrice = ucfirst($lcPrice);
$selectByLc .= "url.$lcPrice url$lcUcPrice, page.nameMenu$lcUcPrice pageNameMenu$lcUcPrice,";
}
$q = $this->createQueryBuilder('f')
->select(
"
f,
f.id,
f.oldCommand,
f.oldId,
f.leftMenu,
parent.id pid,
f.important,
$selectByLc
groups.altName groupsAltName,
param.count paramCount,
country
"
)
->leftJoin('f.url', 'url')
->leftJoin('f.page', 'page')
->leftJoin('f.param', 'param')
->leftJoin('f.groups', 'groups')
->leftJoin('f.country', 'country')
->leftJoin('f.parent', 'parent');
if (!$ignoreEnabled) {
$q
->andWhere('param.isEnabled = 1')
->andWhere('param.showMenu = 1 OR param.showMenuAdvanced = 1')
->andWhere('url.' . $lc . ' is not null')
->andWhere('param.count > 0');
}
$q->orderBy('f.sort ASC, f.name');
if ($groups) {
$groups = is_array($groups) ? $groups : [$groups];
$q->andWhere('groups.altName IN (:groups)')
->setParameter('groups', $groups);
}
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getArrListForMenu2_' . $lc . $lcPrice, $groups);
$r->useQueryCache(true);
if (!App::isDev() or !$ignoreEnabled) {
$r->enableResultCache(TimeConstant::DAY, $cacheName);
}
$res = [];
$items = $r->getArrayResult();
/** @var FilterEntity $item */
foreach ($items as $item) {
$f = $item[0];
unset($item[0]);
$item['country'] = $f['country'];
$res[$item['groupsAltName']][] = $item;
}
return $res;
}
/**
* Получаем массив всех детей по рабителю для фейк тегов
* @param null $groups
* @param $lc
* @param bool $ignoreEnabled
* @return array|null
* @throws Exception
*/
public function getArrListSubForMenu($pid, $lc, bool $ignoreEnabled = false): ?array
{
$lcUc = ucfirst($lc);
$selectByLc = "url.$lc url$lcUc, page.nameMenu$lcUc pageNameMenu$lcUc,";
// костыль для фильтра цен, что бы показывать верно для разных стран
$lcPrice = LocaleHelper::getLocaleForPriceFilter($lc);
if ($lc != $lcPrice) {
$lcUcPrice = ucfirst($lcPrice);
$selectByLc .= "url.$lcPrice url$lcUcPrice, page.nameMenu$lcUcPrice pageNameMenu$lcUcPrice,";
}
$q = $this->createQueryBuilder('f')
->select(
"
$selectByLc
f
"
)
->leftJoin('f.url', 'url')
->leftJoin('f.page', 'page')
->leftJoin('f.param', 'param')
->leftJoin('f.groups', 'groups')
->leftJoin('f.country', 'country')
->leftJoin('f.parent', 'parent');
if (!$ignoreEnabled) {
$q
->andWhere('param.isEnabled = 1')
->andWhere('parent.id = ' . $pid)
->andWhere('param.showMenu = 1 OR param.showMenuAdvanced = 1')
->andWhere('url.' . $lc . ' is not null')
->andWhere('param.count > 0');
}
$q->orderBy('f.sort ASC, f.name');
$r = $q->getQuery();
$cacheName = $this->buildCacheName('filter_getArrListSubMenu_' . $lc . $lcPrice, $pid);
// $r->useQueryCache(true);
if (!App::isDev() or !$ignoreEnabled) {
$r->enableResultCache(TimeConstant::DAY, $cacheName);
}
$res = [];
$items = $r->getArrayResult();
/** @var FilterEntity $item */
foreach ($items as $item) {
$f = $item[0];
unset($item[0]);
$item['url'] = $item["url$lcUc"];
$item['pageNameMenu'] = $item["pageNameMenu$lcUc"];
$res[] = $item;
}
return $res;
}
public function getFilterIdForSettingsCollectionByLeft($leftMenu)
{
$q = $this->createQueryBuilder('f')
->select('f.id, f.name')
->leftJoin('f.url', 'url')
->leftJoin('f.page', 'page')
->andWhere('f.leftMenu = :leftMenu')
->setParameter('leftMenu', $leftMenu)
->getQuery()
->enableResultCache(TimeConstant::DAY);
$id = $q->getArrayResult();
return $id ? $id[0] : null;
}
public function getFilterIdForSettingsColletionByIdDesigner(int $id)
{
$q = $this->createQueryBuilder('f')
->select('f.id, f.name')
->leftJoin('f.url', 'url')
->leftJoin('f.page', 'page')
->andWhere('f.id = :id')->setParameter('id', $id)
->andWhere('f.oldCommand != :oldCommand')->setParameter('oldCommand', 'factory');
$q = $q->getQuery()->enableResultCache(TimeConstant::DAY);
$id = $q->getArrayResult();
return $id ? $id[0] : null;
}
/**
* Получаем массив данных фильтра для свойств коллекции
* URL и имя формируется сразу по локали
* @param $oldId
* @param $oldCommand
* @param null $locale
* @return mixed|null
* @throws Exception
*/
public function findFilterForSettingsColletion($oldId, $oldCommand, $locale = null)
{
$locale = $locale ?: App::getCurLocale();
$localeUc = ucfirst($locale);
$key = 'filter_' . $oldId . '_' . $oldCommand . '_' . $locale;
$res = App::getMemcache()->get($key);
if (!$res) {
$q = $this->createQueryBuilder('f');
$q->select('f, f.id, f.oldId, f.oldCommand, f.altName, f.rank, url, page');
$q
->leftJoin('f.url', 'url')
->leftJoin('f.page', 'page');
$q
->andWhere("f.oldId = :old_id")
->setParameter('old_id', $oldId)
->andWhere("f.oldCommand = :old_command")
->setParameter('old_command', $oldCommand);
$q->setMaxResults(1);
$r = $q->getQuery()->enableResultCache(TimeConstant::DAY);
$item = ArrHelper::get($r->getArrayResult(), '0');
if (!$item) {
return null;
}
$item['url'] = ArrHelper::get($item, "0.url.$locale");
$item['name'] = ArrHelper::get($item, "0.page.nameMany$localeUc");
unset($item[0]);
if (!defined('DB_NOT_CASHED')) {
App::getMemcache()->set($key, $item, false, (int) TimeConstant::WEEK); // неделя
}
$res = $item;
}
return $res;
}
/**
* Получаем список активных фильтров для просчета ранга
* @return array|null
*/
public function getForCalcRank()
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name, f.rank, param.count, groups.id gid')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->andWhere("groups.id != 406")// исключаем бренды
//->andWhere("groups.id != 411")// исключаем дизайнеров
->andWhere("groups.id != 408")// исключаем Размер
->andWhere("groups.id != 412")// исключаем top
->andWhere("groups.id != 415")// исключаем page
->andWhere("groups.id != 416")// исключаем БМ
->andWhere("groups.id != 407")// исключаем Сортировка
->andWhere("groups.id != 399")// исключаем распродажа
->andWhere("param.isEnabled = 1")//->andWhere("param.showMenu = 1")
;
$result = $q->getQuery()->enableResultCache(TimeConstant::DAY);
$res = [];
foreach ($result->getArrayResult() as $i => $item) {
$res[$item['id']] = $item;
}
return $res;
}
/**
* @param string $key
* @return FilterEntity|null
*/
public function admGetExhibitionByKeyForConsole(string $key)
{
$q = $this->createQueryBuilder('f');
$q->select('f, groups, param, page')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->leftJoin('f.page', 'page')
->andWhere("f.name LIKE '$key%'")
->andWhere('param.isEnabled = 1')
->andWhere('groups.id = 420 OR groups.id = 417')
->orderBy('f.id', 'DESC')
->setMaxResults(1);
try {
return $q->getQuery()->getSingleResult();
} catch (NoResultException | NonUniqueResultException $e) {
return null;
}
}
/**
* Получаем последний ID для сфинкса из группы
* @param int $groupId
* @return int
* @throws Throwable
*/
public function admGetExhibitionLastOldIdForConsole(int $groupId): int
{
$sql = "SELECT f.old_id AS `oldId`
FROM filters f
WHERE f.group_id = $groupId
ORDER BY f.old_id DESC LIMIT 1";
$oldId = $this->getEntityManager()
->getConnection()
->executeQuery($sql)
->fetchOne();
return intval($oldId);
}
/**
* Получение последнего дизайнера, для использования в качестве шаблона для создания нового
* @return FilterEntity|null
*/
public function admLastDesigner(): ?FilterEntity
{
$q = $this->createQueryBuilder('f');
$q->select('f, groups, param, page')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->leftJoin('f.page', 'page')
->andWhere("f.parentKey = 'designer'")
->andWhere('param.isEnabled = 1')
->orderBy('f.id', 'DESC')
->setMaxResults(1);
try {
return $q->getQuery()->getSingleResult();
} catch (NoResultException | NonUniqueResultException $e) {
return null;
}
}
/**
* Поиск последней заполненной переводами записи награды.
*/
public function getLastRewards(): ?FilterEntity
{
$q = $this->createQueryBuilder('f');
$q->select('f, groups, param, page')
->innerJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->innerJoin('f.page', 'page')
->where('groups.id = :groupId')
->andWhere('param.isEnabled = 1')
->andWhere('page.nameSingleEn IS NOT NULL AND page.nameSingleEn != :empty')
->andWhere('page.descriptionEn IS NOT NULL AND page.descriptionEn != :empty')
->orderBy('f.id', 'DESC')
->setMaxResults(1)
->setParameters([
'groupId' => FilterGroupEnum::REWARD,
'empty' => ''
]);
$query = $q->getQuery();
$query->useQueryCache(true);
$query->setQueryCacheLifetime(self::QUERY_CACHE_LIFETIME);
try {
return $query->getSingleResult();
} catch (NoResultException | NonUniqueResultException $e) {
return null;
}
}
/**
* Получение списка наград для выпадающего списка
* @return array
*/
public function admGetAwardsForSelectMenu(): array
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name')
->leftJoin('f.groups', 'groups')
->andWhere("groups.altName = 'rewards'")
->andWhere("f.oldId != 1") // исключаем фильтр общий Премированные
;
$res = [];
$out = $q->getQuery()->getArrayResult();
foreach ($out as $i => $item) {
$res[(string) $item['id']] = $item['name'];
}
return $res;
}
/**
* Список выставок для БИ и админки
* @return array
*/
public function admGetExhibitionForSelectMenu(): array
{
$q = $this->createQueryBuilder('f');
$q->select('f.oldId id, f.name')
->leftJoin('f.groups', 'groups')
->andWhere("groups.altName = 'exhibition'");
$res = [];
$out = $q->getQuery()->getArrayResult();
foreach ($out as $i => $item) {
$res[(string) $item['id']] = $item['name'];
}
return $res;
}
/**
* @param $exhibition
* @return array
*/
public function admGetExhibitionForBI($exhibition): array
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name, f.iconUrl')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->andWhere("groups.altName = 'exhibition'")
->andWhere("f.oldId in (:exhibition)")
->setParameter('exhibition', $exhibition);
$res = [];
$out = $q->getQuery()->getArrayResult();
foreach ($out as $i => $item) {
$link = $item['iconUrl'];
$res[(string) $item['id']] = (!empty($link)) ? $item['name'] . '(<a href="' . $link . '" target="_blank" rel="noopener noreferrer">' . $link . '</a>)' : $item['name'];
}
return $res;
}
public function admGetAwardsForBi($awards): array
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name, f.iconUrl')
->leftJoin('f.groups', 'groups')
->andWhere("groups.altName = 'rewards'")
->andWhere("f.oldId != 1") // исключаем фильтр общий Премированные
->andWhere("f.id in (:awards)")
->setParameter('awards', $awards);
$res = [];
$out = $q->getQuery()->getArrayResult();
foreach ($out as $i => $item) {
$link = $item['iconUrl'];
$res[(string) $item['id']] = (!empty($link)) ? $item['name'] . '(<a href="' . $link . '" target="_blank" rel="noopener noreferrer">' . $link . '</a>)' : $item['name'];
}
return $res;
}
public function admGetForJsTree(): array
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name, groups.id gr_id, groups.altName gr_name')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->andWhere("groups.id != 411")// исключаем дизайнеров
->andWhere("groups.id != 408")// исключаем Размер
//->andWhere("groups.id != 412")// исключаем top
->andWhere("groups.id != 415")// исключаем page
->andWhere("groups.id != 416")// исключаем БМ
->andWhere("groups.id != 407")// исключаем Сортировка
->andWhere("groups.id != 399")// исключаем распродажа
->andWhere("param.isEnabled = true")
->andWhere("param.showMenuAdvanced = true")
->orderBy('gr_name', 'ASC')
->addOrderBy('f.name', 'ASC')
->andWhere("groups.id != 406") // исключаем бренды
//->andWhere("groups.id = 397") // временно, что бы был один
;
$items = $q->getQuery()->getArrayResult();
$res = [];
foreach ($items as $item) {
$res[$item['gr_id']][] = $item;
}
return $res;
}
public function getSortListCataloge($locale = null)
{
$locale = $locale ?: App::getCurLocale();
$localeUc = ucfirst($locale);
$q = $this->createQueryBuilder('f')
->select("f.oldId as id, page.nameSingle$localeUc as nameSingle, page.nameMenu$localeUc as nameMenu")
->leftJoin('f.page', 'page')
->leftJoin('f.groups', 'gr')
->andWhere('gr.id = 407')
->orderBy('f.sort', 'ASC');
$r = $q->getQuery()
->useQueryCache(true);
$items = $r->getArrayResult();
$res = [];
foreach ($items as $item) {
$res[$item['id']] = $item;
}
return $res;
}
public function getAwards(array $id)
{
$localeUc = ucfirst(App::getCurLocale());
if (count($id) == 0) {
return [];
}
if (is_array($id)) {
$id = implode(', ', $id);
$id = "($id)";
}
$q = $this->createQueryBuilder('f')
->select("f.id, f.icon, f.iconUrl, page.nameSingle$localeUc")
->leftJoin('f.page', 'page')
// ->andWhere('f.icon IS NOT NULL') решили выводить данные https://te.remote.team/#/discus/649252D6-AAD4-D219-FD67-BBF3CDCA1062/
->andWhere("f.id IN $id");
$r = $q->getQuery()->useQueryCache(true);
$items = $r->getArrayResult();
$res = [];
foreach ($items as $item) {
$res[$item['id']] = [
'id' => $item['id'],
'icon' => PathHelper::pathGenerate('filter', $item),
'title' => $item["nameSingle$localeUc"],
'url' => $item['iconUrl'],
];
}
return $res;
}
/**
* Получаем выставки по oldId
* @param array $id
* @return array
* @throws Exception
*/
public function getExhibitions(array $id): array
{
$lcVo = new LocaleVo();
$lc = $lcVo->getCode();
$lcUc = ucfirst($lc);
$lcFull = $lcVo->getCodeFull();
$id = array_filter($id);
if (count($id) == 0) {
return [];
}
$id = implode(', ', $id);
$id = "($id)";
$q = $this->createQueryBuilder('f')
->select(
"f.id, f.oldId, f.iconUrl, tooltip.$lc as tooltipLc , page.nameMenu$lcUc, url.$lc as urlLocal"
)
->leftJoin('f.page', 'page')
->leftJoin('f.url', 'url')
->leftJoin('f.param', 'param')
->leftJoin('f.tooltip', 'tooltip')
->andWhere('param.isEnabled = 1')
->andWhere('param.count > 0')
->andWhere("f.oldCommand = 'exhibition'")
->andWhere("f.oldId IN $id");
$r = $q->getQuery()->enableResultCache(TimeConstant::DAY);
$router = App::getRouter();
$items = $r->getArrayResult();
$res = [];
foreach ($items as $item) {
$name = $item["nameMenu$lcUc"];
// показываем бирки только с возрастом не более 2-х лет
$year = intval(preg_replace('/\D/', '', $name));
$yearLimit = intval(date("Y")) - 2;
if ($year <= $yearLimit) {
continue;
}
$res[$item['id']] = [
'id' => $item['id'],
'sphinxId' => $item['oldId'],
'name' => $name,
'tooltip' => $item['tooltipLc'],
'urlRemote' => $item['iconUrl'],
'urlLocal' => $router->generate('app_catalog', ['key' => $item['urlLocal'], '_locale' => $lcFull]),
];
}
return $res;
}
/**
* Получаем список url фильтров по языку для sitemap
* @param $lang
* @return array|null
*/
public function getListUrlFiltersByLang($lang): ?array
{
$q = $this->createQueryBuilder('f')
->select("u.$lang url, f.leftMenu")
->leftJoin('f.url', 'u')
->leftJoin('f.groups', 'g')
->leftJoin('f.param', 'p')
->andWhere('p.hide = 0')
->andWhere('p.count > 0')
->andWhere('g.id NOT IN (:groups)')
->setParameter('groups', [407, 416, 417])
->getQuery();
$cacheName = $this->buildCacheName('filter_getListUrlFiltersByLang', $lang);
$q->useQueryCache(true)->enableResultCache((int) TimeConstant::DAY, $cacheName);
return $q->getArrayResult();
}
/**
* Получение списка для проверки на наличие кириллических символов
* @return array
*/
public function getCollectionsAdmForCheckCyrillic(): array
{
$q = $this->createQueryBuilder('f')
->select('f, page')
->leftJoin('f.page', 'page')
->leftJoin('f.param', 'param')
->andWhere("param.isEnabled = true");
return $q->getQuery()->getArrayResult();
}
/**
* Получение ID фильтра по ID бренда
* @param $idBrand
* @return mixed|null
* @throws NonUniqueResultException
*/
public function getIdFilterByIdBrand($idBrand)
{
$q = $this
->createQueryBuilder('f')
->select('f.id')
->leftJoin('f.brand', 'brand')
->andWhere('brand.id = :idBrand')
->setParameter('idBrand', $idBrand)
->setMaxResults(1)
->getQuery();
try {
$id = $q->getSingleResult();
$id = $id['id'];
} catch (NoResultException $e) {
return null;
}
return $id;
}
/**
* Проставляем связи фильтра с коллекциями
* @param int $fID
* @param $cIDs
* @return bool
* @throws Throwable
*/
public function setCollections(int $fID, $cIDs)
{
if (!$cIDs) {
return false;
}
$conn = $this->getEntityManager()->getConnection();
$cIDs = is_array($cIDs) ? $cIDs : [$cIDs];
// находим коллекции, которых нет больше и удаляем их
$cIDstr = implode(',', $cIDs);
$conn->executeStatement(
"DELETE FROM `collection_filters` WHERE `collection_id` NOT IN ($cIDstr) AND `filter_id` = '$fID';"
);
// проставляем связи для всех остальных записей
// делаем порциями по почке запросов за раз
$maxPortion = 100;
$sqlUpdate = '';
$cnt = 0;
foreach ($cIDs as $cID) {
$sqlUpdate .= "INSERT INTO `collection_filters` (`collection_id`,`filter_id`) VALUES ('$cID', '$fID') ON DUPLICATE KEY UPDATE collection_id='$cID', filter_id='$fID';";
$cnt++;
if ($cnt == $maxPortion) {
$sth = $conn->prepare($sqlUpdate);
$sth->execute();
$sth->closeCursor();
$cnt = 0;
$sqlUpdate = '';
}
}
if ($sqlUpdate != '') {
$sth = $conn->prepare($sqlUpdate);
$sth->execute();
$sth->closeCursor();
}
return true;
}
/**
* Получение фильтра для DTO выставки
* @param $fids
* @param $lc
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getForExhDTO($fids, $lc)
{
if (!$fids) {
return [];
}
$fidsStr = implode(',', $fids);
$sql = "SELECT
f.id,
f.alt_name AS `altName`,
f.old_command AS `nameSphinx`,
fp.name_menu_$lc AS `name`,
fp.name_many_$lc AS `nameMany`,
fp.name_single_$lc AS `nameFull`,
p.count AS `count`,
p.hex_code AS `hexCode`,
p.show_menu_advanced AS `showMenuAdvanced`,
p.show_menu AS `showMenu`,
g.alt_name AS `groupAltName`,
gname.$lc AS `groupName`,
c.id AS `countryId`,
c.old_id AS `countryOldId`,
cfp.name_menu_$lc AS `countryName`,
u.$lc AS `slug`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN filter_groups g ON g.id = f.group_id
LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
LEFT JOIN filters c ON c.id = f.country_id
LEFT JOIN filter_pages cfp ON cfp.id = c.page_id
LEFT JOIN locale_url u ON u.filter_id = f.id
WHERE f.id IN ($fidsStr) AND
p.count > 0 AND
g.alt_name != 'top' AND
g.alt_name != 'release_year_collection' AND
g.alt_name != 'price' AND
g.alt_name != 'brand' AND
f.alt_name != 'cataloge' AND
g.alt_name != 'using' AND
p.is_enable = 1
ORDER BY f.sort, f.name";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$memcache->set($memcacheKey, $items);
return $items;
}
/**
* Получение имени для графика статистик в админке
* @param array $fids
* @param bool $isBrand
* @return array
*/
public function getNamesForStatChartAdmin(array $fids, bool $isBrand = false)
{
$fidsStr = implode(',', $fids);
if ($isBrand) {
$where = "WHERE f.brand IN ($fidsStr)";
} else {
$where = "WHERE f.id IN ($fidsStr)";
}
$sql = "SELECT
f.id,
f.brand,
fp.name_menu_ru AS `name`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
$where
ORDER BY fp.name_menu_ru ASC";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$items = $this->getEntityManager()->getConnection()->fetchAll($sql);
$r = [];
foreach ($items as $item) {
$id = $isBrand ? $item['brand'] : $item['id'];
$r[$id] = [
'name' => $item['name'],
'data' => [],
];
}
return $r;
}
/**
* @return array
*/
public function admGetDesigners()
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name')
->leftJoin('f.groups', 'groups')
->andWhere("groups.altName = 'designer'")
->andWhere("f.oldId != 1")
->orderBy('f.name');
$res = [];
$out = $q->getQuery()->getArrayResult();
foreach ($out as $i => $item) {
$res[$item['name']] = StrHelper::toLower($item['name']);
}
return $res;
}
public function admGetDesignersId()
{
$q = $this->createQueryBuilder('f');
$q->select('f.id, f.name')
->leftJoin('f.groups', 'groups')
->andWhere("groups.altName = 'designer'")
->andWhere("f.oldId != 1")
->orderBy('f.name');
return $q->getQuery()->getArrayResult();
}
/**
* Выборка фильтров для формирования свойств коллекции
* @param $fids
* @param null $lc
* @return array
*/
public function getForCollSettings($fids, $lc = null): array
{
$lc = $lc ?: App::getCurLocale();
$fidsStr = implode(',', $fids);
$sql = "SELECT
f.id,
f.rank AS `rank`,
f.alt_name AS `altName`,
f.old_command AS `sphinxName`,
f.old_id AS `sphinxId`,
fp.name_menu_$lc AS `name`,
fp.name_many_$lc AS `nameMany`,
fp.name_single_$lc AS `nameFull`,
p.count AS `count`,
g.id AS `group.id`,
g.alt_name AS `group.altName`,
gname.$lc AS `group.name`,
url.$lc AS `slug`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN filter_groups g ON g.id = f.group_id
LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
LEFT JOIN locale_url url ON url.filter_id = f.id
WHERE
f.id IN ($fidsStr) AND
p.is_enable = 1
ORDER BY f.sort, f.name";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
$items = $this->getEntityManager()->getConnection()->fetchAll($sql);
$memcache->set($memcacheKey, $items);
return $items;
}
/**
* Получение данных для формирования имени фильтра в хистри расширенного поиска
* @param array $fids
* @return array
*/
public function getForFilterNameHistorySearch(array $fids): array
{
$lc = App::getCurLocale();
$fids = array_unique(array_map('intval', array_filter($fids, 'is_numeric')));
if (empty($fids)) {
return [];
}
$fidsStr = implode(',', $fids);
$sql = "SELECT
f.id AS `id`,
f.alt_name AS `altName`,
fpg.name_many_$lc AS `name`,
fpr.code AS `code`,
fg.alt_name AS `groupAltName`,
fg.left_menu AS `groupLeftMenu`
FROM
filters f
LEFT JOIN filter_groups fg ON fg.id = f.group_id
LEFT JOIN filter_pages fpg ON fpg.id = f.page_id
LEFT JOIN filter_params fpr ON fpr.id = f.param_id
WHERE
f.id IN ($fidsStr)";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
$items = $this->getEntityManager()->getConnection()->fetchAll($sql);
$memcache->set($memcacheKey, $items);
return $items;
}
/**
* Список для назначения родителя в админке
* @param $gid
* @param $fid
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function admGetListForParent($gid, $fid): array
{
$sql = "SELECT
f.id as `id`,
f.name AS `name.ru`,
fp.name_menu_en AS `name.en`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
WHERE f.id != $fid AND f.group_id = $gid AND p.is_enable = 1
ORDER BY `name.ru`";
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$rows = [];
foreach ($items as $item) {
$rows[$item['id']] = "{$item['name.ru']} ({$item['name.en']}) #{$item['id']}";
}
return $rows;
}
/**
* @param string $leftMenu
* @return string|null
*/
public function getKeyByLeftMenu(string $leftMenu): ?string
{
$lc = App::getCurLocale();
$sql = "SELECT
lurl.$lc AS `url`
FROM
filters f
LEFT JOIN locale_url lurl ON f.id = lurl.filter_id
WHERE f.left_menu = '$leftMenu'
LIMIT 1";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
try {
$items = $this->getEntityManager()
->getConnection()
->executeQuery($sql)
->fetchOne() ?: null;
$memcache->set($memcacheKey, $items);
return $items;
} catch (Throwable $e) {
return null;
}
}
public function getListForTestCountTranslate()
{
$q = $this->createQueryBuilder('f')
->select('f, g, p, descr, htmlShow')
->leftJoin('f.groups', 'g')
->leftJoin('f.page', 'p')
->leftJoin('f.htmlShow', 'htmlShow')
->leftJoin('f.nameForMetaDescr', 'descr')
->andWhere('g.id != 406')// фабрики
->andWhere('g.id != 411')// дизайнеры
->getQuery();
return $q->getArrayResult();
}
/**
* Получение списка ТОП фильтров, для формирования меню карусели на главной
* @return array
* @throws Exception
* @see src/WebBundle/Resources/views/Home/_top-carousel.html.twig
*/
public function getItemsForTopCollectionCarouselMenu(): array
{
$lc = App::getCurLocale();
$cacheKey = "ItemsForTopCollectionCarouselMenu.$lc";
$redisCachePool = App::getContainer()->get(RedisCachePool::class)->getPool();
$cacheItem = $redisCachePool->getItem($cacheKey);
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
$translator = App::getTranslator();
$sql = "SELECT
lurl.$lc AS `url`,
lurl.en AS `key`,
f.alt_name AS `alt`,
f.id AS `id`
FROM
filters f
LEFT JOIN locale_url lurl ON f.id = lurl.filter_id
WHERE f.id in (10592,10591)";
$rows = $this->getEntityManager()
->getConnection()
->executeQuery($sql)
->fetchAll();
$items = [
'top-all' => [
'title' => $translator->trans('main_top_all'),
'link' => App::generateUrl('app_catalog'),
'url-json' => App::generateUrl('app_last_collection', ['type' => 'top-all']),
'key' => 'top-all',
],
];
if ($rows) {
foreach ($rows as $row) {
$items[$row['key']] = [
'title' => $translator->trans("main_{$row['alt']}"),
'link' => App::generateUrl('app_catalog', ['key' => $row['url']]),
'url-json' => App::generateUrl('app_last_collection', ['type' => $row['key']]),
'key' => $row['key'],
];
}
$cacheItem->set($items);
$redisCachePool->save($cacheItem);
}
return $items;
}
/**
* Выборка для отдачи списка дизайнеров в меню в каталоге
* @param array $onlyIds
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getListDesignersForCataloge(array $onlyIds = []): array
{
if ($onlyIds) {
$onlyIds = implode("','", $onlyIds);
$onlyIds = " AND f.id IN ('$onlyIds')";
} else {
$onlyIds = '';
}
$sql = "SELECT
f.id,
f.rank AS `rank`,
f.old_command AS `oldCommand`,
f.old_id AS `oldId`,
fp.name_menu_en AS `name`,
p.count AS `cnt`,
url.en AS `slug`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN locale_url url ON url.filter_id = f.id
WHERE p.count > 0 AND p.is_enable = 1 AND f.group_id = 411 $onlyIds
ORDER BY f.name";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
$items = $this
->getEntityManager()
->getConnection()
->fetchAllAssociative($sql);
$memcache->set($memcacheKey, $items);
return $items;
}
/**
* @param string $lc
* @param TranslatorInterface $translator
* @return array
*/
public function getListBrandsForMenu(string $lc, TranslatorInterface $translator): array
{
$status = BiConst::STATE_PUBLISHED . ', ' . BiConst::STATE_WORK_CONTINUED;
$hideFactories = HideFactoryCountriesHelper::length() > 0
? join(', ', HideFactoryCountriesHelper::codes())
: 0;
$sql = "SELECT
b.id AS `id`,
url.$lc AS `slug`,
fp.name_menu_en AS `name`,
f.name AS `name2`,
f.id AS `filter_id`,
c.old_id AS `country.id`,
c.left_menu AS `country.alias`,
count(iia.idea_id) AS `totalIdeas`,
b.votes_submit AS `votesSubmit`,
b.votes_stars AS `votesStars`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN locale_url url ON url.filter_id = f.id
LEFT JOIN factory b ON b.id = f.brand
LEFT JOIN filters c ON c.id = f.country_id
LEFT JOIN collection coll on b.id = coll.factory and coll.status = 1
LEFT JOIN interior inte on coll.id = inte.collection
LEFT JOIN idea_interior iia on inte.id = iia.interior_id
WHERE f.brand IS NOT NULL
AND f.id != '10639'
AND p.is_enable = 1
AND p.count >= 0
AND b.status IN ($status)
AND b.unid IS NOT NULL
AND b.id NOT IN ($hideFactories)
group by f.id
ORDER BY fp.name_menu_en";
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$rows = $memcache->get($memcacheKey);
if ($rows) {
return $rows;
}
$rows = $this
->getEntityManager()
->getConnection()
->fetchAll($sql);
foreach ($rows as $i => $row) {
$row['id'] = intval($row['id']);
$row['totalIdeas'] = intval($row['totalIdeas']);
$row['votesSubmit'] = intval($row['votesSubmit']);
$row['votesStars'] = intval($row['votesStars']);
$row['country'] = [
'id' => intval($row['country.id']),
'alias' => trim($translator->trans($row['country.alias'])),
];
unset($row['country.id']);
unset($row['country.alias']);
$rows[$i] = $row;
}
$memcache->set($memcacheKey, $rows);
return $rows;
}
/**
* @param int $filterParamId
* @param int $count
* @return bool
* @throws \Doctrine\DBAL\Exception
*/
public function updateCountAndShow(int $filterParamId, int $count)
{
// исключил из обновы фильтр коммерческая плитка и размеры
if (in_array($filterParamId, [10171, 10405, 10406, 10407, 10408])) {
return true;
}
$isEnabled = $count > 0 ? 1 : 0;
$sql = "UPDATE `filter_params` SET `count` = '$count', `is_enable` = '$isEnabled' WHERE `id` = '$filterParamId';";
$this->getEntityManager()->getConnection()->executeStatement($sql);
return true;
}
/**
* Выборка для простановки данных из шаблона переводов
* @return FilterEntity[]
*/
public function consoleGetListDesigners(): array
{
$q = $this->createQueryBuilder('f');
$q->select('f, groups, param, page')
->leftJoin('f.groups', 'groups')
->leftJoin('f.param', 'param')
->leftJoin('f.page', 'page')
->andWhere("f.parentKey = 'designer'");
return $q->getQuery()->getResult();
}
/**
* @deprecated todo на удаление - не используется
*/
public function getDesigners()
{
$q = $this->createQueryBuilder('f');
$q
->andWhere("f.oldCommand =getDesigner")
->setParameter('getDesigner', 'getDesigner')
->orderBy('f.name');
return $q->getQuery()->getArrayResult();
}
/**
* Выборка для слайдера
* @param string $lc
* @param array $filters
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getArrListForSlider(string $lc, array $filters): array
{
$where = [];
foreach ($filters as $group => $ides) {
if ($ides[0] != null) {
if (is_int($ides[0])) {
$where[] = 'g.id = ' . $group . ' AND f.old_id = ' . $ides[0] . ' AND f.old_command = "' . $ides[1] . '"';
} elseif (is_array($ides[0])) {
$where[] = 'g.id = ' . $group . ' AND f.old_id IN (' . join(',', $ides[0]) . ') AND f.old_command = "' . $ides[1] . '"';
}
}
}
if (count($where) == 0) {
return [];
}
$sql = "SELECT
f.id,
f.alt_name AS `altName`,
fp.name_menu_$lc AS `name`,
u.$lc AS `url`,
p.count AS `count`,
g.id AS `group.id`,
g.alt_name AS `group.altName`,
gname.$lc AS `group.name`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN filter_groups g ON g.id = f.group_id
LEFT JOIN locale_text gname ON gname.filter_group_name = g.id
LEFT JOIN locale_url u ON u.filter_id = f.id
LEFT JOIN factory b ON b.id = f.brand
WHERE (g.alt_name <> 'brand' AND p.show_menu_advanced = 1 OR g.alt_name = 'brand' AND b.status = 1) AND
(p.count > 0 OR g.alt_name = 'brand' OR g.alt_name = 'reviews') AND
p.is_enable = 1 AND p.hide != 1 AND p.hide_all != 1 AND f.id != '10639'
";
if ($where != null) {
$sql .= ' AND (' . join(' OR ', $where) . ')';
}
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$rows = $memcache->get($memcacheKey);
if ($rows) {
return $rows;
}
$rows = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$memcache->set($memcacheKey, $rows);
return $rows;
}
public function getFiltersForSearchSphinx(array $keys, $lc = null)
{
$keys = implode("','", $keys);
$sql = "SELECT
f.id,
f.old_command AS `oldCommand`,
f.old_id AS `oldId`
FROM
filters f
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN locale_url url ON url.filter_id = f.id
WHERE p.count > 0 AND p.is_enable = 1 AND $lc IN ('$keys')
ORDER BY f.name";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql);
$items = $memcache->get($memcacheKey);
if ($items) {
return $items;
}
try {
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
} catch (\Doctrine\DBAL\Exception $e) {
return [];
}
$res = [];
foreach ($items as $item) {
if (empty($res[$item['oldCommand']])) {
$res[$item['oldCommand']] = [];
}
$res[$item['oldCommand']][] = $item['oldId'];
}
$memcache->set($memcacheKey, $res);
return $res;
}
/**
* Получение списка фильтров для формирования ссылок под рекламу в гугле
* @return array
* @throws \Doctrine\DBAL\Exception
*/
public function getListForGoogleAds()
{
// -- группы ------------
// Фактура 402
// Стиль 400
// Мотив рисунка 421
// Цвет 395
// Применение 394
// Форма 413 (кроме прямоугольник 10507, квадрат 10845, неправильная форма 10510, Многоугольник 10509 )
// Коэффициент антискольжения 422
// Производство 396
// -- фильтры ------------
// мозаика на сетке/бумаге 10114
// фоновая плитка 10167
// имитация мозаики 10677
// раковина 10162
// Виниловая плитка 10757
// Назначение напольное 10170
// Назначение настенное 10169
// Поверхность 3D 10526
// Поверхность состаренная 10613
// Крупноформатная плитка 10617
// Керамогранит утолщенный 10512
// Керамогранит тонкий 10411
$urlStrSql = [];
$nameSingleStrSql = [];
$nameManyStrSql = [];
$nameGroupStrSql = [];
$keyAdwords = $titleAdwords = $keyAdwCombiFirst = $titleAdwCombiFirst = $keyAdwCombiOther = $titleAdwCombiOther = [];
$locales = LocaleHelper::getListAvailable();
foreach ($locales as $lc) {
$urlStrSql[] = "url.{$lc['code']} AS `url.{$lc['code']}`";
$nameSingleStrSql[] = "page.name_single_{$lc['code']} AS `nameSingle.{$lc['code']}`";
$nameManyStrSql[] = "page.name_many_{$lc['code']} AS `nameMany.{$lc['code']}`";
$nameGroupStrSql[] = "fgname.{$lc['code']} AS `groupName.{$lc['code']}`";
$keyAdwords[] = "keyAdw.{$lc['code']} AS `keyAdwords.{$lc['code']}`";
$titleAdwords[] = "titleAdw.{$lc['code']} AS `titleAdwords.{$lc['code']}`";
$keyAdwCombiFirst[] = "keyAdwCombiFirst.{$lc['code']} AS `keyAdwCombiFirst.{$lc['code']}`";
$titleAdwCombiFirst[] = "titleAdwCombiFirst.{$lc['code']} AS `titleAdwCombiFirst.{$lc['code']}`";
$keyAdwCombiOther[] = "keyAdwCombiOther.{$lc['code']} AS `keyAdwCombiOther.{$lc['code']}`";
$titleAdwCombiOther[] = "titleAdwCombiOther.{$lc['code']} AS `titleAdwCombiOther.{$lc['code']}`";
}
$urlStrSql = implode(', ', $urlStrSql);
$nameSingleStrSql = implode(', ', $nameSingleStrSql);
$nameManyStrSql = implode(', ', $nameManyStrSql);
$nameGroupStrSql = implode(', ', $nameGroupStrSql);
$keyAdwords = implode(', ', $keyAdwords);
$titleAdwords = implode(', ', $titleAdwords);
$keyAdwCombiFirst = implode(', ', $keyAdwCombiFirst);
$titleAdwCombiFirst = implode(', ', $titleAdwCombiFirst);
$keyAdwCombiOther = implode(', ', $keyAdwCombiOther);
$titleAdwCombiOther = implode(', ', $titleAdwCombiOther);
$sql = "SELECT
f.id,
fg.alt_name AS `groupAltName`,
page.name_single_ru AS `name.single.ru`,
page.name_many_ru AS `name.many.ru`,
f.group_id AS `groupId`,
f.old_command AS `oldCommand`,
f.old_id AS `oldId`,
$urlStrSql, $nameSingleStrSql, $nameManyStrSql, $nameGroupStrSql, $keyAdwords, $titleAdwords, $keyAdwCombiFirst, $titleAdwCombiFirst, $keyAdwCombiOther, {$titleAdwCombiOther}
FROM
filters f
LEFT JOIN filter_params par ON par.id = f.param_id
LEFT JOIN filter_pages page ON page.id = f.param_id
LEFT JOIN locale_url url ON url.filter_id = f.id
LEFT JOIN filter_groups fg ON fg.id = f.group_id
LEFT JOIN locale_text fgname ON fg.id = fgname.filter_group_name
LEFT JOIN locale_text keyAdw ON f.id = keyAdw.filter_key_adwords
LEFT JOIN locale_text titleAdw ON f.id = titleAdw.filter_title_adwords
LEFT JOIN locale_text keyAdwCombiFirst ON f.id = keyAdwCombiFirst.filter_key_adwords_combi_first
LEFT JOIN locale_text titleAdwCombiFirst ON f.id = titleAdwCombiFirst.filter_title_adwords_combi_first
LEFT JOIN locale_text keyAdwCombiOther ON f.id = keyAdwCombiOther.filter_key_adwords_combi_other
LEFT JOIN locale_text titleAdwCombiOther ON f.id = titleAdwCombiOther.filter_title_adwords_combi_other
WHERE par.is_enable = 1 AND par.count > 3
AND (
f.group_id IN (402,400,421,395,394,413,422,396) OR
f.id IN (10114,10677,10162,10757,10170,10169,10526,10613,10617,10512,10411)
)
AND (f.id NOT IN (10507,10845,10510,10509) )
";
$sql = preg_replace('/[\s\n\r]+/', ' ', $sql);
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$rows = [];
foreach ($items as $item) {
$fId = $item['id'];
$url = [];
$nameSingle = [];
$nameMany = [];
$groupName = [];
$keyAdwords = $titleAdwords = $keyAdwCombiFirst = $titleAdwCombiFirst = $keyAdwCombiOther = $titleAdwCombiOther = [];
foreach ($locales as $lc) {
$lcCode = $lc['code'];
$url[$lcCode] = $item["url.$lcCode"];
$nameSingle[$lcCode] = $item["nameSingle.$lcCode"];
$nameMany[$lcCode] = $item["nameMany.$lcCode"];
$groupName[$lcCode] = $item["groupName.$lcCode"];
$keyAdwords[$lcCode] = trim($item["keyAdwords.$lcCode"]);
$titleAdwords[$lcCode] = trim($item["titleAdwords.$lcCode"]);
$keyAdwCombiFirst[$lcCode] = trim($item["keyAdwCombiFirst.$lcCode"]);
$titleAdwCombiFirst[$lcCode] = trim($item["titleAdwCombiFirst.$lcCode"]);
$keyAdwCombiOther[$lcCode] = trim($item["keyAdwCombiOther.$lcCode"]);
$titleAdwCombiOther[$lcCode] = trim($item["titleAdwCombiOther.$lcCode"]);
}
//заменяем первый заговоловок на поле Заголовок из формы рекламы фильтра
$titleAdwCombiFirst = $titleAdwords;
$rows[$fId] = [
'id' => $fId,
'groupId' => $item['groupId'],
'groupAltName' => $item['groupAltName'],
'name.single.ru' => $item['name.single.ru'],
'oldCommand' => $item['oldCommand'],
'oldId' => $item['oldId'],
'url' => $url,
'nameSingle' => $nameSingle,
'nameMany' => $nameMany,
'groupName' => $groupName,
'adwords' => [
'keysOne' => $keyAdwords,
'titleOne' => $titleAdwords,
'keysCombiFirst' => $keyAdwCombiFirst,
'titleCombiFirst' => $titleAdwCombiFirst,
'keysCombiOther' => $keyAdwCombiOther,
'titleCombiOther' => $titleAdwCombiOther,
],
];
}
return $rows;
}
private function buildSQLSelectForFilterResponseDTO(string $lc): string
{
$lcs = LocaleHelper::getListAvailable();
$lcs = array_column($lcs, 'code');
$urlSelect = [];
foreach ($lcs as $lc_) {
$urlSelect[] = "url.$lc_ AS `slug.$lc_`";
}
$urlSelect = implode(', ', $urlSelect);
return "SELECT
f.id,
f.rank AS `rank`,
f.alt_name AS `altName`,
f.old_command AS `sphinxName`,
f.old_id AS `sphinxId`,
htmlshow.$lc AS `isHtmlShow`,
fp.name_menu_$lc AS `nameMenu`,
fp.name_many_$lc AS `nameMany`,
fp.name_single_$lc AS `nameSingle`,
fp.html_$lc AS `html`,
fp.description_$lc AS `description`,
metadesc.$lc AS `metaDescriptionName`,
par.count AS `count`,
par.code AS `code`,
par.is_enable AS `isEnable`,
gr.id AS `groupId`,
gr.alt_name AS `groupAltName`,
gpname.$lc AS `groupName`,
url.$lc AS `slug`, $urlSelect,
b.id AS `brandId`,
b.status AS `brandStatus`,
b.stated_at AS `brandStatedAt`,
b.type AS `brandType`,
b.name AS `brandName`,
f.logo AS `brandLogo`,
f.logo_url AS `brandLogoUrl`,
b.sound AS `brandSound`,
b.video AS `brandVideo`,
cn.id AS `countryId`,
cnfp.name_single_$lc AS `countryName`,
cnurl.$lc AS `countrySlug`,
cnpar.code AS `countryCode`
FROM
filters f
LEFT JOIN filter_pages fp ON fp.id = f.page_id
LEFT JOIN filter_params par ON par.id = f.param_id
LEFT JOIN filter_groups gr ON gr.id = f.group_id
LEFT JOIN locale_text gpname ON gpname.filter_group_name = gr.id
LEFT JOIN locale_text metadesc ON metadesc.filter_name_for_meta_descr_id = f.id
LEFT JOIN locale_url url ON url.filter_id = f.id
LEFT JOIN locale_bool htmlshow ON htmlshow.filter_html_show_id = f.id
LEFT JOIN factory b ON b.id = f.brand
LEFT JOIN filters cn ON cn.id = f.country_id
LEFT JOIN filter_pages cnfp ON cnfp.id = cn.page_id
LEFT JOIN locale_url cnurl ON cnurl.filter_id = cn.id
LEFT JOIN filter_params cnpar ON cnpar.id = cn.param_id
";
}
/**
* $this->buildFilterResponseDTO($item);
* @param array $data
* @return FilterResponseDTO|null
*/
private function buildFilterResponseDTO(array $data): ?FilterResponseDTO
{
if (!$data['slug']) {
return null;
}
$lcs = LocaleHelper::getListAvailable();
$lcs = array_column($lcs, 'code');
$slugs = [];
foreach ($lcs as $lc_) {
$slugs[$lc_] = $data["slug.$lc_"];
}
$country = !$data['countryId']
? null
: new FilterCountryResponseDTO(
(int) $data['countryId'],
$data['countryName'],
$data['countrySlug'],
$data['countryCode'],
);
$brand = !$data['brandId']
? null
: new BrandResponseDTO(
(int) $data['brandId'],
(int) $data['brandStatus'],
$data['brandName'],
$data['slug'],
$data['brandLogo'],
$data['brandLogoUrl'],
(int) $data['brandType'],
$data['brandStatedAt'],
$data['brandSound'],
$data['brandVideo'] ? json_decode($data['brandVideo']) : null,
$data['description'],
$country,
);
return new FilterResponseDTO(
(int) $data['id'],
$data['altName'],
(int) $data['sphinxId'],
$data['sphinxName'],
$data['nameMenu'],
$data['nameMany'],
$data['nameSingle'],
(bool) $data['isHtmlShow'],
$data['metaDescriptionName'],
$data['html'],
$data['count'],
$data['code'],
(bool) $data['isEnable'],
(int) $data['groupId'],
$data['groupName'],
$data['groupAltName'],
$data['slug'],
$slugs,
$data['description'],
$brand
);
}
/**
* @param string $sql
* @param string $locale
* @return FilterResponseDTO[]
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
private function getKeysBySql(string $sql, string $locale): array
{
$memcache = $this->cacheService->getMemcache();
$memcacheKey = md5($sql) . $locale;
$rows = $memcache->get($memcacheKey);
if ($rows) {
return $rows;
}
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql);
$ids = array_column($items, 'id');
$rows = $this->getSortedByIds($ids, $locale);
$memcache->set($memcacheKey, $rows);
return $rows;
}
/**
* Получает фильтры и соответствующие группы по идентификатору группы.
*
* @param int $groupId Идентификатор группы.
* @return array Массив с данными фильтров и групп.
*/
public function getFiltersByGroupId(int $groupId): array
{
$urlStrSql = [];
$keyAdwords = $titleAdwords = $keyAdwCombiFirst = $titleAdwCombiFirst = $keyAdwCombiOther = $titleAdwCombiOther = [];
$locales = LocaleHelper::getListAvailable();
foreach ($locales as $lc) {
$urlStrSql[] = "url.{$lc['code']} AS `url.{$lc['code']}`";
$keyAdwords[] = "keyAdw.{$lc['code']} AS `keyAdwords.{$lc['code']}`";
$titleAdwords[] = "titleAdw.{$lc['code']} AS `titleAdwords.{$lc['code']}`";
$keyAdwCombiFirst[] = "keyAdwCombiFirst.{$lc['code']} AS `keyAdwCombiFirst.{$lc['code']}`";
$titleAdwCombiFirst[] = "titleAdwCombiFirst.{$lc['code']} AS `titleAdwCombiFirst.{$lc['code']}`";
$keyAdwCombiOther[] = "keyAdwCombiOther.{$lc['code']} AS `keyAdwCombiOther.{$lc['code']}`";
$titleAdwCombiOther[] = "titleAdwCombiOther.{$lc['code']} AS `titleAdwCombiOther.{$lc['code']}`";
}
$urlStrSql = implode(', ', $urlStrSql);
$keyAdwords = implode(', ', $keyAdwords);
$titleAdwords = implode(', ', $titleAdwords);
$keyAdwCombiFirst = implode(', ', $keyAdwCombiFirst);
$titleAdwCombiFirst = implode(', ', $titleAdwCombiFirst);
$keyAdwCombiOther = implode(', ', $keyAdwCombiOther);
$titleAdwCombiOther = implode(', ', $titleAdwCombiOther);
$sql = "SELECT
f.id,
f.name AS name,
f.alt_name AS altName,
g.id AS groupId,
p.count AS count,
$urlStrSql,
$keyAdwords,
$titleAdwords,
$keyAdwCombiFirst,
$titleAdwCombiFirst,
$keyAdwCombiOther,
$titleAdwCombiOther
FROM
filters f
LEFT JOIN filter_groups g ON g.id = f.group_id
LEFT JOIN filter_params p ON p.id = f.param_id
LEFT JOIN locale_url url ON url.filter_id = f.id
LEFT JOIN locale_text keyAdw ON keyAdw.filter_key_adwords = f.id
LEFT JOIN locale_text titleAdw ON titleAdw.filter_title_adwords = f.id
LEFT JOIN locale_text keyAdwCombiFirst ON keyAdwCombiFirst.filter_key_adwords_combi_first = f.id
LEFT JOIN locale_text titleAdwCombiFirst ON titleAdwCombiFirst.filter_title_adwords_combi_first = f.id
LEFT JOIN locale_text keyAdwCombiOther ON keyAdwCombiOther.filter_key_adwords_combi_other = f.id
LEFT JOIN locale_text titleAdwCombiOther ON titleAdwCombiOther.filter_title_adwords_combi_other = f.id
WHERE
g.id = :groupId
ORDER BY
p.count DESC
";
$items = $this->getEntityManager()->getConnection()->fetchAllAssociative($sql, [
'groupId' => $groupId
]);
return $items;
}
}