<?php
namespace WebBundle\Service;
use Doctrine\ORM\EntityManager;
use Exception;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Translation\Translator;
use WebBundle\Entity\ListMaterial;
use WebBundle\Entity\ListMeasure;
use WebBundle\Helper\App;
use WebBundle\Helper\CurrencyRateHelper;
use WebBundle\Helper\HideFactoryCountriesHelper;
use WebBundle\Helper\LocaleHelper;
use WebBundle\Helper\StrHelper;
use WebBundle\Repository\FilterRepository;
use WebBundle\Repository\ListMaterialRepository;
use WebBundle\Repository\ListMeasureRepository;
class SphinxSearcherService
{
private array $materials = [];
/** @required */
public ListMeasureRepository $listMeasureRepository;
/** @required */
public ListMaterialRepository $listMaterialRepository;
/** @var EntityManager */
private $em;
/** @var sphinxQLService $sphinxQL */
private $sphinxQL;
/** @var Translator $translator */
private $translator;
protected array $articlesId = [];
protected array $subFilters = [];
private FilterRepository $filterRepo;
/**
* @param ContainerInterface $container
* @param FilterRepository $filterRepository
* @throws Exception
*/
public function __construct(ContainerInterface $container, FilterRepository $filterRepository)
{
$this->filterRepo = $filterRepository;
$this->em = $container->get('doctrine');
$this->sphinxQL = $container->get('sphinx_ql');
$this->translator = $container->get('translator');
}
/**
* @param ?array $data - данные для выборки
* @param ?int $limit - если 0 то вывести все
* @param ?bool $withSchema - если true, то в поиске подбирать артикулы со схематичным изображением
* @param ?bool $full
* @param ?bool $getCount
* @return array
* @throws Exception
*/
public function searchSphinx(
?array $data = [],
?int $limit = 0,
?bool $withSchema = false,
?bool $full = false,
?bool $getCount = false
): array {
$this->sphinxQL->clear();
ini_set('memory_limit', '2048M');
$dataReview = [];
$fields = [
'c_id',
'coll',
'border_grey',
'a_id',
'type_filter',
'c_name',
'c_status',
'c_header',
'c_release_year',
'c_url',
'c_awards',
'c_exhibition',
'c_accessible',
'f_name',
'f_id',
'f_url',
'rating_month',
'publish_date',
'country',
'country_code',
'author',
'a_name',
// Чистим от не нужных полей
'size_x',
'size_y',
'tolsch',
//для вывода возможных толщин
'sliding',
'a_style',
'measure',
'type',
'file',
'fs_x',
'fs_y',
'is_main',
'c_express_sample',
'price_sort',
//'square',
'c_material',
'process',
'express_sample',
'factory',
'u_id',
'thin_granite',
'attr_data',
//.i as interior || .i as i не получаем лишние данные если не будет facet еще быстрее получаем только a_id и дальше к бд (тест скорости провести)
'size_big',
'glazed_granite',
'thick_granite',
'publish_period',
'dyed_in_mass',
'color_body',
'c_designer_ids',
'monochrome',
'prc_count',
'prc_vote',
'reviews',
'a_texture',
'a_motive',
'surface',
'shape',
'color',
'material',
'a_stone_texture',
'a_motiv',
'typecoll',
'a_head',
'sid',
'styleid',
'styleida',
'sort',
'is_head',
'apply_id',
'c_apply',
'using',
'pr_status',
'edge_type',
'off_shade',
];
if (isset($data['searchFilter']['getTopMonth'])) {
$fields[] = 'c_pop30';
$fields[] = 'c_last_pop30';
} elseif (isset($data['searchFilter']['getTopWeek'])) {
$fields[] = 'c_pop7';
$fields[] = 'c_last_pop7';
}
$buildingMixtureOff = false;
// тут костыль для скольжения https://te.remote.team/#/discus/7AF53097-7533-5034-0808-93CF8BDB1E75/
// Не бывает матовой поверхности с коэффициентом противоскольжения (если и бывает, то это просто ошибка в свойствах артикула)
// todo излишнее так как sliding= '999.a.sliding
if (
!empty($data['searchFilter']['getSurfaces'])
&& !empty($data['searchFilter']['sliding'])
&& count($data['searchFilter']['sliding']) == 4
) {
$data['searchFilter']['getSurfaces'][] = 8;
unset($data['searchFilter']['sliding']);
}
// фильтр по антислипу sliding на самом деле getSurfaces
// todo лишнее
if (!empty($data['searchFilter']['sliding'])) {
foreach ($data['searchFilter']['sliding'] as $row) {
$data['searchFilter']['getSurfaces'][] = (int)('999' . $row);
}
unset($data['searchFilter']['sliding']);
}
// На основании вот этой просьбы https://te.remote.team/#/discus/4B853CC1-9B65-BD60-F896-352327BC5F2C/
if (!empty($data['searchFilter']['factory']) && count($data['searchFilter']) == 1) {
$withSchema = true;
}
if (!App::isRole('ROLE_TEST')) {
$this->sphinxQL->addWhere('c_test_access != 1');
$this->sphinxQL->addWhere('f_test_access != 1');
}
if (!empty($data['HideFactory'])) {
$this->sphinxQL->addWhere('f_id NOT IN (?)', $data['HideFactory']);
} elseif (HideFactoryCountriesHelper::length() > 0) {
$this->sphinxQL->addWhere('f_id NOT IN (?)', HideFactoryCountriesHelper::codes());
}
$country = App::getCurCountry();
$measure = !empty($data['measure']) ? $data['measure'] : LocaleHelper::getUserMeasure();
$priceFields = $this->getPriceFields(LocaleHelper::getCur(), $country, $measure);
// для автоматической простановки фильтров
$dataArticles = [
'getPrstatus' => 'pr_status', // код акции
'getTypes' => 'type', // код вида изделия
'getTypeUsings' => 'using', // код назначения
'getCountry' => 'country', // код страны
'getPrcateg' => 'pr_status', // код акции
'getMaterials' => 'material', // код материала
'getCostCategory' => $priceFields[3],//'a_price_cat', // код категории цены
'getEdgeType' => 'edge_type', // тип края
'offShade' => 'off_shade', // разнотон (моноколор)
'getStyles' => 'sid', // код стиля
'getSurfaces' => 'surface', // код типа
'getFacturas' => 'a_texture', // код фактуры
'getStone' => 'a_stone_texture', // код фактуры камня
'getColors' => 'color', // код цветов
'shape' => 'shape', // код формы
'motive' => 'a_motive', // мотив рисунка
'motiv' => 'a_motiv', // мотив рисунка
'pei' => 'pei',
];
// $fromCountArr = [
// //Filter => sphinx_filds
// 'getStyles' => 'sid', // код стиля
// 'getSurfaces' => 'surface', // код типа
// 'getFacturas' => 'a_texture', // код фактуры
// 'getStone' => 'a_stone_texture', // код фактуры камня
// 'getColors' => 'color', // код цветов
// 'shape' => 'shape', // код формы
// 'motive' => 'a_motive', // мотив рисунка
// 'motiv' => 'a_motiv', // мотив рисунка
// 'inside' => $priceFields[0],
// 'discontinued' => 'typecoll',
// 'expressSample' => 'express_sample',
// 'getAwards' => 'c_awards',
// 'exhibition' => 'c_exhibition',
// 'size_x' => 'size_x',
// 'size_y' => 'size_y',
// 'tolsch' => 'thick',
// 'thick' => 'thick',
// 'material' => 'material',
// 'getTypeUsings' => 'using',
// 'factory' => 'factory',
// 'bm' => 'u_id',
// 'c_id' => 'c_id',
// 'getThinGranite' => 'thin_granite',
// 'size_big' => 'size_big',
// 'getGlazedGranit' => 'glazed_granite',
// 'getThickGranite' => 'thick_granite',
// 'searchPeriod' => 'publish_period',
// 'releaseYear' => 'c_release_year',
// 'reviews' => 'reviews',
// 'dyedInMass' => 'dyed_in_mass',
// 'colorBody' => 'color_body',
// 'sliding' => 'sliding',
// 'getUsings' => 'apply_id',
// 'getDesigner' => 'c_designer_ids',
// 'monochrome' => 'monochrome',
// ];
//Добавим поля интерьера первые найденный тогда сфинкс вернет сразу пустую строку и не нужно будет делать проверку и цикл
$interiorFilds = [
'attr_data.i[0].i_name as i_name',
'attr_data.i[0].i_id as i_id',
'attr_data.i[0].i_rating as i_rating',
'attr_data.i[0].i_monochrome as i_monochrome',
'attr_data.i[0].i_status as i_status',
'attr_data.i[0].i_file as i_file',
'attr_data.i[0].i_wall_and_floor as i_wall_and_floor',
'attr_data.i[0].i_style as i_style',
'attr_data.i[0].i_texture as i_texture',
'attr_data.i[0].fsi_x as fsi_x',
'attr_data.i[0].fsi_y as fsi_y',
];
//поля которые перенесены в attr_data что позволило сократить таблицу до артикулов проверить
$mvaFields = [
'color',
'material',
'a_motive',
'a_texture',
'designer',
'edge_type',
'a_motiv',
'shape',
'a_stone_texture',
'style',
'surface',
'texture',
'a_head',
'sid',
'styleida',
'styleid',
'sort',
'i_style',
'c_apply',
'apply_id',
'typecoll',
'i_rating',
'i_id',
'is_head',
'fsi_x',
'fsi_y',
'i_name_hash',
'i_file_hash',
'i_type',
'i_status',
'i_texture',
'i_monochrome',
'i_wall_and_floor',
'using',
'type',
];
//вычитаем поля если они attr_data добавляются через $dataAttrFields
// $plusFields = array_diff($plusFields, $attrData);
$fields = array_unique(array_merge($interiorFilds, $fields, $priceFields));
// App::debugExit($fields);
if (empty($data['total_found'])) {
$this->sphinxQL->setFrom('article', $fields);
} else {
$this->sphinxQL->setFrom('article', 'coll'); //todo тут должна появиться новая таблица
}
if (!empty($data['searchFilter']['inside'])) {
$this->sphinxQL->addWhere($priceFields[0] . ' > 0.0');
$this->sphinxQL->addWhere('delivery <> 6');
} elseif (!empty($data['searchFilter']['discontinued'])) {
$this->sphinxQL->addWhere('ANY(typeColl) in (2) ');
} else {
$this->sphinxQL->addWhere('ANY(typeColl) in (1)');
if (!(!empty($data['searchFilter']['factory']) && count($data['searchFilter']) == 1)) {
$this->sphinxQL->addWhere($priceFields[0] . ' > 0.0');
$this->sphinxQL->addWhere('c_status = 1');
} else {
$this->sphinxQL->addWhere('c_status IN (1, 3)');
}
}
// принято решение, если выбран стиль, то отбираем сразу по фонам декорам панно
// https://te.remote.team/#/discus/85E0842C-BCDE-D6E6-7EA4-2DB50BB404EC/
if (
!empty($data['searchFilter']['getStyles']) &&
empty($data['searchFilter']['getTypes']) &&
empty($data['searchFilter']['inside'])
) {
$data['searchFilter']['getTypes'] = [1, 113, 106, 24, 122, 128]; //todo нужно перенести в индекс
}
//TODO Удалить раз схемы навсегда улетают
// if (
// !$withSchema && (
// empty($data['searchFilter']['getTypes']) ||
// array_intersect($data['searchFilter']['getTypes'], [1, 24, 113, 122])
// ) &&
// empty($data['searchFilter']['size_x']) &&
// empty($data['searchFilter']['size_y']) &&
// empty($data['searchFilter']['size_z']) &&
// empty($data['searchFilter']['motiv'])
// ) {
// $this->sphinxQL->addWhere('scheme = ?', 0);
// }
$this->sphinxQL->addWhere('scheme = ?', 0);
// ставим фильтры
if (!empty($data['searchFilter'])) {
if (!empty($data['searchFilter']['expressSample'])) {
if (
!empty($data['searchFilter']['inside']) ||
count($data['searchFilter']) > 1 && empty($data['searchFilter']['factory']) ||
count($data['searchFilter']) > 2 && !empty($data['searchFilter']['factory'])
) {
$this->sphinxQL->addWhere("express_sample = 1");
} else {
$this->sphinxQL->addWhere("c_express_sample = 1");
}
}
// если getAwards, то просто проверяем наличие наград и все, без уточнений
if (!empty($data['searchFilter']['getAwards'])) {
$this->sphinxQL->addWhere("c_awards is not null");
}
// Если exhibition, то просто проверяем наличие выставок и все,
// без уточнений. Их фильтруем потом дополнительно
if (!empty($data['searchFilter']['exhibition'])) {
$this->sphinxQL->addWhere("c_exhibition <> ''");
}
// отдельно фильтр для дизайнеров, с заготовкой под ID
if (!empty($data['searchFilter']['getDesigner'])) {
// 1 имя, 0 это Id
$designerName = '';
$designerId = $data['searchFilter']['getDesigner'][0];
// поставил LIKE поиск по имени дизайнера + поиск по ID
$this->sphinxQL->addWhere("MATCH('(@c_designer_ids $designerId) {$designerName}')");
unset($data['searchFilter']['getDesigner']);
}
if (!empty($data['searchFilter']['size_x'])) {
$this->sphinxQL->addWhere(
'size_x >= ?',
str_replace(',', '.', $data['searchFilter']['size_x'][0] * 100)
);
$buildingMixtureOff = true;
}
if (!empty($data['searchFilter']['size_y'])) {
$this->sphinxQL->addWhere(
'size_y >= ?',
str_replace(',', '.', $data['searchFilter']['size_y'][0] * 100)
);
$buildingMixtureOff = true;
}
if (!empty($data['searchFilter']['tolsch'])) {
$this->sphinxQL->addWhere(
'tolsch >= ?',
str_replace(',', '.', $data['searchFilter']['tolsch'][0] * 100)
);
$buildingMixtureOff = true;
}
if (!empty($data['searchFilter']['size_x2'])) {
$this->sphinxQL->addWhere(
'size_x <= ?',
str_replace(',', '.', $data['searchFilter']['size_x2'][0] * 100)
);
if (empty($data['searchFilter']['size_x'])) {
$this->sphinxQL->addWhere('size_x > ?', 0);
}
$buildingMixtureOff = true;
}
if (!empty($data['searchFilter']['size_y2'])) {
$this->sphinxQL->addWhere(
'size_y <= ?',
str_replace(',', '.', $data['searchFilter']['size_y2'][0] * 100)
);
if (empty($data['searchFilter']['size_y'])) {
$this->sphinxQL->addWhere('size_y > ?', 0);
}
$buildingMixtureOff = true;
}
if (!empty($data['searchFilter']['tolsch2'])) {
$this->sphinxQL->addWhere(
'tolsch <= ?',
str_replace(',', '.', $data['searchFilter']['tolsch2'][0] * 100)
);
if (empty($data['searchFilter']['tolsch'])) {
$this->sphinxQL->addWhere('tolsch > ?', 0);
}
$buildingMixtureOff = true;
}
// специально для приложений
if (!empty($data['searchFilter']['prMinFrom'])) {
$this->sphinxQL->addWhere(
'pr_min <= ?',
str_replace(',', '.', $data['searchFilter']['prMinFrom'][0] * 100)
);
}
if (!empty($data['searchFilter']['prMinTo'])) {
$this->sphinxQL->addWhere(
'pr_min >= ?',
str_replace(',', '.', $data['searchFilter']['prMinTo'][0] * 100)
);
}
//todo удалить после тестов перенести логику наверх
if (!empty($data['searchFilter']['shape'])) {
// if (in_array(10, $data['searchFilter']['shape'])) {
// unset($data['searchFilter']['shape'][array_search(10, $data['searchFilter']['shape'])]);
// $this->sphinxQL->addWhere('module = ?', 1);
// }
if (!count($data['searchFilter']['shape'])) {
unset($data['searchFilter']['shape']);
}
}
// фильтр окрашен по color body //нужно добавить в материал иначе идет только через AND
if (!empty($data['searchFilter']['colorBody'])) {
$data['searchFilter']['getMaterials'][] = 999;
// $this->sphinxQL->addWhere("color_body = ?", $data['searchFilter']['colorBody']);
}
if (!empty($data['searchFilter']['getColors']) && in_array(99, $data['searchFilter']['getColors'])) {
$this->sphinxQL->addWhere('ANY(color) in (?)', 99);
unset($data['searchFilter']['getColors'][array_search(99, $data['searchFilter']['getColors'])]);
if (empty($data['searchFilter']['getColors'])) {
unset($data['searchFilter']['getColors']);
}
}
// если есть фильтры, то добавляем их к запросу
foreach ($data['searchFilter'] as $key => $row) {
if (!empty($dataArticles[$key])) {
// отключаем фильтр getPrcateg и ориентируемся на баланс
if (trim($key) == 'getPrcateg') {
continue;
}
//тут проставим $mvaFields чтобы искать в MVA any|all
if (in_array($dataArticles[$key], $mvaFields)) {
$dataArticles[$key] = ' ANY(' . $dataArticles[$key] . ')';
}
$this->sphinxQL->addWhere($dataArticles[$key] . ' IN (?)', $row);
}
}
// фильтр окрашен в массе
if (!empty($data['searchFilter']['dyedInMass'])) {
$this->sphinxQL->addWhere('dyed_in_mass = 1');
}
// !!! теперь если выбран фильтр применения показываем только интерьеры
// для применения работает немного иначе если более одного признака то идёт наследование от коллекции,
// но при этом надо не показывать интерьеры, которые не соответствуют применению
if (!empty($data['searchFilter']['getUsings'])) {
if (!empty($data['searchFilter']['getUsings'])) {
// вернул выборку по ID иначе показывает все из "применения" без фильтрации.
$this->sphinxQL->addWhere('ANY(apply_id) IN (?)', $data['searchFilter']['getUsings']);
}
$this->sphinxQL->addWhere('c_accessible <> 1');
}
// фильтр по фабрике
if (!empty($data['searchFilter']['factory'])) {
$this->sphinxQL->addWhere('factory = \'' . $data['searchFilter']['factory'][0] . '\'');
}
// фильтр по фабрике
if (!empty($data['searchFilter']['bm'])) {
$bmId = $data['searchFilter']['bm'];
$bmId = is_array($bmId) ? $bmId[0] : $bmId;
$this->sphinxQL->addWhere('u_id = ' . $bmId);
}
// фильтр по id коллекций
if (!empty($data['searchFilter']['c_id'])) {
$this->sphinxQL->addWhere('c_id IN (?)', $data['searchFilter']['c_id']);
}
}
// тонкий керамогранит
if (!empty($data['searchFilter']['getThinGranite'])) {
$this->sphinxQL->addWhere('thin_granite = ?', 1);
$buildingMixtureOff = true;
}
// фильтр большого размера плитки
if (!empty($data['searchFilter']['size_big'])) {
$this->sphinxQL->addWhere('size_big = ?', 1);
$buildingMixtureOff = true;
}
// глазурированный/неглазурированный керамогранит
if (!empty($data['searchFilter']['getGlazedGranit'])) {
$this->sphinxQL->addWhere('glazed_granite = ?', $data['searchFilter']['getGlazedGranit']);
}
if ($country == 'ru' || $buildingMixtureOff) {
$this->sphinxQL->addWhere('c_id != ?', 3245628);
}
// утолщенный керамогранит
if (!empty($data['searchFilter']['getThickGranite'])) {
$this->sphinxQL->addWhere('thick_granite = ?', $data['searchFilter']['getThickGranite']);
}
// Если новинки, то выводим только коллекции за месяц
//Семраш пишет не может сканировать страницу новинок
//https://te2.remote.team/discus/35DEFA01-C136-0EA2-DB72-E8999812EBFC
if (isset($data['searchFilter']['getTop'])) {
$this->sphinxQL->addWhere('ANY(publish_period) = ?', 4);
}
// выборки за период
if (isset($data['searchPeriod'])) {
$this->sphinxQL->addWhere('ANY(publish_period) = ?', $data['searchPeriod']);
}
$dateSort = 'publish_date DESC';
// фильтрация по году выпуска
if (!empty($data['searchFilter']['releaseYear'])) {
$years = [];
foreach ($data['searchFilter']['releaseYear'] as $year) {
if (strlen($year) > 4) {
$y = substr($year, 0, 4);
do {
$y--;
$years[] = $y;
} while ($y > 2013);
} elseif ($year == 999) {
$years[] = date('Y');
} else {
$years[] = $year;
}
}
if (count($years) > 0) {
$this->sphinxQL->addWhere('c_release_year IN (?)', $years);
}
}
// фильтрация по средней оценке отзывов
if (!empty($data['searchFilter']['reviews'])) {
$this->sphinxQL->addWhere('reviews IN (?)', $data['searchFilter']['reviews']);
if ($this->getSearchSortId() == 0) {
$data['searchSort'] = 6;
}
}
// учитываем сортировку в запросе
if (isset($data['searchFilter']['getTopMonth'])) {
$searchSort = 'c_pop30 DESC';
} elseif (isset($data['searchFilter']['getTopWeek'])) {
$searchSort = 'c_pop7 DESC';
} else {
$searchSort = 'rating DESC';
}
if (!empty($data['searchFilter']['getCostCategory']) && $this->getSearchSortId() == 0) {
$searchSort = 'price_sort ASC';
}
if (!empty($data['searchFilter'][''])) {
unset($data['searchFilter']['']);
}
// определяем тип минимальной цены
$minTypeAll = false;
if (
(count($data['searchFilter']) == 0 || !empty($data['searchFilter']['factory'])
&& count($data['searchFilter']) == 1) && !$getCount
) {
$minTypeAll = true;
// Если нет фильтров ищем только по фонам мозаике декору
// Ага, а если ищем зеленный, то выводим красный :)
// $this->sphinxQL->addWhere('ANY(type) IN (?)', [1, 24, 113, 122, 27, 106, 64, 128, 0]);
}
// https://te.remote.team/#/discus/BDBD8973-1F54-3B16-99ED-8656AEFC1105/
// убрал совсем сортировку по полю price_euro
if (
!empty($data['searchFilter']['getTypes']) && !array_intersect(
(array)$data['searchFilter']['getTypes'],
[1, 24, 113, 122, 106]
)
) {
$sort = 'price_sort ASC';
} else {
$sort = $priceFields[4] . ' ASC';
}
$searchSortLimit = false;
if (!empty($data['searchSort'])) {
switch ($data['searchSort']) {
case 2:
// по цене
$searchSort = false;
break;
case 3:
// по дате
$searchSort = 'publish_date DESC';
break;
case 4:
// по алфавиту
$searchSort = 'c_name ASC';
break;
case 5:
// по популярности за месяц
$searchSort = 'rating_month DESC';
break;
case 6:
// по отзывам
$searchSort = 'prc_star DESC';
$searchSortLimit = 'prc_count DESC';
break;
}
}
if (empty($data['total_found'])) {
if ($searchSort) {
$this->sphinxQL->setOrder($searchSort);
}
$this->sphinxQL
->setOrder('sort DESC')
->setOrder(
$searchSortLimit ? $searchSortLimit : $sort
) //цена в приоритете она создает коллекцию и минимальную ее цену
->setOrder('max_is_head DESC') //сортирует только по строкам max_is_head"
->setOrder($dateSort);
}
if (!empty($data['total_found'])) {
$this->sphinxQL->setLimit(1)
->setGroup('coll');
$rows = $this->sphinxQL->getQuery()->fetchAllAssociative();
$totalFound = $this->sphinxQL->getTotalFound();
return ['total_found' => $totalFound];
}
$this->subFilters = $this->filterRepo->getFiltersSubRelation(false);
if (empty($data['limit'])) {
$this->sphinxQL->setLimit(SphinxQLService::MAX_MATCHES);
if (empty($data['searchFilter']['inside'])) {
$this->sphinxQL->setGroup('a_id');//, i_id, sid, styleid, styleida
}
} else {
$this->sphinxQL->setLimit($data['limit'])
->setGroup('coll');
}
if (!empty($data['real'])) {
$this->sphinxQL->setOption('max_matches=200000');
$this->sphinxQL->setLimit(200000);
}
$ed = [];
$listMeasure = $this->em->getRepository('WebBundle:ListMeasure')->findBy(['hide' => false]);
/** @var ListMeasure $row */
foreach ($listMeasure as $row) {
$ed[$row->getId()] = $row->getAlias() != null
? $this->translator->trans($row->getAlias())
: $row->getName();
}
//дополнительные свойства
$collections = ['i_names' => [], 'a_names' => []];
$num = 0;
$rows = $this->sphinxQL->getQuery()->fetchAllAssociative();
if ($getCount) {
$calculate = [];
//Создаем привязку фильтра к нашим полям для подсчета
$aFiltersOnlyNoChilds = $this->filterRepo->getListForSynchCountFilters([]);
$realFilterProperty = [];
$newFiltersOnlyNoChild = [];
foreach ($aFiltersOnlyNoChilds as $fVal) {
$fRealId = $fVal['oldCommand'] == 'getDesigner' ? $fVal['id'] : $fVal['oldId'];
$realFilterProperty[$fVal['oldCommand']] [$fRealId] = $fVal;
$realFilterProperty[$fVal['oldCommand']] [$fRealId] ['oldId'] = $fRealId;
$realFilterProperty[$fVal['oldCommand']] [$fRealId] ['count'] = 0;
$realFilterProperty[$fVal['oldCommand']] [$fRealId] ['coll_array'] = []; //добавляем массив колеккций дабы отсекать у родителей дубли
$newFiltersOnlyNoChild[$fVal['id']] = $fVal;
$newFiltersOnlyNoChild[$fVal['id']]['coll_array'] = [];
}
}
foreach ($rows as $row) {
if (!empty($row['attr_data']) && $attDate = json_decode($row['attr_data'], true)) {
// удаляем интерфейсы
unset($attDate['i_name']);
unset($attDate['i_id']);
unset($attDate['i_rating']);
unset($attDate['i_monochrome']);
unset($attDate['i_status']);
unset($attDate['i_file']);
unset($attDate['i_wall_and_floor']);
unset($attDate['i_style']);
unset($attDate['i_texture']);
unset($attDate['fsi_x']);
unset($attDate['fsi_y']);
$row = array_merge((array)$row, $attDate); //удалить главный интерьер из сфинкса
}
if (!empty($row['c_exhibition']) && $exhibitionDate = json_decode($row['c_exhibition'], true)) {
$row['c_exhibition'] = $exhibitionDate;
} else {
$row['c_exhibition'] = [];
}
if (!empty($row['c_awards']) && $c_awardsDate = json_decode($row['c_awards'], true)) {
$row['c_awards'] = $c_awardsDate;
} else {
$row['c_awards'] = [];
}
if (!empty($row['c_designer_ids']) && $c_designer_idsDate = json_decode($row['c_designer_ids'], true)) {
$row['c_designer_ids'] = $c_designer_idsDate;
} else {
$row['c_designer_ids'] = [];
}
// временно
if ($getCount) {
if (empty($calculate[$row['coll']])) {
//todo по факту эти поля нужно будет собрать из индекса который будет колеккцией пока у меня article2
$calculate[$row['coll']] = [
'getStyles' => [],
'getSurfaces' => [],
'getFacturas' => [],
'getMaterials' => [],
'getStone' => [],
'getColors' => [],
'shape' => [],
'motive' => [],
'motiv' => [],
// 'inside' => [],
'discontinued' => [],
'expressSample' => [],
'getAwards' => [],
'exhibition' => [],
'size_x' => [],
'size_y' => [],
'tolsch' => [],
'material' => [],
'getTypeUsings' => [],
'factory' => [],
'bm' => [],
'c_id' => [],
'getThinGranite' => [],
'size_big' => [],
'getGlazedGranit' => [],
'getThickGranite' => [],
'searchPeriod' => [],
'releaseYear' => [],
'reviews' => [],
'dyedInMass' => [],
'colorBody' => [],
'sliding' => [],
'getUsings' => [],
'getDesigner' => [],
'monochrome' => [],
'getPrcateg' => [],
'getTypes' => [],
'getCountry' => [],
'a_price_cat_pln' => [],
'getEdgeType' => [],
'offShade' => [],
'getCostCategory' => [],
];
}
//пробуем просто собрать данные;
$calculate[$row['coll']]['getCostCategory'] = array_merge(
$calculate[$row['coll']]['getCostCategory'],
[$row[$priceFields[3]]]
);
$calculate[$row['coll']]['getStyles'] = array_merge(
$calculate[$row['coll']]['getStyles'],
explode(',', $row['sid'])
);
$calculate[$row['coll']]['getSurfaces'] = array_merge(
$calculate[$row['coll']]['getSurfaces'],
explode(',', $row['surface'])
);
$calculate[$row['coll']]['getMaterials'] = array_merge(
$calculate[$row['coll']]['getMaterials'],
explode(',', $row['material'])
);
$calculate[$row['coll']]['getFacturas'] = array_merge(
$calculate[$row['coll']]['getFacturas'],
explode(',', $row['a_texture'])
);
$calculate[$row['coll']]['getStone'] = array_merge(
$calculate[$row['coll']]['getStone'],
explode(',', $row['a_stone_texture'])
);
$calculate[$row['coll']]['getColors'] = array_merge(
$calculate[$row['coll']]['getColors'],
explode(',', $row['color'])
);
$calculate[$row['coll']]['shape'] = array_merge(
$calculate[$row['coll']]['shape'],
explode(',', $row['shape'])
);
$calculate[$row['coll']]['motive'] = array_merge(
$calculate[$row['coll']]['motive'],
explode(',', $row['a_motive'])
);
$calculate[$row['coll']]['motiv'] = array_merge(
$calculate[$row['coll']]['motiv'],
explode(',', $row['a_motiv'])
);
// $calculate[$row['coll']]['inside'] = array_merge(
// $calculate[$row['coll']]['inside'],
// [$row[$priceFields[0]]]
// );
$calculate[$row['coll']]['discontinued'] = array_merge(
$calculate[$row['coll']]['discontinued'],
explode(',', $row['typecoll'])
);
$calculate[$row['coll']]['expressSample'] = array_merge(
$calculate[$row['coll']]['expressSample'],
[$row['c_express_sample']]
);
$calculate[$row['coll']]['getAwards'] = array_merge(
$calculate[$row['coll']]['getAwards'],
[!empty($row['c_awards']) ? 1 : 2]
);
$calculate[$row['coll']]['exhibition'] = array_merge(
$calculate[$row['coll']]['exhibition'],
$row['c_exhibition']
);
$calculate[$row['coll']]['size_x'] = array_merge(
$calculate[$row['coll']]['size_x'],
[$row['size_x']]
);
$calculate[$row['coll']]['size_y'] = array_merge(
$calculate[$row['coll']]['size_y'],
[$row['size_y']]
);
$calculate[$row['coll']]['tolsch'] = array_merge(
$calculate[$row['coll']]['tolsch'],
[$row['tolsch']]
);
$calculate[$row['coll']]['material'] = array_merge(
$calculate[$row['coll']]['material'],
explode(',', $row['material'])
);
$calculate[$row['coll']]['getTypeUsings'] = array_merge(
$calculate[$row['coll']]['getTypeUsings'],
explode(',', $row['using'])
);
$calculate[$row['coll']]['factory'] = array_merge(
$calculate[$row['coll']]['factory'],
[$row['factory']]
);
$calculate[$row['coll']]['bm'] = array_merge($calculate[$row['coll']]['bm'], [$row['u_id']]);
$calculate[$row['coll']]['c_id'] = array_merge($calculate[$row['coll']]['c_id'], [$row['c_id']]);
$calculate[$row['coll']]['getThinGranite'] = array_merge(
$calculate[$row['coll']]['getThinGranite'],
[$row['thin_granite']]
);
$calculate[$row['coll']]['size_big'] = array_merge(
$calculate[$row['coll']]['size_big'],
[$row['size_big']]
);
$calculate[$row['coll']]['getGlazedGranit'] = array_merge(
$calculate[$row['coll']]['getGlazedGranit'],
[$row['glazed_granite']]
);
$calculate[$row['coll']]['getThickGranite'] = array_merge(
$calculate[$row['coll']]['getThickGranite'],
[$row['thick_granite']]
);
$calculate[$row['coll']]['searchPeriod'] = array_merge(
$calculate[$row['coll']]['searchPeriod'],
[$row['publish_period']]
);
$calculate[$row['coll']]['releaseYear'] = array_merge(
$calculate[$row['coll']]['releaseYear'],
[$row['c_release_year']]
);
$calculate[$row['coll']]['reviews'] = array_merge(
$calculate[$row['coll']]['reviews'],
explode(',', $row['reviews'])
);
$calculate[$row['coll']]['dyedInMass'] = array_merge(
$calculate[$row['coll']]['dyedInMass'],
[$row['dyed_in_mass']]
);
$calculate[$row['coll']]['sliding'] = array_merge(
$calculate[$row['coll']]['sliding'],
[$row['sliding']]
);
$calculate[$row['coll']]['getUsings'] = array_merge(
$calculate[$row['coll']]['getUsings'],
explode(',', $row['apply_id'])
);
$calculate[$row['coll']]['getDesigner'] = array_merge(
$calculate[$row['coll']]['getDesigner'],
$row['c_designer_ids']
);
$calculate[$row['coll']]['monochrome'] = array_merge(
$calculate[$row['coll']]['monochrome'],
explode(',', $row['monochrome'])
);
$calculate[$row['coll']]['getPrcateg'] = array_merge(
$calculate[$row['coll']]['getPrcateg'],
[$row['pr_status']]
);
$calculate[$row['coll']]['getTypes'] = array_merge(
$calculate[$row['coll']]['getTypes'],
explode(',', $row['type'])
);
$calculate[$row['coll']]['getCountry'] = array_merge(
$calculate[$row['coll']]['getCountry'],
[$row['country']]
);
$calculate[$row['coll']]['getEdgeType'] = array_merge(
$calculate[$row['coll']]['getEdgeType'],
explode(',', $row['edge_type'])
);
$calculate[$row['coll']]['offShade'] = array_merge(
$calculate[$row['coll']]['offShade'],
[$row['off_shade']]
);
//
//включаем если запрашивали
}
$row['apply_id'] = explode(',', $row['apply_id']);
if (!empty($data['offset'])) {
$num++;
if ($data['offset'] > ($num - 1)) {
continue;
}
}
if (!empty($row['c_accessible'])) {
$noInteriorFactory = true;
} else {
$noInteriorFactory = false;
}
if ($row['c_id'] == 3245628) {
$row['c_name'] = App::trans('left_menu_glue');
}
//создаем клон из строки, но с данными из Коллекций для блатного удаления и фильтрации
//обратить внимание при поиске по коллекциям возврщает полный результат и потом фильтрует возможно можно что-то перенести в sphinx или в where
$iRows = [];
if (!empty($row['i'])) {
// Заменяем значения $row значениями $row[i][n]
foreach ($row['i'] as $v) {
$iRows[] = array_merge($row, $v);
}
} else {
//если нет, то для дальнейшей проверки оставим старое значение
$iRows[] = $row;
}
foreach ($iRows as $intRow) {
$row = $intRow;
if (
!empty($data['searchFilter']['getUsings']) && count($data['searchFilter']) > 1 &&
!(count(array_intersect([$row['apply_id']], $data['searchFilter']['getUsings'])) > 0)
) {
$applyShow = false;
} else {
$applyShow = true;
}
if ($row['process'] == 1) {
$row['i_file'] = str_replace(['.jpeg', '.jpg'], '.webp', $row['i_file']);
}
$noRestriction = $this->getNoRestriction($data['searchFilter'], $row, $oldTypeUsings ?? null);
// есть ограничение на показ интерьером, но выбран фильтр применения, пропускаем такой элемент
if (
!empty($data['searchFilter']['getUsings'])
&& !$noRestriction
) {
continue;
}
// базовая информация о коллекции
if (empty($collections[$row['coll']])) {
if ($row['c_status'] == 1) {
$dataReview[$row['coll']] = [
'name' => App::trans(
$row['c_header'] . '.short',
App::getCurLocale(),
[
'%collection%' => $row['c_name'],
]
),
'url' => App::generateUrl(
'app_collection',
[
'factoryUrl' => $row['f_url'],
'collectionUrl' => $row['c_url'],
]
),
];
}
if (isset($data['searchFilter']['getTopMonth'])) {
$arrow = $row['c_pop30'] > $row['c_last_pop30'] ? 'up' : 'down';
} elseif (isset($data['searchFilter']['getTopWeek'])) {
$arrow = $row['c_pop7'] > $row['c_last_pop7'] ? 'up' : 'down';
} else {
$arrow = false;
}
$collections[$row['coll']] = [
'c_id' => $row['c_id'],
'c_code' => $row['coll'],
'c_status' => $row['c_status'],
'c_name' => $row['c_name'],
'ratingMonth' => $row['rating_month'],
'arrow' => $arrow,
'c_header' => $row['c_header'],
'c_release_year' => $row['c_release_year'],
'c_url' => $row['c_url'],
'f_name' => $row['f_name'],
'f_url' => $row['f_id'] == 12 ? StrHelper::toLower($row['f_url']) : $row['f_url'],
];
// если не пустое, то там массив с ID фильтров, иконки которых надо получить будет
$collections[$row['coll']]['c_awards'] = $row['c_awards'];
// если не пустое, то там массив с sub ID фильтров выставок
$collections[$row['coll']]['c_exhibition'] = $row['c_exhibition'];
$collections[$row['coll']]['date'] = date('d.m.Y', $row['publish_date']);
$collections[$row['coll']]['country'] = $row['country'];
$collections[$row['coll']]['country_code'] = $row['country_code'];
$collections[$row['coll']]['type'] = $row['type'];
$collections[$row['coll']]['material'] = $this->mapMaterial(
array_unique(explode(',', $row['c_material'] ?? ''))
);
// вывел признак экспресс образца
$collections[$row['coll']]['hasExpressSample'] = !empty($row['c_express_sample']) && $row['c_express_sample'] == 1;
// добавил вывод prc_middle, что бы можно было проверить точность фильтрации
$prcCount = empty($row['prc_count']) ? null : $row['prc_count'];
$prcVote = empty($row['prc_vote']) ? null : $row['prc_vote'];
$prcMiddle = 0;
if ($prcCount && $prcVote) {
$prcMiddle = ($prcVote / $prcCount + 0.01 * $prcCount) * 100;
}
$collections[$row['coll']]['prc_count'] = $prcCount;
$collections[$row['coll']]['prc_vote'] = $prcVote;
$collections[$row['coll']]['prc_middle'] = $prcMiddle;
$collections[$row['coll']]['process'] = $row['process'] ?? 0;
$collections[$row['coll']]['alt'] = str_replace(
['\\', '"', '\''],
'',
join(', ', [$row['f_name'], $row['c_name'], $row['i_name']])
);
$collections[$row['coll']]['author'] = empty($row['author']) ? null : $row['author'];
$collections[$row['coll']]['sliding'] = empty($row['sliding']) ? [] : [$row['sliding']];
$collections[$row['coll']]['a_show'] = empty($data['searchFilter']['getUsings']) ? '1' : '0';
// цены по умолчанию
$collections[$row['coll']]['price'] = (float)(max($row[$priceFields[0]], 1));
$collections[$row['coll']]['pr_min'] = (float)(max($row[$priceFields[2]], 1));
$collections[$row['coll']]['price_mq'] = (float)(max($row[$priceFields[1]], 1));
$collections[$row['coll']][$priceFields[4]] = (float)(max($row[$priceFields[4]], 1));
$collections[$row['coll']]['measureId'] = $row['measure'];
if (!empty($collections[$row['coll']]['price_mq']) && $row[$priceFields[3]] > 0) {
$collections[$row['coll']]['price'] = $collections[$row['coll']]['price_mq'];
$collections[$row['coll']]['measureId'] = 1;
$row['measure'] = 1;
}
$collections[$row['coll']]['measureText'] = $ed[$row['measure']] == 'm²' && LocaleHelper::getUserMeasure(
) == 'ft' ? 'ft²' : $ed[$row['measure']];
if (in_array($country, ['ch', 'no', 'hk', 'sg'])) {
$collections[$row['coll']]['price'] = round(
$collections[$row['coll']]['price'] - $collections[$row['coll']]['price'] * 18 / 118,
2
);
$collections[$row['coll']]['pr_min'] = round(
$collections[$row['coll']]['pr_min'] - $collections[$row['coll']]['pr_min'] * 18 / 118,
2
);
$collections[$row['coll']]['price_mq'] = round(
$collections[$row['coll']]['price_mq'] - $collections[$row['coll']]['price_mq'] * 18 / 118,
2
);
}
// для Гонконга конвертируем из мальтийских цен по курсу
if ($country == 'hk') {
$collections[$row['coll']]['price'] = CurrencyRateHelper::convertPrice(
'HKD',
$collections[$row['coll']]['price']
);
$collections[$row['coll']]['pr_min'] = CurrencyRateHelper::convertPrice(
'HKD',
$collections[$row['coll']]['pr_min']
);
$collections[$row['coll']]['price_mq'] = CurrencyRateHelper::convertPrice(
'HKD',
$collections[$row['coll']]['price_mq']
);
$collections[$row['coll']][$priceFields[4]] = CurrencyRateHelper::convertPrice(
'HKD',
$collections[$row['coll']][$priceFields[4]]
);
}
// для Сингапура конвертируем из мальтийских цен по курсу
if ($country == 'sg') {
$collections[$row['coll']]['price'] = CurrencyRateHelper::convertPrice(
'SGD',
$collections[$row['coll']]['price']
);
$collections[$row['coll']]['pr_min'] = CurrencyRateHelper::convertPrice(
'SGD',
$collections[$row['coll']]['pr_min']
);
$collections[$row['coll']]['price_mq'] = CurrencyRateHelper::convertPrice(
'SGD',
$collections[$row['coll']]['price_mq']
);
$collections[$row['coll']][$priceFields[4]] = CurrencyRateHelper::convertPrice(
'SGD',
$collections[$row['coll']][$priceFields[4]]
);
}
// убираем копейки
$collections[$row['coll']]['price'] = round($collections[$row['coll']]['price']);
$collections[$row['coll']]['pr_min'] = round($collections[$row['coll']]['pr_min']);
$collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['price_mq']);
// минимальная цена по коллекции если, не установлены дополнительные фильтры
if ($minTypeAll) {
$collections[$row['coll']]['pr_min'] = round($collections[$row['coll']][$priceFields[4]]);
$collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['pr_min']);
$collections[$row['coll']]['price'] = round($collections[$row['coll']]['pr_min']);
} elseif (empty($collections[$row['coll']]['price_mq'])) {
$collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['price']);
}
// собираем коды ед.изм.
$collections[$row['coll']]['measure'] = $ed[$row['measure']] ?? (App::trans(
$measure == 'm' ? 'measure_mq' : 'measure_ft'
));
$collections['i_names'][$row['coll']] = [];
$collections[$row['coll']]['interiors'] = [];
$collections[$row['coll']]['articles'][] = $this->article($row);
$collections[$row['coll']]['slidingShow'] = 0;
if (
!empty($data['searchFilter']['getSurfaces'])
&& in_array(8, $data['searchFilter']['getSurfaces'])
) {
$collections[$row['coll']]['slidingShow'] = 1;
}
$collections['a_names'][$row['coll']][] = $row['a_name'];
if (
empty($data['searchFilter']['inside'])
&& !$noInteriorFactory
&& (empty($data['searchFilter'])
|| count($data['searchFilter']) <= 2
&& !empty($data['searchFilter']['getAlsoCollViewed'])
|| count($data['searchFilter']) == 1
&& (!empty($data['searchFilter']['factory'])
|| !empty($data['searchFilter'][''])
)
)
&& !empty($row['is_main'])
) { // специальная заглушка для главной картинки коллекции на случай если не выбраны фильтры
[
$mainInteriorId,
$mainInteriorName,
$mainInteriorFile,
$fileSizeX,
$fileSizeY,
$iRating,
] = explode('|', $row['is_main']);
if (!$fileSizeY == 0 && !empty($mainInteriorName)) {
$iName = $mainInteriorName;
$iFile = $mainInteriorFile;
if ($row['a_head'] || !empty($data['searchFilter']['factory'])) {
$collections['i_names'][$row['coll']][] = $iName;
$collections[$row['coll']]['interiors'][] = [
'i_id' => $mainInteriorId,
'i_name' => $iName,
'i_file' => $iFile,
'i_rating' => $iRating,
'x' => $fileSizeX,
'y' => $fileSizeY,
];
}
}
}
if (
!$noInteriorFactory
&& !empty($row['i_name'])
&& isset($row['i_id']) && $row['i_id'] !== null
&& $noRestriction
&& $applyShow
&& !in_array($row['i_name'], $collections['i_names'][$row['coll']])
&& (empty($data['searchFilter']['getUsings'])
|| in_array(8, $data['searchFilter']['getUsings'])
&& $row['apply_id'] == 8
|| !in_array(8, $data['searchFilter']['getUsings'])
)
) {
$iName = $row['i_name'];
$iFile = $row['i_file'];
if ($row['a_head']) {
$collections['i_names'][$row['coll']][] = $iName;
$collections[$row['coll']]['interiors'][] = [
'i_id' => $row['i_id'],
'i_name' => $iName,
'i_file' => $iFile,
'x' => $row['fsi_x'],
'y' => $row['fsi_y'],
'i_rating' => $row['i_rating'],
];
}
}
} else {
// если запрошена фильтрация по коллекции, то выводим все артикулы
if (!empty($_GET['debug']) || !empty($data['searchFilter']['inside'])) {
$collections[$row['coll']]['articles'][] = $this->article($row);
}
if (
!empty($row['author']) &&
is_array($collections[$row['coll']]['author']) &&
!in_array($row['author'], $collections[$row['coll']]['author'])
) {
$collections[$row['coll']]['author'] = $row['author'];
}
if (!empty($row['sliding']) && !in_array($row['sliding'], $collections[$row['coll']]['sliding'])) {
$collections[$row['coll']]['sliding'][] = $row['sliding'];
}
// собираем коды ед.изм.
$collections[$row['coll']]['measure'] = $ed[$row['measure']] ?? (App::trans(
$measure == 'm' ? 'measure_mq' : 'measure_ft'
));
// если не установлен лимит или интерьера нет для вывода, то смотрим артикулы
if (
!empty($_GET['debug'])
|| $limit == 0
|| count($collections[$row['coll']]['interiors']) < $limit
) {
if (
(!empty($data['searchFilter']['getPrcateg'])
&& (in_array(7, $data['searchFilter']['getPrcateg'])
|| in_array(6, $data['searchFilter']['getPrcateg'])
)
)
|| !empty($data['searchFilter']['coll']) || count(
$collections[$row['coll']]['articles']
) == 0
) {
/** см. выше для первого вхождения артикула в коллекцию */
if (
empty($data['searchFilter']['getStyles'])
|| (!empty($data['searchFilter']['getStyles'])
&& in_array($row['a_style'], $data['searchFilter']['getStyles'])
)
) {
if (!in_array($row['a_name'], $collections['a_names'][$row['coll']])) {
$collections[$row['coll']]['articles'][] = $this->article($row);
}
}
}
if (
!$noInteriorFactory
&& !empty($row['i_name'])
&& isset($row['i_id']) && $row['i_id'] !== null
&& $noRestriction
&& $applyShow
&& !in_array($row['i_name'], $collections['i_names'][$row['coll']])
&& (
empty($data['searchFilter']['getUsings'])
|| !in_array(8, $data['searchFilter']['getUsings'])
|| $row['apply_id'] == 8
)
) {
if ($row['a_head']) {
$collections['i_names'][$row['coll']][] = $row['i_name'];
$collections[$row['coll']]['interiors'][] = [
'i_id' => $row['i_id'],
'i_name' => $row['i_name'],
'i_file' => $row['i_file'],
'x' => $row['fsi_x'],
'y' => $row['fsi_y'],
'i_rating' => $row['i_rating'],
];
}
}
}
$collections['a_names'][$row['coll']][] = $row['a_name'];
}
}
}
unset($collections['i_names']);
unset($collections['a_names']);
// проверяем и фильтруем дополнительно выставки
if (!empty($data['searchFilter']['exhibition'])) {
$idExh = $data['searchFilter']['exhibition'];
foreach ($collections as $i_ => $coll_) {
if (!array_intersect($idExh, $coll_['c_exhibition'])) {
unset($collections[$i_]);
}
}
}
if (
!empty($data['searchFilter']['getPrcateg'])
&& (in_array(6, $data['searchFilter']['getPrcateg'])
|| in_array(7, $data['searchFilter']['getPrcateg'])
)
) {
$collections = $this->setIndexesForArticlesInCollections($collections);
}
if ($getCount) {
//Отсекаем ненужные колекции
foreach ($calculate as $i => $coll) {
if (!isset($collections[$i])) {
unset($calculate[$i]);
}
}
}
$collections = array_values($collections);
if ($getCount) {
$fixfilter = $this->getCount($calculate, $realFilterProperty, $newFiltersOnlyNoChild);
if (!empty($fixfilter)) {
$res_enabledSize = $fixfilter;
} else {
$res_enabledSize = [];
}
$collections = [
'collections' => $collections,
'calculate' => $res_enabledSize,
];
}
if ($full) {
return [
'res' => $collections,
'codes' => $dataReview,
];
}
return $collections;
}
/**
* Подсчитывает Коллекции в свойстве
* @param array $calculate - Собраные значения
* @param array $realFilterProperty - фильтр связь ключей старые новые
* @return array - подсчет коллекций
* @throws Exception
*/
private function getCount(array $calculate, array $realFilterProperty = [], $aFiltersOnlyNoChilds = []): array
{
$oldId = 'id';
$res = [];
//перебераем массив с коллекциями не товарами
foreach ($calculate as $coll => $values) {
//перебираем их свойства
foreach ($values as $key => $value) {
//перебираем их значение
foreach (array_unique($value) as $v) {
//тут вся логика с фильтром
if (isset($realFilterProperty[$key][$v])) {
// $realFilterProperty[$key][$v]['count']++;
if (isset($res[$key][$realFilterProperty[$key][$v][$oldId]])) {
$res[$key][$realFilterProperty[$key][$v][$oldId]]++;
} else {
$res[$key][$realFilterProperty[$key][$v][$oldId]] = 1;
}
} else {
//если такого фильтра не существует нужно создать и присвоить его свойству первое вхождение
if (isset($res[$key][$v])) {
$res[$key][$v]++;
} else {
$res[$key][$v] = 1;
}
}
}
}
}
return $res;
}
/**
* @param $row
* @return array
* @throws Exception
*/
private function article($row): array
{
// сохраняем id артикула для выборки подробных данных артикулов подходящих под отбор
$this->articlesId[] = $row['a_id'];
return [
'a_id' => $row['a_id'],
'a_name' => $row['a_name'],
'file' => $row['process'] == 1 ? str_replace(['.jpeg', '.jpg'], '.webp', $row['file']) : $row['file'],
'a_x' => $row['fs_x'],
'a_y' => $row['fs_y'],
'b_g' => $row['border_grey'],
'alt' => str_replace(['\\', '"', '\''], '', join(', ', [$row['f_name'], $row['c_name'], $row['a_name']])),
];
}
/**
* @throws Exception
*/
private function mapMaterial(array $collectionMaterials = []): array
{
$listMaterialCollection = [];
foreach ($collectionMaterials as $materialId) {
if (!empty($this->getMaterials()[$materialId])) {
$listMaterialCollection[] = $this->getMaterials()[$materialId];
}
}
return $listMaterialCollection;
}
/**
* @return array
* @throws Exception
*/
private function getMaterials(): array
{
if (count($this->materials) == 0) {
/** @var ListMaterialRepository $repoMaterialList */
$repoMaterialList = App::getRepository(ListMaterial::class);
$list = $repoMaterialList->getList(true);
/** @var ListMaterial $r */
foreach ($list as $r) {
$materials = App::trans('coll_preview_' . $r['alias']);
$position = strpos($materials, '_');
if ($position !== false) {
$materials = App::trans($r['alias']);
}
$this->materials[$r['id']] = $materials;
}
}
return $this->materials;
}
private function getPriceFields(string $currency, string $country, string $measure): array
{
if ($currency === 'EUR') {
switch ($country) {
case 'de':
return ['price_euro_de', 'price_mq_euro_de', 'pr_min_euro_de', 'a_price_cat_de', 'price_sort_de'];
case 'at':
return ['price_euro_at', 'price_mq_euro_at', 'pr_min_euro_at', 'a_price_cat_at', 'price_sort_at'];
case 'fi':
return ['price_euro_fi', 'price_mq_euro_fi', 'pr_min_euro_fi', 'a_price_cat_fi', 'price_sort_fi'];
case 'fr':
return ['price_euro_fr', 'price_mq_euro_fr', 'pr_min_euro_fr', 'a_price_cat_fr', 'price_sort_fr'];
case 'it':
return ['price_euro_it', 'price_mq_euro_it', 'pr_min_euro_it', 'a_price_cat_it', 'price_sort_it'];
case 'be':
return ['price_euro_be', 'price_mq_euro_be', 'pr_min_euro_be', 'a_price_cat_be', 'price_sort_be'];
case 'ie':
return ['price_euro_ie', 'price_mq_euro_ie', 'pr_min_euro_ie', 'a_price_cat_ie', 'price_sort_ie'];
case 'nl':
return ['price_euro_nl', 'price_mq_euro_nl', 'pr_min_euro_nl', 'a_price_cat_nl', 'price_sort_nl'];
case 'es':
return ['price_euro_es', 'price_mq_euro_es', 'pr_min_euro_es', 'a_price_cat_es', 'price_sort_es'];
case 'ru':
return ['price_rue', 'price_mq_rue', 'pr_min_rue', 'a_price_cat_rue', 'price_sort_rub'];
case 'gb':
return ['price_gbe', 'price_mq_gbe', 'pr_min_gbe', 'a_price_cat_gbe', 'price_sort_gbp'];
case 'ch':
return ['price_che', 'price_mq_che', 'pr_min_che', 'a_price_cat_che', 'price_sort_chf'];
case 'se':
return ['price_see', 'price_mq_see', 'pr_min_see', 'a_price_cat_see', 'price_sort_sek'];
case 'pl':
return ['price_ple', 'price_mq_ple', 'pr_min_ple', 'a_price_cat_ple', 'price_sort_pln'];
case 'us':
if ($measure === 'ft') {
return [
'price_fq_use',
'price_fq_use',
'pr_min_f_use',
'a_price_cat_fq_use',
'price_sort_fq_usd'
];
}
return ['price_use', 'price_mq_use', 'pr_min_use', 'a_price_cat_use', 'price_sort_usd'];
case 'ca':
if ($measure === 'ft') {
return ['price_cae', 'price_fq_cae', 'pr_min_cae', 'a_price_cat_fq_cae', 'price_sort_fq_cad'];
}
return ['price_cae', 'price_mq_cae', 'pr_min_cae', 'a_price_cat_cae', 'price_sort_cad'];
}
return ['price_euro', 'price_mq_euro', 'pr_min_euro', 'a_price_cat', 'price_sort'];
}
if ($country === 'ru' && $currency === 'RUB') {
return ['price_rub', 'price_mq_rub', 'pr_min_rub', 'a_price_cat_rub', 'price_sort_rub'];
}
if ($country === 'gb' && $currency === 'GBP') {
return ['price_gbp', 'price_mq_gbp', 'pr_min_gbp', 'a_price_cat_gbp', 'price_sort_gbp'];
}
if ($country === 'ch' && $currency === 'CHF') {
return ['price_chf', 'price_mq_chf', 'pr_min_chf', 'a_price_cat_chf', 'price_sort_chf'];
}
if ($country === 'se' && $currency === 'SEK') {
return ['price_sek', 'price_mq_sek', 'pr_min_sek', 'a_price_cat_sek', 'price_sort_sek'];
}
if ($country === 'dk' && $currency === 'DKK') {
return ['price_dkk', 'price_mq_dkk', 'pr_min_dkk', 'a_price_cat_dkk', 'price_sort_dkk'];
}
if ($country === 'no' && $currency === 'NOK') {
return ['price_nok', 'price_mq_nok', 'pr_min_nok', 'a_price_cat_nok', 'price_sort_nok'];
}
if ($country === 'pl' && $currency === 'PLN') {
return ['price_pln', 'price_mq_pln', 'pr_min_pln', 'a_price_cat_pln', 'price_sort_pln'];
}
if ($country === 'us' && $currency === 'USD') {
if ($measure === 'ft') {
return ['price_fq_usd', 'price_fq_usd', 'pr_min_f_usd', 'a_price_cat_fq_usd', 'price_sort_fq_usd'];
}
return ['price_usd', 'price_mq_usd', 'pr_min_usd', 'a_price_cat_usd', 'price_sort_usd'];
}
if ($country === 'ca' && $currency === 'CAD') {
if ($measure === 'ft') {
return ['price_cad', 'price_fq_cad', 'pr_min_cad', 'a_price_cat_fq_cad', 'price_sort_fq_cad'];
}
return ['price_cad', 'price_mq_cad', 'pr_min_cad', 'a_price_cat_cad', 'price_sort_cad'];
}
return ['price_euro', 'price_mq_euro', 'pr_min_euro', 'a_price_cat', 'price_sort'];
}
/**
* Ограничение на показ интерьеров
*
* @param array $searchFilter
* @param array $row
* @param array|null $oldTypeUsings
* @return bool
*/
private function getNoRestriction(array $searchFilter, array $row, ?array $oldTypeUsings): bool
{
$iTexture = explode(',', $row['i_texture']);
// В этой просьбе попросили исключить из ограничения фактуру по 17 кодом https://te.remote.team/#/discus/F4D2CA8B-BE66-7853-8FDC-2CFE011A151C/
$iTexture[] = 17;
//если поиск по группе и интерьер содержит текстуру подгруппы, то выведем как-бу-то это интерьер группы
if (
!empty($searchFilter['getFacturas'])
&& in_array(999, $searchFilter['getFacturas'])
&& in_array($iTexture, $this->subFilters)
) {
$iTexture[] = 999;
}
//внутри коллекции для интерьеров надо проверить, что привязаны заглавный артикулы
if (!empty($searchFilter['inside']) && empty($row['a_head'])) {
return true;
}
// ограничение на показ интерьера по признаку назначение
if (
!empty($oldTypeUsings)
&& (array_search(4, $oldTypeUsings)
&& !$row['i_wall_and_floor']
|| !in_array($row['i_type'], $oldTypeUsings)
)
) {
return false;
}
// ограничение на показ интерьера по признаку стиль
// внутри коллекции не используется это условие !!!!уже используется https://te2.remote.team/discus/C0B5DD6C-8487-9233-5238-08E2AF112A60?goto=true
// так же это ограничение не должно работать если стиль "ручная работа"
if (
isset($row['i_style'])
&& $row['i_style'] == 0
&& !empty($searchFilter['getStyles'])
&& !in_array(14, $searchFilter['getStyles'])
&& !in_array(14, [$row['a_style'], $row['styleida']])
) {
return false;
}
// если выбран фильтр монохром надо проверить, есть ли он у интерьера
if (
!empty($searchFilter['getColors'])
&& in_array(99, $searchFilter['getColors'])
&& !in_array(99, $iTexture)
) {
return false;
}
// ограничение на показ интерьеров при поиске по фактуре
if (
(
(empty($searchFilter['getTypes'])
|| !in_array($row['type'], $searchFilter['getTypes'])
)
&& (empty($searchFilter['getMaterials'])
|| !in_array(99, $searchFilter['getMaterials'])
|| $row['material'] != 99
)
)
&& empty($searchFilter['inside'])
) {
if (
!empty($searchFilter['getFacturas'])
&& count(array_intersect($iTexture, $searchFilter['getFacturas'])) == 0
) {
return true;
}
if (
!empty($searchFilter)
&& (!empty($searchFilter['getColors'])
|| !empty($searchFilter['getMaterials'])
|| !empty($searchFilter['getSurfaces'])
)
&& empty($row['type_filter'])
) { // ограничение подбора интерьеров по некоторым фильтрам
return false;
}
return true;
}
if (empty($searchFilter['getFacturas'])) {
return true;
}
if (count(array_intersect($iTexture, $searchFilter['getFacturas'])) > 0) {
return true;
}
return false;
}
/**
* @param array $collections
* @return array
*/
private function setIndexesForArticlesInCollections(array $collections): array
{
$n = 0; // для простановки индексов артикулов
foreach ($collections as &$collection) {
unset($collection['interiors']);
if (!empty($collection['articles'])) {
foreach ($collection['articles'] as &$item) {
$item['num'] = $n;
$n++;
}
}
}
return $collections;
}
//нужно узнать не сортирует ли человек случайно чтобы отсортировать за него
/**
* @return int
* @throws Exception
*/
public function getSearchSortId()
{
$sort = App::getSession()->get('sort_catalog_tmp');
if ($sort == null) {
$sort = App::getRequest()->get('sort');
}
if ($sort == null) {
$sort = App::getRequest()->cookies->get('sort_catalog');
}
if ($sort == null) {
$sort = 0;
}
return $sort;
}
}