<?php
namespace WebBundle\Controller;
use Doctrine\DBAL\DBALException;
use Exception;
use FlexApp\Constant\TimeConstant;
use FlexApp\Service\CacheService;
use FlexApp\Service\RedisCachePool;
use Import1CBundle\Helper\v3\BiConst;
use Memcache;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use WebBundle\Entity\Article;
use WebBundle\Entity\Collection;
use WebBundle\Entity\FilterEntity;
use WebBundle\Helper\App;
use WebBundle\Helper\ArrHelper;
use WebBundle\Helper\ConversionHelper;
use WebBundle\Helper\LocaleHelper;
use WebBundle\Helper\RequestHelper;
use WebBundle\Helper\StrHelper;
use WebBundle\Helper\SynchronizeFiltersHelper;
use WebBundle\Repository\ArticleRepository;
use WebBundle\Repository\CollectionRepository;
use WebBundle\Repository\FilterHistorySearchRepository;
use WebBundle\Repository\FilterRepository;
use WebBundle\Repository\UserRepository;
use WebBundle\Service\FiltersService;
class FiltersController extends ExtendedController
{
/** @required */
public CollectionRepository $collectionRepository;
/** @required */
public FilterRepository $filterRepository;
/** @required */
public FilterHistorySearchRepository $filterHistorySearchRepository;
/** @required */
public ArticleRepository $articleRepository;
/** @required */
public CacheService $cacheService;
public Memcache $memcached;
/**
* FilterController constructor.
* @param CacheService $cacheService
* @throws Exception
*/
public function __construct(CacheService $cacheService)
{
parent::__construct();
$this->memcached = $cacheService->getMemcache();
}
/**
* @return null|JsonResponse
* @throws Exception
*/
public function ajaxAdvancedSearchAction()
{
$locale = App::getCurLocale();
$func = RequestHelper::get('func');
$respLink = '';
$respCount = 0;
$calculate = [];
$respDisabledFilters = [];
$dataCollection = [];
$isInteriors = false;
if ($func == 'getLinkHistory') {
$hash = RequestHelper::get('hash');
if (!$hash) {
return $this->error('Not found hash.', 404, true);
}
$row = $this->filterHistorySearchRepository->getRowByHash($hash);
if (!$row) {
$row_ = $this->filterHistorySearchRepository->getRowByHash($hash, false);
if ($row_) {
return $this->error('Access denied.', 403, true);
}
return $this->error('Not found history.', 404, true);
}
$fids = $row['filterIds'];
$filterService = App::getContainer()->get('app.service.filters');
if ($row['collId']) {
$filterService->loadByIds($fids, $locale);
$coll = $this->collectionRepository->getCollectionsForMenuFilters(['id' => $row['collId']]);
$coll = count($coll) == 1 ? $coll[0] : null;
/** @var Collection $coll */
if (!$coll) {
return $this->error('Not found collection.', 404, true);
}
$brand = $coll->getFactory();
/** @var FilterEntity $brand */
if (!$brand) {
return $this->error('Not found brand.', 404, true);
}
$brandUrl = $brand->getFilter()->getUrl()->{'get' . ucfirst($locale)}();
$collUrl = $coll->getUrl();
$attrUrl = [
'factoryUrl' => $brandUrl,
'collectionUrl' => $collUrl,
];
// прикручиваем строки фильтрации к URL коллекции
if ($fKey = $filterService->getWord()) {
$fKey = str_replace($attrUrl['factoryUrl'], '', $fKey);
$fKey = trim($fKey, '&');
if ($fKey) {
$attrUrl['type'] = 'f';
$attrUrl['elementId'] = $fKey;
}
}
$respLink = $this->generateUrl('app_collection', $attrUrl);
} else {
if ($row['brandId']) {
$fids[] = $row['brandId'];
}
$filterService->loadByIds($fids, $locale);
$respLink = $filterService->getUrl();
}
return $this->ok(['link' => $respLink, 'hash' => $hash], true);
}
if ($func == 'saveHistory') {
$hasLiteMenu = RequestHelper::get('lmenu') == 1;
$rows = RequestHelper::get('data');
if (!$rows) {
return $this->error('Not found values data.', 404, true);
}
$rows = json_decode($rows, true);
$collId = null;
$brandId = null;
if (!empty($rows['collection'][0][1])) {
$collId = $rows['collection'][0][1];
unset($rows['collection']);
}
if (!empty($rows['brand'][0][1])) {
$brandId = $rows['brand'][0][1];
unset($rows['brand']);
}
$fids = [];
if ($hasLiteMenu) {
// логика под короткое меню
/** @var $repoFilter FilterRepository */
$repoFilter = App::getRepository('WebBundle:FilterEntity');
if (!empty($rows['factory'][0])) {
$brandId = $repoFilter->getFilterIdByOldId((int)$rows['factory'][0], 'factory');
unset($rows['factory']);
}
foreach ($rows as $oldCommand => $oldIds) {
$oldIds = array_filter($oldIds);
if ($oldIds) {
$fids_ = $repoFilter->getFilterIdsByOldIds($oldIds, $oldCommand);
if ($fids_) {
$fids = array_merge($fids, $fids_);
}
}
}
} else {
foreach ($rows as $els) {
foreach ($els as $el) {
$fids[] = $el[1];
}
}
}
$fids = array_unique($fids);
$this->filterHistorySearchRepository->setHistory($collId, $brandId, $fids);
$data = [
'state' => 'saved',
'list' => $this->getListHistory(),
];
return $this->ok($data, true);
}
if ($func == 'gethistory') {
$data = [
'state' => 'get_history',
'list' => $this->getListHistory(),
];
return $this->ok($data, true);
}
if ($func == 'delLinkHistory') {
$hash = RequestHelper::get('hash');
if (!$hash) {
return $this->error('Not found hash.', 404, true);
}
$this->filterHistorySearchRepository->delHistory($hash);
$data = [
'state' => 'deleted',
'list' => $this->getListHistory(),
];
return $this->ok($data, true);
}
if ($func == 'getLink') {
$data = RequestHelper::get('data', []);
// обработка запроса коллекций
if (!empty($data['collection'])) {
$collId = array_shift($data['collection']);
$collId = !empty($collId['val']) ? $collId['val'] : null;
if (!$collId) {
return $this->error('ID коллекции не получен');
}
$coll = $this->collectionRepository->getCollectionsForMenuFilters(['id' => $collId]);
$coll = count($coll) == 1 ? $coll[0] : null;
/** @var Collection $coll */
if (!$coll) {
return $this->error('Коллекция не найдена');
}
$factoryUrl = null;
if (!empty($data['brand'])) {
$brandId = ArrHelper::get($data, 'brand.brand.val');
if (!$brandId) {
return $this->error('ID фабрики не получен');
}
$data[] = $data['brand'];
unset($data['brand']);
unset($data['collection']);
/** @var FilterRepository $fRepo */
$fRepo = App::getRepository('WebBundle:FilterEntity');
$brand = $fRepo->getBrand(['id' => $brandId]);
$brand = count($brand) == 1 ? $brand[0] : null;
/** @var FilterEntity $brand */
if (!$brand) {
return $this->error('Фабрика не найдена');
}
$factoryUrl = $brand->getUrl()->{'get' . ucfirst($locale)}();
}
if (!$factoryUrl) {
$factoryUrl = $coll->getFactory()->getFilter()->getUrl()->{'get' . ucfirst($locale)}();
}
$dataCollection = [
'c_id' => [$coll->getId()],
'attrUrl' => [
'factoryUrl' => $factoryUrl,
'collectionUrl' => $coll->getUrl(),
],
];
}
/**
* обработка остальных запросов
*/
$ids = [];
foreach ($data as $items) {
foreach ($items as $item) {
$ids[] = $item['val'];
}
}
$lc = App::getCurLocale();
$cc = App::getCurCountry();
$lcFull = $lc == $cc ? $lc : "{$lc}_$cc";
$memcachedKey = 'collection_filter_factory_AdvancedSearch_null_' . $lcFull;
$resCache = $this->memcached->get($memcachedKey);
if ($resCache and count($ids) < 1 and !$dataCollection) {
$resCache = json_decode($resCache, true);
$respLink = $resCache['respLink'];
$respCount = $resCache['respCount'];
$respDisabledFilters = $resCache['filtered'];
} else {
$filterService = App::getContainer()->get('app.service.filters');
$filterService->loadByIds($ids, $locale);
if ($dataCollection) {
$attrUrl = $dataCollection['attrUrl'];
// прикручиваем строки фильтрации к URL коллекции
$fKey = $filterService->getWord();
if ($fKey) {
$fKey = str_replace($attrUrl['factoryUrl'], '', $fKey);
$fKey = trim($fKey, '&');
$fKey = str_replace('&&', '&', $fKey);
if ($fKey) {
$attrUrl['type'] = 'f';
$attrUrl['elementId'] = $fKey;
}
}
$respLink = $this->generateUrl('app_collection', $attrUrl);
} else {
$respLink = $filterService->getUrl();
}
$data = [
'searchFilter' => [],
'searchSort' => 1,
'searchPeriod' => null,
'locale' => $locale,
];
$filters = $filterService->getCurFilters();
foreach ($filters as $filter) {
if ($filter->isDimension()) {
$searchFilterVal = $filterService->getDimensions()[$filter->getAltName()];
} elseif ($filter->isBM()) {
$searchFilterVal = $filterService->getBMs()[$filter->getAltName()];
} else {
$searchFilterVal = $filter->getSphinxId();
}
$data['searchFilter'][$filter->getSphinxName()][] = $searchFilterVal;
}
if ($dataCollection) {
$data['searchFilter']['c_id'] = $dataCollection['c_id'];
$data['searchFilter']['inside'] = true;
}
$data['total_found'] = 1;
$searchResult = App::searchSphinx($data, 0, false, false, !empty($data['calculate']));
//если запросили подсчет
if (!empty($data['calculate'])) {
$calculate = $searchResult['calculate'];
$aRes = $searchResult['collections'];
} else {
$aRes = $searchResult;
}
if ($dataCollection) {
$aRes = !empty($aRes[0]['articles'])
? array_values(array_unique(array_column($aRes[0]['articles'], 'a_id')))
: [];
if (!$aRes) {
$aRes = !empty($searchTrue[0]['interiors'])
? array_values(array_unique(array_column($searchTrue[0]['interiors'], 'i_id')))
: [];
$isInteriors = true;
}
}
$respCount = isset($searchResult['total_found']) ? $searchResult['total_found'] : count($aRes);
// если есть выбранная коллекция, то показываем в количестве ее одну или ничего
if ($dataCollection) {
$respCount = $respCount ? 1 : 0;
}
// проверяем результат сочетаний с другими фильтрами
if (count($ids) > 0) {
//todo вынести в отдельную команду так как кешируеться на всех зеркалах а просчитаться может на одном
// проверка на количество коллекций в поиске с сохранением в поле фильтра
// if (count($filters) == 1) {
// $filter = $filters[0];
// $filterResCount = 0;
// if ($filter instanceof FilterEntity) {
// $filterResCount = $filter->getParam()->getCount();
// } elseif ($filter instanceof FilterResponseDTO) {
// $filterResCount = $filter->getCount();
// }
// if ($filter && $respCount != $filterResCount) {
// SynchronizeFiltersHelper::runSynchCountFilters($filter->getId());
// }
// }
if ($checkIds = RequestHelper::get('checkIds', [])) {
/** @var FilterRepository $fRepo */
$fRepo = App::getRepository('WebBundle:FilterEntity');
$filtersCheck = $fRepo->getByIds($checkIds);
foreach ($filtersCheck as $filter) {
if (!in_array($filter->getId(), $ids)) {
$dataSS = $data;
$dataSS['searchFilter'][$filter->getOldCommand()][] = $filter->getOldId();
$aRes = App::searchSphinx($dataSS, 3);
if (count($aRes) < 1) {
$respDisabledFilters['ids'][] = $filter->getId();
}
}
}
}
} else {
// если массив запросов пустой, то пишем данные в кеш и оттуда будем выдавать //Todo а на всякий случай загоним не тут а при открытии фильтра
$data = [
'respLink' => $respLink,
'respCount' => $respCount,
'filtered' => $respDisabledFilters,
];
$data = json_encode($data);
// кешируем на продакшене
if (App::isGeneral()) {
$this->memcached->add($memcachedKey, $data, false, (int)TimeConstant::HOUR * 12);
}
}
}
}
if ($dataCollection) {
if ($isInteriors) {
$countPluralType = 'interior';
} else {
$countPluralType = 'articles';
}
} else {
$countPluralType = 'collection';
}
$btnInfo = $this->translate('left_menu_show');
$response = [
'link' => urldecode($respLink),
'count' => $respCount,
'btnInfo' => $btnInfo,
'filtered' => $respDisabledFilters,
'countPluralType' => $countPluralType,
'calculate' => $calculate,
];
return $this->ok($response, true);
}
/**
* проставляем выбранные фильтры
*/
private function setFilterSelected(array $selected, string $alt, array $filters): array
{
$selectedReact = [];
foreach ($filters as $i => $item) {
if ($alt == 'collection') {
foreach ($selected['collections'] as $k => $v) {
if (StrHelper::toLower($item['url']) == StrHelper::toLower($k)) {
if (StrHelper::toLower($item['brand']['url']) == StrHelper::toLower($selected['brand'])) {
$filters[$i]['selected'][] = $item['id'];
$selectedReactItem = [];
$selectedReactItem[] = 'collection';
$selectedReactItem[] = $item['id'];
$selectedReact[] = $selectedReactItem;
}
}
}
} else {
foreach ($selected['filters'] as $k => $v) {
if (!empty($item['groupList'])) {
$response = $this->setFilterSelected($selected, $alt, $item['groupList']);
$filters[$i]['groupList'] = $response['items'];
$selectedSubFiltersReact = $response['selectedReact'];
}
if (!empty($item['sub'])) {
$response = $this->setFilterSelected($selected, $alt, $item['sub']);
$filters[$i]['sub'] = $response['items'];
$selectedSubFiltersReact = $response['selectedReact'];
}
if ($alt == 'dimension') {
foreach ($item as $ii => $d) {
if (strripos($k, $d['key']) !== false) {
$val = trim(str_replace($d['key'], '', $k), '-');
$filters[$i][$ii]['selected'][] = $val;
$selectedReactItem = [];
$selectedReactItem[] = $d['altName'];
$selectedReactItem[] = "{$d['id']}::{$val}";
$selectedReact[] = $selectedReactItem;
}
}
} elseif ($alt == 'bm') {
if (preg_match("/.*-{$item['id']}$/", $k)) {
$filters[$i]['selected'][] = $item['id'];
$selectedReactItem = [];
$selectedReactItem[] = 'bm';
$selectedReactItem[] = "{$item['fid']}::{$item['id']}";
$selectedReact[] = $selectedReactItem;
}
} elseif ($item['key'] == $k) {
$filters[$i]['selected'][] = $item['id'];
$selectedReactItem = [];
if ($alt == 'brand') {
$selectedReactItem[] = 'brand';
} else {
$selectedReactItem[] = $item['name'];
}
$selectedReactItem[] = $item['id'];
$selectedReact[] = $selectedReactItem;
}
}
// добавляем выбранные вложенные фильтры
if (!empty($selectedSubFiltersReact) && (!empty($item['sub']) || !empty($item['groupList']))) {
$selectedReact = array_merge($selectedReact, $selectedSubFiltersReact);
}
}
}
return [
'items' => $filters,
'selectedReact' => $selectedReact,
];
}
/**
* карта фильтров
* @param $filters
* @return array|string
* @throws Exception
*/
private function getFiltersMap($filters)
{
$lc = App::getCurLocale();
$cur = LocaleHelper::getCurrency();
$msr = LocaleHelper::getUserMeasure();
$memcacheKey = "collection_filter_factory_search_page_map_{$lc}.{$cur}.{$msr}";
$map = $this->memcached->get($memcacheKey);
if (!$map) {
$groups = [];
$filtersTmp = $this->filterRepository->getArrListForFilterMenuNew($lc);
foreach ($filtersTmp as $filter) {
$groupAltName = $filter['group']['altName'];
$groups[$groupAltName] = $filter['group'];
}
$groups['collection'] = [
'name' => App::getTranslator()->trans('left_menu_collections'),
'altName' => 'collections',
];
// для категории цены вывел вылюту
$priceName = $groups['price']['name'];
$priceName = $priceName . ', ' . html_entity_decode($cur) . '/' . $msr . '²';
$map = [
'coll_1' => [
'brand' => $groups['brand']['name'],
'collection' => $groups['collection']['name'],
'bm' => $groups['bm']['name'],
'effect' => $groups['effect']['name'],
'style' => $groups['style']['name'],
'price' => $priceName,
],
'coll_2' => [
'color' => $groups['color']['name'],
'using' => $groups['using']['name'],
'material' => $groups['material']['name'],
],
'coll_3' => [
'samples' => !empty($groups['samples']) && $groups['samples']['name'],
'type' => $groups['type']['name'],
'surface' => $groups['surface']['name'],
'apply' => $groups['apply']['name'],
],
'coll_4' => [
'shape' => $groups['shape']['name'],
'motiv' => $groups['motiv']['name'],
'country' => $groups['country']['name'],
],
'coll_5' => [
'dimension' => $groups['dimension']['name'],
'granite' => $groups['granite']['name'],
'edge_type' => $groups['edge_type']['name'],
'other' => $groups['other']['name'],
'rewards' => $groups['rewards']['name'],
'reviews' => $groups['reviews']['name'],
],
];
// кешируем на продакшене
if (App::isGeneral()) {
$this->memcached->add($memcacheKey, $map, MEMCACHE_COMPRESSED, 600);
}
}
// убираем из карты поля, под которые нет фильтров
foreach ($map as $col => $row) {
foreach ($row as $alt => $item) {
if (empty($filters[$alt])) {
unset($map[$col][$alt]);
}
}
}
return $map;
}
/**
* Формирование страницы расширенных фильтров
* @return array
* @throws Exception
*/
private function getAdvancedSearchPageData(): array
{
$locale = App::getCurLocale();
$curCountry = LocaleHelper::getCurCountry();
// формируем выбранные фильтры из строки запроса
$selected = [
'filters' => [],
'collections' => [],
'brand' => null,
];
$uri = urldecode(RequestHelper::syRequest()->getRequestUri());
$uri = parse_url($uri, PHP_URL_QUERY);
$uri = str_replace('c=/', '', $uri);
$uri = trim($uri, '/');
$uri = StrHelper::toLower($uri);
$uri = explode('/', $uri);
array_shift($uri);
if (count($uri) > 1) {
if ($uri[0] == 'catalogue') {
$uri = $uri[1];
foreach (explode('&', $uri) as $item) {
$selected['filters'][$item] = $item;
}
}
if ($uri[0] == 'tile') {
$selected['filters'][$uri[1]] = $uri[1];
$selected['brand'] = $uri[1];
$selected['collections'][$uri[2]] = $uri[2];
// получение фильтров для коллекций
if ($uriFilters = ArrHelper::get($uri, 4)) {
foreach (explode('&', $uriFilters) as $item) {
$selected['filters'][$item] = $item;
}
}
}
}
$filterService = new FiltersService();
$filtersList = $filterService->getFiltersList();
// удаляем БМом, если роль не позволяет
if (!$this->isGranted('ROLE_BM')) {
unset($filtersList['bm']);
}
// формируем выбранные фильтры из строки
$selectedFilters = [];
$selectedFiltersQty = 0;
foreach ($filtersList as $alt => $items) {
$filterSelectedResponse = $this->setFilterSelected($selected, $alt, $items);
$filtersList[$alt] = $filterSelectedResponse['items'];
$selectedFilters[$alt] = $filterSelectedResponse['selectedReact'];
$selectedFiltersQty += count($filterSelectedResponse['selectedReact']);
}
// формируем фильтры цен
foreach ($filtersList['price'] as $i => $item) {
if ($curCountry != $locale) {
$name = LocaleHelper::getNamePriceFilter($item['name'], $locale, $curCountry);
$filtersList['price'][$i]['name'] = $name;
}
}
$filtersMap = $this->getFiltersMap($filtersList);
$isNullSelected = !(count($selected['collections']) > 0 or count($selected['filters']) > 0);
$resLink = null;
if ($isNullSelected) {
$resLink = $this->generateUrl('app_catalog');
}
$lc = App::getCurLocale();
$cc = App::getCurCountry();
$lcFull = $lc == $cc ? $lc : "{$lc}_$cc";
$memcachedKey = 'collection_filter_factory_AdvancedSearch_null_' . $lcFull;
$resCache = $this->memcached->get($memcachedKey);
if (!$resCache) {
$cntCollAll = App::getContainer()->get('app.service.collection')->countNotFilteredCollection();
$data = [
'respLink' => $resLink,
'respCount' => $cntCollAll,
'filtered' => [],
];
$data = json_encode($data);
// кешируем на продакшене
if (App::isGeneral()) {
$this->memcached->add($memcachedKey, $data, false, (int)TimeConstant::HOUR * 12);
}
} else {
$resCache = json_decode($resCache, true);
$cntCollAll = $resCache['respCount'];
}
//todo дублируется выдача при выборе группы
foreach ($filtersList as $groupKey => &$group) {
foreach ($group as $itemKey => &$item) {
if (!empty($item['selected']) && isset($item['sub']) && !empty($item['sub'])) {
$selectedFiltersQty--; // :) а вот так :) иначе фронт ляжет
$item['selected'] = []; //пробовал удалять из выбранных родителя не помогло
//удаляем родителя
$value_to_remove = $item['id']; // Переменная с переданным значением
$selectedFilters[$groupKey] = array_filter(
$selectedFilters[$groupKey],
function ($item_) use ($value_to_remove) {
return $item_[1] != $value_to_remove;
}
);
$selectedFilters[$groupKey] = array_values($selectedFilters[$groupKey]);
foreach ($item['sub'] as $subKey => &$subItem) {
$subItem['selected'] = [$subItem['id']];
$selected['filters'][$subItem['key']] = $subItem['key'];
$selectedFilters[$groupKey][] = [$subItem['name'], $subItem['id']];
$selectedFiltersQty++;
}
}
}
}
return [
'action' => urldecode($this->generateUrl('app_filters_advanced_search_json')),
'map' => $filtersMap,
'filters' => $filtersList,
'selected' => $selected,
'cntCollAll' => $cntCollAll,
'resLink' => $resLink,
'isNullSelected' => $isNullSelected,
'noFloor' => true,
'selectedFilters' => $selectedFilters,
'selectedFiltersQty' => $selectedFiltersQty,
'countPluralType' => 'collection',
];
}
/**
* @param bool $noResponse
* @return array|null|string|JsonResponse
* @throws Exception
*/
public function ajaxListMenuFactoryAction(bool $noResponse = false)
{
//todo скрыть скрытые фабрики
$locale = App::getCurLocale();
$cacheKey = "left_menu_lite_factory_filter_{$locale}_1" . App::getCurCountry();
$factories = App::getMemcache()->get($cacheKey);
$redisCachePool = App::getContainer()->get(RedisCachePool::class)->getPool();
$cc = App::getCurCountry();
$msr = LocaleHelper::getUserMeasure();
$memKeyCalc = 'all_calculate_' . $cc . '_' . $msr; //
$allCalculateItem = $redisCachePool->getItem($memKeyCalc);
if ($allCalculateItem->isHit()) {
$allCalculate = $allCalculateItem->get();
} else {
$allCalculate = false;
}
$issetCollectionFactory = $allCalculate ? array_keys($allCalculate['factory']) : [];
if (!$factories || App::isDev()) {
$translator = $this->get('translator');
/** @var FilterRepository $repoFilter */
$repoFilter = App::getRepository('WebBundle:FilterEntity');
$brands = $repoFilter->getListBrandsForMenu($locale, $translator);
foreach ($brands as $i => $brand) {
if (!empty($issetCollectionFactory) && !in_array($brand['filter_id'], $issetCollectionFactory)) {
unset($brands[$i]);
}
}
$factoryAllCount = count($brands);
if ($factoryAllCount > 0) {
$factories = [
'data' => $brands,
'all' => $factoryAllCount,
'to' => 'brand',
];
App::getMemcache()->set($cacheKey, $factories, false, TimeConstant::DAY);
}
}
if ($noResponse) {
$response = $factories;
} else {
$response = $this->ok($factories, true);
}
return $response;
}
/**
* @param bool $noResponse
* @param null $brands
* @return array|null|string|JsonResponse
* @throws Exception
*/
public function ajaxListMenuCollectionAction($noResponse = false, $brands = null)
{
$collectionId = RequestHelper::get('collectionId', null);
$_locale = App::getCurLocale('full');
$redisCachePool = App::getContainer()->get(RedisCachePool::class)->getPool();
$cc = App::getCurCountry();
$msr = LocaleHelper::getUserMeasure();
$memKeyCalc = 'all_calculate_' . $cc . '_' . $msr; //
$allCalculateItem = $redisCachePool->getItem($memKeyCalc);
if ($allCalculateItem->isHit()) {
$allCalculate = $allCalculateItem->get();
} else {
$allCalculate = false;
}
$issetCollectionFactory = $allCalculate ? array_keys($allCalculate['factory']) : [];
$issetCollection = $allCalculate ? array_keys($allCalculate['c_id']) : [];
$memcacheName = 'left_menu_collection.0.' . $collectionId . $_locale . (App::isRole('ROLE_TEST') ? 1 : 0);
$collections = $this->memcached->get($memcacheName);
if (!$collections || App::isDev()) {
$isStatusWork = $this->collectionRepository->findOneBy([
'status' => BiConst::STATE_DISCONTINUED,
'id' => $collectionId,
]);
$collectionId = ($isStatusWork) ? $collectionId : null;
$param = [
'order' => 'c.name, f.name',
'onlyCF' => true,
'collectionId' => $collectionId,
'leftCollectionCount' => true,
'locale' => App::getCurLocale(),
];
if ($brands) {
foreach ($brands as $brand) {
$param['factoryId'][] = $brand['id'];
}
}
$aColls = $this->collectionRepository->getListForMenu($param);
foreach ($aColls as $i => $coll) {
if (!empty($issetCollectionFactory) && !in_array($coll['id'], $issetCollection)) {
unset($aColls[$i]);
continue;
}
$coll['dataLink'] = $this->generateUrl(
'app_collection',
[
'factoryUrl' => $coll['factory']['slug'],
'collectionUrl' => $coll['slug'],
]
);
$aColls[$i] = $coll;
}
$collectionAllCount = count($aColls);
if ($collectionAllCount > 0) {
$collections = [
'data' => $aColls,
'all' => $collectionAllCount,
'to' => 'collection',
];
// кешируем на продакшене
if (App::isGeneral()) {
$this->memcached->add($memcacheName, $collections, false, (int)TimeConstant::MINUTE * 10);
}
}
}
if ($noResponse) {
$response = $collections;
} else {
$response = $this->ok($collections, true);
}
return $response;
}
/**
* Страница фильтров под реакт
* @return JsonResponse|Response|null
* @throws Exception
*/
public function pageAdvancedSearchReactAction()
{
$data = $this->getAdvancedSearchPageData();
$data['trans'] = [
'countPluralInterior' => App::transPluralStrToArray($this->translate('filter.res.count.interior')),
'countPluralArticles' => App::transPluralStrToArray($this->translate('filter.res.count.articles')),
'countPluralCollection' => App::transPluralStrToArray($this->translate('filter.res.count.collection')),
'searchHistory' => $this->translate('search_history_advancedsearch'),
'leftMenuCriteria' => $this->translate('left_menu_criteria'),
'leftMenuShow' => $this->translate('left_menu_show'),
'leftAdvancedReset' => $this->translate('left_advanced_reset'),
'leftAdvancedSearch' => $this->translate('left_advanced_search'),
'leftMenuSelect' => $this->translate('left_menu_select'),
'leftMenuCollections' => $this->translate('left_menu_collections'),
'searchNoResult' => $this->translate('search_no_result'),
'factoryFirstLi' => $this->translate('factory_first_li'),
'factoryFirstLiLink' => $this->translate('factory_first_li_link'),
'factoryFirstLiHelp' => $this->translate('factory_first_li_help'),
'leftMenuFactories' => $this->translate('left_menu_factories'),
'filterHideFilters' => $this->translate('filter_hide_filters'),
'filterShowAllFilters' => $this->translate('filter_show_all_filters'),
'leftMenuAll' => $this->translate('left_menu_all'),
'clear' => $this->translate('clear'),
'filtersTipsWallAndFloor' => $this->translate('filters.tips.wallAndFloor'),
'hintCollGroupTypeBassein' => $this->translate('hint_coll_group_type_bassein'),
'hintCollGroupTypeBorder' => $this->translate('hint_coll_group_type_border'),
'hintCollGroupTypePencil' => $this->translate('hint_coll_group_type_pencil'),
'hintCollGroupTypeRiser' => $this->translate('hint_coll_group_type_riser'),
'hintCollGroupTypeStep' => $this->translate('hint_coll_group_type_step'),
'hintCollGroupTypeTypeCorner' => $this->translate('hint_coll_group_type_type_corner'),
'hintCollGroupTypeCornerProfile' => $this->translate('hint_coll_group_type_corner_profile'),
'hintCollGroupTypeCornerElement' => $this->translate('hint_coll_group_type_corner_element'),
'hintCollGroupTypeBaseboard' => $this->translate('hint_coll_group_type_baseboard'),
'hintCollGroupTypePanel' => $this->translate('hint_coll_group_type_panel'),
'hintCollGroupTypeMosaicImitation' => $this->translate('hint_coll_group_type_mosaic_imitation'),
'hintCollGroupTypeMosaic' => $this->translate('hint_coll_group_type_mosaic'),
'chooseDropdownTooltip' => $this->translate('choose_dropdown_tooltip'),
];
$data['path'] = App::getRouter()->generate('app_request', ['action' => 'get']);
$data['map'] = array_values($data['map']);
foreach ($data['filters'] as $i => $fl) {
if ($i == 'dimension') {
foreach ($fl as $ii => $fll) {
$fl[$ii] = array_values($fll);
}
} else {
$fl = array_values($fl);
}
$data['filters'][$i] = $fl;
}
$data['history']['actionSave'] = App::getRouter()->generate(
'app_filters_advanced_search_json',
['func' => 'saveHistory']
);
$data['history']['actionGet'] = App::getRouter()->generate(
'app_filters_advanced_search_json',
['func' => 'gethistory']
);
$data['history']['list'] = [];//$this->getListHistory(); // TODO Удалить если сделаю через ?func=gethistory или вернуть
return $this->renderReact('@Web/Filters/React/page.html.twig', [
'meta' => [
'title' => $this->translate('left_advanced_search') . ' · ' . App::getParameter('site_name'),
'description' => '',
'keywords' => '',
],
'initialState' => ['filters' => $data],
]);
}
/**
* @return array
* @throws DBALException
* @throws Exception
*/
private function getListHistory()
{
$items = [];
$rows = $this->filterHistorySearchRepository->getHistoryForCurUser();
foreach ($rows as $row) {
$names = [];
if ($row['collId']) {
if ($nameColl = $this->collectionRepository->getNameForFilterHistorySearch($row['collId'])) {
$names[] = $nameColl;
}
}
if ($row['brandId']) {
$row['filterIds'][] = $row['brandId'];
}
// новый объект для фронта, из которого можно собрать значения группы - фильтр
$groupedFilter = [];
if ($row['filterIds']) {
$idsParam = [];
$fids = [];
$namesF = [];
foreach ($row['filterIds'] as $fid) {
$ids = explode('::', $fid);
if (!$ids[0]) {
continue;
}
$fids[] = $ids[0];
// обработка через :: для запросов по размерам, т.к. ID там идет вида 56564::0.5
// где первое - ID, а второе параметр
if (count($ids) > 1) {
$idsParam[$ids[0]] = $ids[1];
}
}
$filters = $this->filterRepository->getForFilterNameHistorySearch($fids);
$dimensions = [];
if ($filters) {
foreach ($filters as $fl) {
$name = $fl['name'];
$groupAltName = $fl['groupAltName'];
$groupLeftMenu = $fl['groupLeftMenu'];
// если группа размеров содержит более одного элемента, формируем дополнительный массив $dimensions
if ($groupAltName == 'dimension') {
if (!empty($idsParam[$fl['id']])) {
$size = $idsParam[$fl['id']];
$sizeEd = App::trans('left_menu_' . $fl['code']);
$type = str_replace('2', '', $fl['altName']);
$ind = $type == $fl['altName'] ? 1 : 2;
$dim = array_merge($fl, [
'size' => $size,
'sizeEd' => $sizeEd,
'type' => $type,
]);
$dimensions[$type][$ind] = $dim;
$name = null;
}
// логика для БМов
} elseif ($groupAltName == 'bm') {
if (!empty($idsParam[$fl['id']])) {
$bmId = $idsParam[$fl['id']];
/** @var UserRepository $repoUser */
$repoUser = App::getRepository('WebBundle:User');
$name = $repoUser->getUserEasyNameById($bmId);
$name = "{$fl['name']}: {$name}";
}
} else {
if (!isset($groupedFilter[$groupAltName])) {
$groupedFilter[$groupAltName] = [
'name' => App::trans($groupLeftMenu ?: $groupAltName),
'values' => [],
];
}
$groupedFilter[$groupAltName]['values'][] = $name;
}
if ($name) {
$namesF[] = $name;
}
}
}
if ($dimensions) {
$groupedFilter['dimension'] = [
'name' => App::trans('left_menu_dimensions'),
'values' => [],
];
foreach ($dimensions as $type => $dims) {
// для создания вывода фильтров единой строкой, а не по отдельности
if (count($dims) > 1) {
$d1 = $dims[1];
$d2 = $dims[2];
$first = explode(' ', $d1['name']);
$first = array_shift($first);
$name = App::trans(
'settings_size_from_to',
null,
['%size%' => $d1['size'], '%size2%' => $d2['size']]
);
$name = "{$first} {$name} {$d1['sizeEd']}";
} else {
$d = array_shift($dims);
$name = "{$d['name']} {$d['size']} {$d['sizeEd']}";
}
$groupedFilter['dimension']['values'][$type] = $name;
$namesF[] = $name;
}
}
asort($namesF);
$names = array_merge($names, $namesF);
}
$name = implode(', ', $names);
$items[] = [
'name' => $name,
'groupAltName' => $groupedFilter,
'getElLink' => App::getRouter()->generate(
'app_filters_advanced_search_json',
['func' => 'getLinkHistory', 'hash' => $row['hash']]
),
'delEl' => App::getRouter()->generate(
'app_filters_advanced_search_json',
['func' => 'delLinkHistory', 'hash' => $row['hash']]
),
];
}
return $items;
}
/**
* Меню для реакта
* @return JsonResponse|Response|null
* @throws Exception
*/
public function ajaxListMenuLite()
{
$oLeftService = App::getContainer()->get('app.service.leftmenu');
$output = $oLeftService->getDataMenuLite();
return $this->ok($output, true);
}
}