src/WebBundle/Service/SphinxSearcherService.php line 1584

Open in your IDE?
  1. <?php
  2. namespace WebBundle\Service;
  3. use Doctrine\ORM\EntityManager;
  4. use Exception;
  5. use Symfony\Component\DependencyInjection\ContainerInterface;
  6. use Symfony\Component\Translation\Translator;
  7. use WebBundle\Entity\ListMaterial;
  8. use WebBundle\Entity\ListMeasure;
  9. use WebBundle\Helper\App;
  10. use WebBundle\Helper\CurrencyRateHelper;
  11. use WebBundle\Helper\HideFactoryCountriesHelper;
  12. use WebBundle\Helper\LocaleHelper;
  13. use WebBundle\Helper\StrHelper;
  14. use WebBundle\Repository\FilterRepository;
  15. use WebBundle\Repository\ListMaterialRepository;
  16. use WebBundle\Repository\ListMeasureRepository;
  17. class SphinxSearcherService
  18. {
  19.     private array $materials = [];
  20.     /** @required */
  21.     public ListMeasureRepository $listMeasureRepository;
  22.     /** @required */
  23.     public ListMaterialRepository $listMaterialRepository;
  24.     /** @var EntityManager */
  25.     private $em;
  26.     /** @var sphinxQLService $sphinxQL */
  27.     private $sphinxQL;
  28.     /** @var Translator $translator */
  29.     private $translator;
  30.     protected array $articlesId = [];
  31.     protected array $subFilters = [];
  32.     private FilterRepository $filterRepo;
  33.     /**
  34.      * @param ContainerInterface $container
  35.      * @param FilterRepository $filterRepository
  36.      * @throws Exception
  37.      */
  38.     public function __construct(ContainerInterface $containerFilterRepository $filterRepository)
  39.     {
  40.         $this->filterRepo $filterRepository;
  41.         $this->em $container->get('doctrine');
  42.         $this->sphinxQL $container->get('sphinx_ql');
  43.         $this->translator $container->get('translator');
  44.     }
  45.     /**
  46.      * @param ?array $data - данные для выборки
  47.      * @param ?int $limit - если 0 то вывести все (интерьеры!!!!!!!!!!)
  48.      * @param ?bool $withSchema - если true, то в поиске подбирать артикулы со схематичным изображением
  49.      * @param ?bool $full
  50.      * @param ?bool $getCount
  51.      * @param ?bool $onlyCID
  52.      * @param ?bool $NoWithArticles
  53.      * @return array
  54.      * @throws Exception
  55.      */
  56.     public function searchSphinx(
  57.         ?array $data = [],
  58.         ?int $limit 0,
  59.         ?bool $withSchema false,
  60.         ?bool $full false,
  61.         ?bool $getCount false,
  62.         ?bool $onlyCID false//для мантикоры
  63.         ?bool $NoWithArticles false //для мантикоры и для ускорения
  64.     ): array {
  65.         $this->sphinxQL->clear();
  66.         if ($getCount) {
  67.             ini_set('memory_limit''4048M');
  68.         } else {
  69.             ini_set('memory_limit''2048M');
  70.         }
  71. //App::debugExit($onlyCID,$NoWithArticles);
  72.         $dataReview = [];
  73.         $fields = [
  74. //from Articule
  75.             'a_id',
  76.             'is_main',
  77.             'a_name',
  78.             'process',
  79.             'a_style',
  80.             'file',
  81.             'fs_x',
  82.             'fs_y',
  83.             'border_grey',
  84.             'f_name',
  85.             'c_name',
  86.             'publish_date',
  87.             'country',
  88.             'country_code',
  89.             'type',
  90. //from collection
  91.             'coll',
  92.             'c_header',
  93.             'c_name',
  94.             'f_url',
  95.             'c_url',
  96.             'c_id',
  97.             'c_status',
  98.             'sliding',
  99.             'author',
  100.             'c_name',
  101.             'rating_month',
  102.             'c_header',
  103.             'c_release_year',
  104.             'c_url',
  105.             'f_name',
  106.             'f_id',
  107.             'f_url',
  108.             'c_material',
  109.             'prc_count',
  110.             'prc_vote',
  111.             'measure',
  112.             //from other
  113.             'attr_data',
  114.             'type_filter',
  115.             'c_exhibition',
  116.             'c_awards',
  117.             'c_designer_ids',
  118.             'c_accessible',
  119.             'c_express_sample',
  120.             'a_head'//для интерьера
  121.             'styleida',//для интерьера
  122.         ];
  123.         //поиск по этим фильтрам выводит интерьер по умолчанию
  124.         $allowedKeys = [
  125.             'expressSample',
  126.             'getAwards',
  127.             'reviews',
  128.             'getCountry',
  129.             'factory',
  130.             'c_id'
  131.         ];
  132.         $isValidFromMainInterior = empty(array_diff_key($data['searchFilter'], array_flip($allowedKeys)));
  133.         if (isset($data['searchFilter']['getTopMonth'])) {
  134.             $fields[] = 'c_pop30';
  135.             $fields[] = 'c_last_pop30';
  136.         } elseif (isset($data['searchFilter']['getTopWeek'])) {
  137.             $fields[] = 'c_pop7';
  138.             $fields[] = 'c_last_pop7';
  139.         }
  140.         $buildingMixtureOff false;
  141.         // тут костыль для скольжения https://te.remote.team/#/discus/7AF53097-7533-5034-0808-93CF8BDB1E75/
  142.         // Не бывает матовой поверхности с коэффициентом противоскольжения (если и бывает, то это просто ошибка в свойствах артикула)
  143.         // todo излишнее так как sliding= '999.a.sliding
  144.         if (
  145.             !empty($data['searchFilter']['getSurfaces'])
  146.             && !empty($data['searchFilter']['sliding'])
  147.             && count($data['searchFilter']['sliding']) == 4
  148.         ) {
  149.             $data['searchFilter']['getSurfaces'][] = 8;
  150.             unset($data['searchFilter']['sliding']);
  151.         }
  152.         // фильтр по антислипу sliding на самом деле getSurfaces
  153.         // todo лишнее
  154.         if (!empty($data['searchFilter']['sliding'])) {
  155.             foreach ($data['searchFilter']['sliding'] as $row) {
  156.                 $data['searchFilter']['getSurfaces'][] = (int)('999' $row);
  157.             }
  158.             unset($data['searchFilter']['sliding']);
  159.         }
  160.         // На основании вот этой просьбы https://te.remote.team/#/discus/4B853CC1-9B65-BD60-F896-352327BC5F2C/
  161.         if (!empty($data['searchFilter']['factory']) && count($data['searchFilter']) == 1) {
  162.             $withSchema true;
  163.         }
  164.         if (!App::isRole('ROLE_TEST')) {
  165.             $this->sphinxQL->addWhere('c_test_access != 1');
  166.             $this->sphinxQL->addWhere('f_test_access != 1');
  167.         }
  168.         if (!empty($data['HideFactory'])) {
  169.             $this->sphinxQL->addWhere('f_id NOT IN (?)'$data['HideFactory']);
  170.         } elseif (HideFactoryCountriesHelper::length() > 0) {
  171.             $this->sphinxQL->addWhere('f_id NOT IN (?)'HideFactoryCountriesHelper::codes());
  172.         }
  173.         $country App::getCurCountry();
  174.         $measure = !empty($data['measure']) ? $data['measure'] : LocaleHelper::getUserMeasure();
  175.         $priceFields $this->getPriceFields(LocaleHelper::getCur(), $country$measure);
  176.         // для автоматической простановки фильтров
  177.         $dataArticles = [
  178.             'getPrstatus' => 'pr_status'// код акции
  179.             'getTypes' => 'type'// код вида изделия
  180.             'getTypeUsings' => 'using'// код назначения
  181.             'getCountry' => 'country'// код страны
  182.             'getPrcateg' => 'pr_status'// код акции
  183.             'getMaterials' => 'material'// код материала
  184.             'getCostCategory' => $priceFields[3],//'a_price_cat', // код категории цены
  185.             'getEdgeType' => 'edge_type'// тип края
  186.             'offShade' => 'off_shade'// разнотон (моноколор)
  187.             'getStyles' => 'sid'// код стиля
  188.             'getSurfaces' => 'surface'// код типа
  189.             'getFacturas' => 'a_texture'// код фактуры
  190.             'getStone' => 'a_stone_texture'// код фактуры камня
  191.             //'getColors' => 'color', // код цветов
  192.             'shape' => 'shape'// код формы
  193.             'motive' => 'a_motive'// мотив рисунка
  194.             'motiv' => 'a_motiv'// мотив рисунка
  195.             'pei' => 'pei',
  196.             'exhibition' => 'c_exhibition',
  197.         ];
  198.         //Добавим поля интерьера первые найденный тогда сфинкс вернет сразу пустую строку и не нужно будет делать проверку и цикл
  199.         $interiorFilds = [
  200.             'attr_data.i[0].i_name as i_name',
  201.             'attr_data.i[0].i_id as i_id',
  202.             'attr_data.i[0].i_rating as i_rating',
  203.             'attr_data.i[0].i_monochrome as i_monochrome',
  204.             'attr_data.i[0].i_status as i_status',
  205.             'attr_data.i[0].i_file as i_file',
  206.             'attr_data.i[0].i_wall_and_floor as i_wall_and_floor',
  207.             'attr_data.i[0].i_style as i_style',
  208.             'attr_data.i[0].i_texture as i_texture',
  209.             'attr_data.i[0].fsi_x as fsi_x',
  210.             'attr_data.i[0].fsi_y as fsi_y',
  211.         ];
  212.         //поля которые перенесены в attr_data что позволило сократить таблицу до артикулов проверить
  213.         $mvaFields = [
  214.             'color',
  215.             'material',
  216.             'a_motive',
  217.             'a_texture',
  218.             'designer',
  219.             'edge_type',
  220.             'a_motiv',
  221.             'shape',
  222.             'shape_module',
  223.             'a_stone_texture',
  224.             'style',
  225.             'surface',
  226.             'texture',
  227.             'a_head',
  228.             'sid',
  229.             'styleida',
  230.             'styleid',
  231.             'sort',
  232.             'i_style',
  233.             'c_apply',
  234.             'apply_id',
  235.             'typecoll',
  236.             'i_rating',
  237.             'i_id',
  238.             'is_head',
  239.             'fsi_x',
  240.             'fsi_y',
  241.             'i_name_hash',
  242.             'i_file_hash',
  243.             'i_type',
  244.             'i_status',
  245.             'i_texture',
  246.             'i_monochrome',
  247.             'i_wall_and_floor',
  248.             'using',
  249.             'type',
  250.             'c_exhibition',
  251.         ];
  252.         //вычитаем поля если они attr_data добавляются через $dataAttrFields
  253.         // $plusFields = array_diff($plusFields, $attrData);
  254.         if (!$getCount) {
  255.             $fields array_unique(array_merge($interiorFilds$fields$priceFields));
  256.         } else {
  257.             if ($getCount) {
  258.                 $fieldsGetCount = [
  259.                     'coll',
  260.                     'sid',
  261.                     'surface',
  262.                     'material',
  263.                     'a_texture',
  264.                     'a_stone_texture',
  265.                     'color',
  266.                     'shape',
  267.                     'a_motive',
  268.                     'a_motiv',
  269.                     'typecoll',
  270.                     'c_express_sample',
  271.                     'c_awards',
  272.                     'c_exhibition',
  273.                     'size_x',
  274.                     'size_y',
  275.                     'tolsch',
  276.                     'using',
  277.                     'factory',
  278.                     'u_id',
  279.                     'c_id',
  280.                     'thin_granite',
  281.                     'size_big',
  282.                     'glazed_granite',
  283.                     'thick_granite',
  284.                     'publish_period',
  285.                     'c_release_year',
  286.                     'reviews',
  287.                     'dyed_in_mass',
  288.                     'apply_id',
  289.                     'c_designer_ids',
  290.                     'monochrome',
  291.                     'pr_status',
  292.                     'type',
  293.                     'country',
  294.                     'edge_type',
  295.                     'off_shade',
  296.                     $priceFields[3] . ' as a_price_cat'
  297.                 ];
  298.                 $fields array_merge($fieldsGetCount);
  299.             }
  300.         }
  301. //        App::debugExit($fields);
  302.         if (empty($data['total_found'])) {
  303.             $this->sphinxQL->setFrom('article'$fields);
  304.         } else {
  305.             $this->sphinxQL->setFrom('article''coll'); //todo тут должна появиться новая таблица
  306.         }
  307.         $this->sphinxQL->addWhere('delivery_suspended <> 1');
  308.         if (!empty($data['searchFilter']['inside'])) {
  309.             $this->sphinxQL->addWhere($priceFields[0] . ' > 0.0');
  310.             $this->sphinxQL->addWhere('delivery <> 6');
  311.         } elseif (!empty($data['searchFilter']['discontinued'])) {
  312.             $this->sphinxQL->addWhere('ANY(typeColl) in (2) ');
  313.         } else {
  314.             //http://te2.remote.team/discus/42C71507-B112-C241-1D70-BB99E3BD2278?goto=true
  315.             //Снятая с производства коллекция не убирается из рекламы
  316.             // а при чем здесь выдача?
  317.             // if (!empty($data['ads'])) {
  318.             $this->sphinxQL->addWhere('ANY(typeColl) in (1)');
  319.             //  }
  320.             if (!(!empty($data['searchFilter']['factory']) && count($data['searchFilter']) == 1)) {
  321.                 $this->sphinxQL->addWhere($priceFields[0] . ' > 0.0');
  322.                 $this->sphinxQL->addWhere('c_status = 1');
  323.             } else {
  324.                 $this->sphinxQL->addWhere('c_status IN (1, 3)');
  325.             }
  326.         }
  327.         // принято решение, если выбран стиль, то отбираем сразу по фонам декорам панно
  328.         // https://te.remote.team/#/discus/85E0842C-BCDE-D6E6-7EA4-2DB50BB404EC/
  329.         if (
  330.             !empty($data['searchFilter']['getStyles']) &&
  331.             empty($data['searchFilter']['getTypes']) &&
  332.             empty($data['searchFilter']['inside'])
  333.         ) {
  334.             $data['searchFilter']['getTypes'] = [111310624122128]; //todo нужно перенести в индекс
  335.         }
  336.         $this->sphinxQL->addWhere('scheme = ?'0);
  337.         // ставим фильтры
  338.         //переносим 3Д в И
  339.         if (
  340.             !empty($data['searchFilter']['getSurfaces'])
  341.             && in_array(12$data['searchFilter']['getSurfaces'])
  342.         ) {
  343.             $this->sphinxQL->addWhere('ANY(surface) = ?'12);
  344.             $data['searchFilter']['getSurfaces'] = array_diff($data['searchFilter']['getSurfaces'], [12]);
  345.             if (!empty($data['searchFilter']['getSurfaces'])) {
  346.                 $this->sphinxQL->addWhere('ANY(surface) in(?)'$data['searchFilter']['getSurfaces']);
  347.             } else {
  348.                 unset($data['searchFilter']['getSurfaces']);
  349.                 $data['searchFilter']['getSurfaces_old'] = 1;
  350.             }
  351.         }
  352.         if (!empty($data['searchFilter'])) {
  353.             if (!empty($data['searchFilter']['expressSample'])) {
  354.                 if (
  355.                     !empty($data['searchFilter']['inside']) ||
  356.                     count($data['searchFilter']) > && empty($data['searchFilter']['factory']) ||
  357.                     count($data['searchFilter']) > && !empty($data['searchFilter']['factory'])
  358.                 ) {
  359.                     $this->sphinxQL->addWhere("express_sample = 1");
  360.                 } else {
  361.                     $this->sphinxQL->addWhere("c_express_sample = 1");
  362.                 }
  363.             }
  364.             // если getAwards, то просто проверяем наличие наград и все, без уточнений
  365.             if (!empty($data['searchFilter']['getAwards'])) {
  366.                 $this->sphinxQL->addWhere("c_awards != '' ");
  367.             }
  368.             // отдельно фильтр для дизайнеров, с заготовкой под ID
  369.             if (!empty($data['searchFilter']['getDesigner'])) {
  370.                 // 1 имя, 0 это Id
  371.                 $designerName '';
  372.                 $designerId $data['searchFilter']['getDesigner'][0];
  373.                 // поставил LIKE поиск по имени дизайнера + поиск по ID
  374.                // $this->sphinxQL->addWhere('ANY(c_designer_ids) IN (?)', $designerId); only manticore
  375.                 $this->sphinxQL->addWhere("MATCH('(@c_designer_ids \"[$designerId]\") {$designerName}')");
  376.                 unset($data['searchFilter']['getDesigner']);
  377.                 $data['searchFilter']['getDesigner_old'] = 1;
  378.             }
  379.             if (!empty($data['searchFilter']['size_x'])) {
  380.                 $this->sphinxQL->addWhere(
  381.                     'size_x >= ?',
  382.                     str_replace(',''.'$data['searchFilter']['size_x'][0] * 100)
  383.                 );
  384.                 $buildingMixtureOff true;
  385.             }
  386.             if (!empty($data['searchFilter']['size_y'])) {
  387.                 $this->sphinxQL->addWhere(
  388.                     'size_y >= ?',
  389.                     str_replace(',''.'$data['searchFilter']['size_y'][0] * 100)
  390.                 );
  391.                 $buildingMixtureOff true;
  392.             }
  393.             if (!empty($data['searchFilter']['tolsch'])) {
  394.                 $this->sphinxQL->addWhere(
  395.                     'tolsch >= ?',
  396.                     str_replace(',''.'$data['searchFilter']['tolsch'][0] * 100)
  397.                 );
  398.                 $buildingMixtureOff true;
  399.             }
  400.             if (!empty($data['searchFilter']['size_x2'])) {
  401.                 $this->sphinxQL->addWhere(
  402.                     'size_x <= ?',
  403.                     str_replace(',''.'$data['searchFilter']['size_x2'][0] * 100)
  404.                 );
  405.                 if (empty($data['searchFilter']['size_x'])) {
  406.                     $this->sphinxQL->addWhere('size_x > ?'0);
  407.                 }
  408.                 $buildingMixtureOff true;
  409.             }
  410.             if (!empty($data['searchFilter']['size_y2'])) {
  411.                 $this->sphinxQL->addWhere(
  412.                     'size_y <= ?',
  413.                     str_replace(',''.'$data['searchFilter']['size_y2'][0] * 100)
  414.                 );
  415.                 if (empty($data['searchFilter']['size_y'])) {
  416.                     $this->sphinxQL->addWhere('size_y > ?'0);
  417.                 }
  418.                 $buildingMixtureOff true;
  419.             }
  420.             if (!empty($data['searchFilter']['tolsch2'])) {
  421.                 $this->sphinxQL->addWhere(
  422.                     'tolsch <= ?',
  423.                     str_replace(',''.'$data['searchFilter']['tolsch2'][0] * 100)
  424.                 );
  425.                 if (empty($data['searchFilter']['tolsch'])) {
  426.                     $this->sphinxQL->addWhere('tolsch > ?'0);
  427.                 }
  428.                 $buildingMixtureOff true;
  429.             }
  430.             // специально для приложений
  431.             if (!empty($data['searchFilter']['prMinFrom'])) {
  432.                 $this->sphinxQL->addWhere(
  433.                     'pr_min <= ?',
  434.                     str_replace(',''.'$data['searchFilter']['prMinFrom'][0] * 100)
  435.                 );
  436.             }
  437.             if (!empty($data['searchFilter']['prMinTo'])) {
  438.                 $this->sphinxQL->addWhere(
  439.                     'pr_min >= ?',
  440.                     str_replace(',''.'$data['searchFilter']['prMinTo'][0] * 100)
  441.                 );
  442.             }
  443.             if (!empty($data['searchFilter']['shape'])) {
  444.                 // Если в фильтре есть модуль (shape = 10)
  445.                 if (in_array(10$data['searchFilter']['shape'])) {
  446.                     // Ищем по формам модулей (shape_module содержит формы модулей)
  447.                     $shape $data['searchFilter']['shape'];
  448.                     unset($shape[array_search(10$shape)]);
  449.                     if (!empty($shape)) {
  450.                         // Если есть другие формы, ищем их в формах модулей
  451.                         $this->sphinxQL->addWhere('ANY(shape_module) in (?)'$shape);
  452.                     } else {
  453.                         // Если выбрана только форма 10 (модуль), показываем все модули
  454.                         // shape_module не пустое означает что это модуль (любое значение > 0)
  455.                         $this->sphinxQL->addWhere('ANY(shape_module) > 0');
  456.                     }
  457.                 } else {
  458.                     // Если модуль не выбран, ищем по обычным формам (shape, исключая модули)
  459.                     // Исключаем модули: shape не должен содержать 10
  460.                     $this->sphinxQL->addWhere('ALL(shape) not in (?)'10);
  461.                     // Показываем только выбранные формы (квадрат, прямоугольник, неопределенная и т.д.)
  462.                     $this->sphinxQL->addWhere('ANY(shape) in (?)'$data['searchFilter']['shape']);
  463.                     $dataArticles['shape'] = 'shape'// код цветов
  464.                 }
  465.             }
  466.             if (!empty($data['searchFilter']['getColors']) && in_array(99$data['searchFilter']['getColors'])) {
  467.                 $this->sphinxQL->addWhere('ANY(color) in (?)'99);
  468.                 $colors $data['searchFilter']['getColors'];
  469.                 unset($colors[array_search(99$colors)]);
  470.                 if (!empty($colors)) {
  471.                     $this->sphinxQL->addWhere('ANY(color) in (?)'$colors);
  472.                 }
  473.             } else {
  474.                 $dataArticles['getColors'] = 'color'// код цветов
  475.             }
  476.             // если есть фильтры, то добавляем их к запросу
  477.             foreach ($data['searchFilter'] as $key => $row) {
  478.                 if (!empty($dataArticles[$key])) {
  479.                     // отключаем фильтр getPrcateg и ориентируемся на баланс
  480.                     if (trim($key) == 'getPrcateg') {
  481.                         continue;
  482.                     }
  483.                     //тут проставим $mvaFields чтобы искать в MVA any|all
  484.                     if (in_array($dataArticles[$key], $mvaFields)) {
  485.                         $dataArticles[$key] = ' ANY(' $dataArticles[$key] . ')';
  486.                     }
  487.                     $this->sphinxQL->addWhere($dataArticles[$key] . ' IN (?)'$row);
  488.                 }
  489.             }
  490.             // фильтр окрашен в массе
  491.             if (!empty($data['searchFilter']['dyedInMass'])) {
  492.                 $this->sphinxQL->addWhere('dyed_in_mass = 1');
  493.             }
  494.             // !!! теперь если выбран фильтр применения показываем только интерьеры
  495.             // для применения работает немного иначе если более одного признака то идёт наследование от коллекции,
  496.             // но при этом надо не показывать интерьеры, которые не соответствуют применению
  497.             if (!empty($data['searchFilter']['getUsings'])) {
  498.                 if (!empty($data['searchFilter']['getUsings'])) {
  499.                     // вернул выборку по ID иначе показывает все из "применения" без фильтрации.
  500.                     $this->sphinxQL->addWhere('ANY(apply_id) IN (?)'$data['searchFilter']['getUsings']);
  501.                 }
  502.                 $this->sphinxQL->addWhere('c_accessible <> 1');
  503.             }
  504.             // фильтр по фабрике
  505.             if (!empty($data['searchFilter']['factory'])) {
  506.                 $this->sphinxQL->addWhere('factory = \'' $data['searchFilter']['factory'][0] . '\'');
  507.             }
  508.             // фильтр по фабрике
  509.             if (!empty($data['searchFilter']['bm'])) {
  510.                 $bmId $data['searchFilter']['bm'];
  511.                 $bmId is_array($bmId) ? $bmId[0] : $bmId;
  512.                 $this->sphinxQL->addWhere('u_id = ' $bmId);
  513.             }
  514.             // фильтр по id коллекций
  515.             if (!empty($data['searchFilter']['c_id'])) {
  516.                 $this->sphinxQL->addWhere('c_id IN (?)'$data['searchFilter']['c_id']);
  517.                 unset($data['searchFilter']['c_id']);
  518.             }
  519.         }
  520.         // тонкий керамогранит
  521.         if (!empty($data['searchFilter']['getThinGranite'])) {
  522.             $this->sphinxQL->addWhere('thin_granite = ?'1);
  523.             $buildingMixtureOff true;
  524.         }
  525.         // фильтр большого размера плитки
  526.         if (!empty($data['searchFilter']['size_big'])) {
  527.             $this->sphinxQL->addWhere('size_big = ?'1);
  528.             $buildingMixtureOff true;
  529.         }
  530.         // глазурированный/неглазурированный керамогранит
  531.         if (!empty($data['searchFilter']['getGlazedGranit'])) {
  532.             $this->sphinxQL->addWhere('glazed_granite = ?'$data['searchFilter']['getGlazedGranit']);
  533.         }
  534.         if ($country == 'ru' || $buildingMixtureOff) {
  535.             $this->sphinxQL->addWhere('c_id != ?'3245628);
  536.         }
  537.         // утолщенный керамогранит
  538.         if (!empty($data['searchFilter']['getThickGranite'])) {
  539.             $this->sphinxQL->addWhere('thick_granite = ?'$data['searchFilter']['getThickGranite']);
  540.         }
  541.         // Если новинки, то выводим только коллекции за месяц
  542.         //Семраш пишет не может сканировать страницу новинок
  543.         //https://te2.remote.team/discus/35DEFA01-C136-0EA2-DB72-E8999812EBFC
  544.         if (isset($data['searchFilter']['getTop'])) {
  545.             $this->sphinxQL->addWhere('ANY(publish_period) = ?'4);
  546.         }
  547.         // выборки за период
  548.         if (isset($data['searchPeriod'])) {
  549.             $this->sphinxQL->addWhere('ANY(publish_period) = ?'$data['searchPeriod']);
  550.         }
  551.         $dateSort 'publish_date DESC';
  552.         // фильтрация по году выпуска
  553.         if (!empty($data['searchFilter']['releaseYear'])) {
  554.             $years = [];
  555.             foreach ($data['searchFilter']['releaseYear'] as $year) {
  556.                 if (strlen($year) > 4) {
  557.                     $y substr($year04);
  558.                     do {
  559.                         $y--;
  560.                         $years[] = $y;
  561.                     } while ($y 2013);
  562.                 } elseif ($year == 999) {
  563.                     $years[] = date('Y');
  564.                 } else {
  565.                     $years[] = $year;
  566.                 }
  567.             }
  568.             if (count($years) > 0) {
  569.                 $this->sphinxQL->addWhere('c_release_year IN (?)'$years);
  570.             }
  571.         }
  572.         // фильтрация по средней оценке отзывов
  573.         if (!empty($data['searchFilter']['reviews'])) {
  574.             $this->sphinxQL->addWhere('reviews IN (?)'$data['searchFilter']['reviews']);
  575.             if ($this->getSearchSortId() == 0) {
  576.                 $data['searchSort'] = 6;
  577.             }
  578.         }
  579.         // учитываем сортировку в запросе
  580. //        App::debugExit($data);
  581.         if (isset($data['searchFilter']['getTopMonth'])) {
  582.             $searchSort 'c_pop30 DESC';
  583.         } elseif (isset($data['searchFilter']['getTopWeek'])) {
  584.             $searchSort 'c_pop7 DESC';
  585.         } else {
  586.             $searchSort 'rating DESC';
  587.         }
  588.         if (!empty($data['searchFilter']['getCostCategory']) && $this->getSearchSortId() == 0) {
  589.             $searchSort 'price_sort ASC';
  590.         }
  591.         if (!empty($data['searchFilter'][''])) {
  592.             unset($data['searchFilter']['']);
  593.         }
  594.         // определяем тип минимальной цены
  595.         $minTypeAll false;
  596.         if (
  597.             (count($data['searchFilter']) == || !empty($data['searchFilter']['factory'])
  598.                 && count($data['searchFilter']) == 1) && !$getCount
  599.         ) {
  600.             $minTypeAll true;
  601.             // Если нет фильтров ищем только по фонам мозаике декору
  602.             // Ага, а если ищем зеленный, то выводим красный :)
  603.             //   $this->sphinxQL->addWhere('ANY(type) IN (?)', [1, 24, 113, 122, 27, 106, 64, 128, 0]);
  604.         }
  605.         // https://te.remote.team/#/discus/BDBD8973-1F54-3B16-99ED-8656AEFC1105/
  606.         // убрал совсем сортировку по полю price_euro
  607.         if (
  608.             !empty($data['searchFilter']['getTypes']) && !array_intersect(
  609.                 (array)$data['searchFilter']['getTypes'],
  610.                 [124113122106]
  611.             )
  612.         ) {
  613.             $sort 'price_sort ASC';
  614.         } else {
  615.             $sort $priceFields[4] . ' ASC';
  616.         }
  617.         $searchSortLimit false;
  618.         if (!empty($data['searchSort'])) {
  619.             switch ($data['searchSort']) {
  620.                 case 1:
  621.                     $searchSort 'c_pop7 DESC';
  622.                     break;
  623.                 case 2:
  624.                     // по цене
  625.                     $searchSort false;
  626.                     break;
  627.                 case 3:
  628.                     // по дате
  629.                     $searchSort 'publish_date DESC';
  630.                     break;
  631.                 case 4:
  632.                     // по алфавиту
  633.                     $searchSort 'c_name ASC';
  634.                     break;
  635.                 case 5:
  636.                     // по популярности за месяц
  637.                     $searchSort 'c_pop30 DESC';
  638.                     break;
  639.                 case 6:
  640.                     // по отзывам
  641.                     $searchSort 'prc_star DESC';
  642.                     $searchSortLimit 'prc_count DESC';
  643.                     break;
  644.             }
  645.         }
  646.         if (empty($data['total_found'])) {
  647.             if ($searchSort) {
  648.                 $this->sphinxQL->setOrder($searchSort);
  649.             }
  650.             if ($searchSortLimit) {
  651.                 $this->sphinxQL->setOrder($searchSortLimit);
  652.             }
  653.                 $this->sphinxQL->setOrder('sort DESC');
  654.             $this->sphinxQL
  655.                 ->setOrder($sort//цена в приоритете она создает коллекцию и минимальную ее цену
  656.                 ->setOrder('max_is_head DESC'); //сортирует только по строкам max_is_head"
  657.             if (!$searchSortLimit) {
  658.                 $this->sphinxQL->setOrder($dateSort);
  659.             }
  660.         }
  661.         if (!empty($data['total_found'])) {
  662.             $this->sphinxQL->setLimit(1)
  663.                 ->setGroup('coll');
  664.             $rows $this->sphinxQL->getQuery()->fetchAllAssociative();
  665.             $totalFound $this->sphinxQL->getTotalFound();
  666.             return ['total_found' => $totalFound];
  667.         }
  668.         if (!empty($data['only_c_id'])) {
  669.             $this->sphinxQL->setLimit(200000)
  670.                 ->setGroup('c_id');
  671.             $rows $this->sphinxQL->getQuery()->fetchAllAssociative();
  672.             return  $rows;
  673.         }
  674.         $this->subFilters $this->filterRepo->getFiltersSubRelation(false);
  675.         if (empty($data['limit'])) {
  676.             $this->sphinxQL->setLimit(SphinxQLService::MAX_MATCHES);
  677.             if (empty($data['searchFilter']['inside'])) {
  678.                 $this->sphinxQL->setGroup('a_id');//, i_id, sid, styleid, styleida
  679.             }
  680.         } else {
  681.             $this->sphinxQL->setLimit($data['limit'])
  682.                 ->setGroup('coll');
  683.         }
  684.         if (!empty($data['real'])) {
  685.             $this->sphinxQL->setOption('max_matches=200000');
  686.             $this->sphinxQL->setLimit(200000);
  687.         }
  688.         $ed = [];
  689.         $listMeasure $this->em->getRepository('WebBundle:ListMeasure')->findBy(['hide' => false]);
  690.         /** @var ListMeasure $row */
  691.         foreach ($listMeasure as $row) {
  692.             $ed[$row->getId()] = $row->getAlias() != null
  693.                 $this->translator->trans($row->getAlias())
  694.                 : $row->getName();
  695.         }
  696.         //дополнительные свойства
  697.         $collections = ['i_names' => [], 'a_names' => []];
  698.         $num 0;
  699.         if ($getCount) {
  700. //            $client = HttpClient::create();
  701. //            $response = $client->request('POST', 'http://go-service:8080/process', [
  702. //                'json' => ['text' => 'hello world1', 'query'=> $this->sphinxQL->getSql()],
  703. //            ]);
  704. //
  705. //            $calculate = $response->toArray();
  706.             $calculate = [];
  707. //            //Создаем привязку фильтра к нашим полям для подсчета
  708.             $aFiltersOnlyNoChilds $this->filterRepo->getListForSynchCountFilters([]);
  709.             $realFilterProperty = [];
  710.             $newFiltersOnlyNoChild = [];
  711.             foreach ($aFiltersOnlyNoChilds as $fVal) {
  712.                 $fRealId $fVal['oldCommand'] == 'getDesigner' $fVal['id'] : $fVal['oldId'];
  713.                 $realFilterProperty[$fVal['oldCommand']] [$fRealId] = $fVal;
  714.                 $realFilterProperty[$fVal['oldCommand']] [$fRealId] ['oldId'] = $fRealId;
  715.                 $realFilterProperty[$fVal['oldCommand']] [$fRealId] ['count'] = 0;
  716.                 $realFilterProperty[$fVal['oldCommand']] [$fRealId] ['coll_array'] = []; //добавляем массив колеккций дабы отсекать у родителей дубли
  717.                 $newFiltersOnlyNoChild[$fVal['id']] = $fVal;
  718.                 $newFiltersOnlyNoChild[$fVal['id']]['coll_array'] = [];
  719.             }
  720.             $rows $this->sphinxQL->getQuery()->fetchAllAssociative();
  721.             foreach ($rows as $row) {
  722.                 if ($getCount) {
  723.                     if (!empty($row['c_exhibition']) && $exhibitionDate json_decode($row['c_exhibition'], true)) {
  724.                         $row['c_exhibition'] = $exhibitionDate;
  725.                     } else {
  726.                         $row['c_exhibition'] = [];
  727.                     }
  728.                     if (
  729.                         !empty($row['c_designer_ids']) && $c_designer_idsDate json_decode(
  730.                             $row['c_designer_ids'],
  731.                             true
  732.                         )
  733.                     ) {
  734.                         $row['c_designer_ids'] = $c_designer_idsDate;
  735.                     } else {
  736.                         $row['c_designer_ids'] = [];
  737.                     }
  738.                     if (empty($calculate[$row['coll']])) {
  739.                         //todo по факту эти поля нужно будет собрать из индекса который будет колеккцией пока у меня article2
  740.                         $calculate[$row['coll']] = [
  741.                             'getStyles' => [],
  742.                             'getSurfaces' => [],
  743.                             'getFacturas' => [],
  744.                             'getMaterials' => [],
  745.                             'getStone' => [],
  746.                             'getColors' => [],
  747.                             'shape' => [],
  748.                             'motive' => [],
  749.                             'motiv' => [],
  750.                             'discontinued' => [],
  751.                             'expressSample' => [],
  752.                             'getAwards' => [],
  753.                             'exhibition' => [],
  754.                             'size_x' => [],
  755.                             'size_y' => [],
  756.                             'tolsch' => [],
  757.                             'material' => [],
  758.                             'getTypeUsings' => [],
  759.                             'factory' => [],
  760.                             'bm' => [],
  761.                             'c_id' => [],
  762.                             'getThinGranite' => [],
  763.                             'size_big' => [],
  764.                             'getGlazedGranit' => [],
  765.                             'getThickGranite' => [],
  766.                             'searchPeriod' => [],
  767.                             'releaseYear' => [],
  768.                             'reviews' => [],
  769.                             'dyedInMass' => [],
  770.                             'colorBody' => [],
  771.                             'getUsings' => [],
  772.                             'getDesigner' => [],
  773.                             'monochrome' => [],
  774.                             'getPrcateg' => [],
  775.                             'getTypes' => [],
  776.                             'getCountry' => [],
  777.                             'a_price_cat' => [],
  778.                             'getEdgeType' => [],
  779.                             'offShade' => [],
  780.                             'getCostCategory' => [],
  781.                         ];
  782.                     }
  783.                     //пробуем просто собрать данные;
  784.                     $calculate[$row['coll']]['getCostCategory'] = array_merge(
  785.                         $calculate[$row['coll']]['getCostCategory'],
  786.                         [$row['a_price_cat']]
  787.                     );
  788.                     $calculate[$row['coll']]['getStyles'] = array_merge(
  789.                         $calculate[$row['coll']]['getStyles'],
  790.                         explode(','$row['sid'])
  791.                     );
  792.                     $calculate[$row['coll']]['getSurfaces'] = array_merge(
  793.                         $calculate[$row['coll']]['getSurfaces'],
  794.                         explode(','$row['surface'])
  795.                     );
  796.                     $calculate[$row['coll']]['getMaterials'] = array_merge(
  797.                         $calculate[$row['coll']]['getMaterials'],
  798.                         explode(','$row['material'])
  799.                     );
  800.                     $calculate[$row['coll']]['getFacturas'] = array_merge(
  801.                         $calculate[$row['coll']]['getFacturas'],
  802.                         explode(','$row['a_texture'])
  803.                     );
  804.                     $calculate[$row['coll']]['getStone'] = array_merge(
  805.                         $calculate[$row['coll']]['getStone'],
  806.                         explode(','$row['a_stone_texture'])
  807.                     );
  808.                     $calculate[$row['coll']]['getColors'] = array_merge(
  809.                         $calculate[$row['coll']]['getColors'],
  810.                         explode(','$row['color'])
  811.                     );
  812.                     $calculate[$row['coll']]['shape'] = array_merge(
  813.                         $calculate[$row['coll']]['shape'],
  814.                         explode(','$row['shape'])
  815.                     );
  816.                     $calculate[$row['coll']]['motive'] = array_merge(
  817.                         $calculate[$row['coll']]['motive'],
  818.                         explode(','$row['a_motive'])
  819.                     );
  820.                     $calculate[$row['coll']]['motiv'] = array_merge(
  821.                         $calculate[$row['coll']]['motiv'],
  822.                         explode(','$row['a_motiv'])
  823.                     );
  824.                     $calculate[$row['coll']]['discontinued'] = array_merge(
  825.                         $calculate[$row['coll']]['discontinued'],
  826.                         explode(','$row['typecoll'])
  827.                     );
  828.                     $calculate[$row['coll']]['expressSample'] = array_merge(
  829.                         $calculate[$row['coll']]['expressSample'],
  830.                         [$row['c_express_sample']]
  831.                     );
  832.                     $calculate[$row['coll']]['getAwards'] = array_merge(
  833.                         $calculate[$row['coll']]['getAwards'],
  834.                         [!empty($row['c_awards']) ? 2]
  835.                     );
  836.                     $calculate[$row['coll']]['exhibition'] = array_merge(
  837.                         $calculate[$row['coll']]['exhibition'],
  838.                         $row['c_exhibition']
  839.                     );
  840.                     $calculate[$row['coll']]['size_x'] = array_merge(
  841.                         $calculate[$row['coll']]['size_x'],
  842.                         [$row['size_x']]
  843.                     );
  844.                     $calculate[$row['coll']]['size_y'] = array_merge(
  845.                         $calculate[$row['coll']]['size_y'],
  846.                         [$row['size_y']]
  847.                     );
  848.                     $calculate[$row['coll']]['tolsch'] = array_merge(
  849.                         $calculate[$row['coll']]['tolsch'],
  850.                         [$row['tolsch']]
  851.                     );
  852.                     $calculate[$row['coll']]['material'] = array_merge(
  853.                         $calculate[$row['coll']]['material'],
  854.                         explode(','$row['material'])
  855.                     );
  856.                     $calculate[$row['coll']]['getTypeUsings'] = array_merge(
  857.                         $calculate[$row['coll']]['getTypeUsings'],
  858.                         explode(','$row['using'])
  859.                     );
  860.                     $calculate[$row['coll']]['factory'] = array_merge(
  861.                         $calculate[$row['coll']]['factory'],
  862.                         [$row['factory']]
  863.                     );
  864.                     $calculate[$row['coll']]['bm'] = array_merge($calculate[$row['coll']]['bm'], [$row['u_id']]);
  865.                     $calculate[$row['coll']]['c_id'] = array_merge($calculate[$row['coll']]['c_id'], [$row['c_id']]);
  866.                     $calculate[$row['coll']]['getThinGranite'] = array_merge(
  867.                         $calculate[$row['coll']]['getThinGranite'],
  868.                         [$row['thin_granite']]
  869.                     );
  870.                     $calculate[$row['coll']]['size_big'] = array_merge(
  871.                         $calculate[$row['coll']]['size_big'],
  872.                         [$row['size_big']]
  873.                     );
  874.                     $calculate[$row['coll']]['getGlazedGranit'] = array_merge(
  875.                         $calculate[$row['coll']]['getGlazedGranit'],
  876.                         [$row['glazed_granite']]
  877.                     );
  878.                     $calculate[$row['coll']]['getThickGranite'] = array_merge(
  879.                         $calculate[$row['coll']]['getThickGranite'],
  880.                         [$row['thick_granite']]
  881.                     );
  882.                     $calculate[$row['coll']]['searchPeriod'] = array_merge(
  883.                         $calculate[$row['coll']]['searchPeriod'],
  884.                         [$row['publish_period']]
  885.                     );
  886.                     $calculate[$row['coll']]['releaseYear'] = array_merge(
  887.                         $calculate[$row['coll']]['releaseYear'],
  888.                         [$row['c_release_year']]
  889.                     );
  890.                     $calculate[$row['coll']]['reviews'] = array_merge(
  891.                         $calculate[$row['coll']]['reviews'],
  892.                         explode(','$row['reviews'])
  893.                     );
  894.                     $calculate[$row['coll']]['dyedInMass'] = array_merge(
  895.                         $calculate[$row['coll']]['dyedInMass'],
  896.                         [$row['dyed_in_mass']]
  897.                     );
  898.                     $calculate[$row['coll']]['getUsings'] = array_merge(
  899.                         $calculate[$row['coll']]['getUsings'],
  900.                         explode(','$row['apply_id'])
  901.                     );
  902.                     $calculate[$row['coll']]['getDesigner'] = array_merge(
  903.                         $calculate[$row['coll']]['getDesigner'],
  904.                         $row['c_designer_ids']
  905.                     );
  906.                     $calculate[$row['coll']]['monochrome'] = array_merge(
  907.                         $calculate[$row['coll']]['monochrome'],
  908.                         explode(','$row['monochrome'])
  909.                     );
  910.                     $calculate[$row['coll']]['getPrcateg'] = array_merge(
  911.                         $calculate[$row['coll']]['getPrcateg'],
  912.                         [$row['pr_status']]
  913.                     );
  914.                     $calculate[$row['coll']]['getTypes'] = array_merge(
  915.                         $calculate[$row['coll']]['getTypes'],
  916.                         explode(','$row['type'])
  917.                     );
  918.                     $calculate[$row['coll']]['getCountry'] = array_merge(
  919.                         $calculate[$row['coll']]['getCountry'],
  920.                         [$row['country']]
  921.                     );
  922.                     $calculate[$row['coll']]['getEdgeType'] = array_merge(
  923.                         $calculate[$row['coll']]['getEdgeType'],
  924.                         explode(','$row['edge_type'])
  925.                     );
  926.                     $calculate[$row['coll']]['offShade'] = array_merge(
  927.                         $calculate[$row['coll']]['offShade'],
  928.                         [$row['off_shade']]
  929.                     );
  930.                     //
  931.                     //включаем если запрашивали
  932.                 }
  933.             }
  934.         } else {
  935.             $rows $this->sphinxQL->getQuery()->fetchAllAssociative();
  936.             foreach ($rows as $row) {
  937.                 if (!empty($row['attr_data']) && $attDate json_decode($row['attr_data'], true)) {
  938.                     //               удаляем интерьеры
  939.                     unset($attDate['i_name']);
  940.                     unset($attDate['i_id']);
  941.                     unset($attDate['i_rating']);
  942.                     unset($attDate['i_monochrome']);
  943.                     unset($attDate['i_status']);
  944.                     unset($attDate['i_file']);
  945.                     unset($attDate['i_wall_and_floor']);
  946.                     unset($attDate['i_style']);
  947.                     unset($attDate['i_texture']);
  948.                     unset($attDate['fsi_x']);
  949.                     unset($attDate['fsi_y']);
  950.                     $row array_merge((array)$row$attDate); //удалить главный интерьер из сфинкса
  951.                 }
  952.                 if (!empty($row['c_exhibition']) && $exhibitionDate json_decode($row['c_exhibition'], true)) {
  953.                     $row['c_exhibition'] = $exhibitionDate;
  954.                 } else {
  955.                     $row['c_exhibition'] = [];
  956.                 }
  957.                 if (!empty($row['c_awards']) && $c_awardsDate json_decode($row['c_awards'], true)) {
  958.                     $row['c_awards'] = $c_awardsDate;
  959.                 } else {
  960.                     $row['c_awards'] = [];
  961.                 }
  962.                 if (!empty($row['c_designer_ids']) && $c_designer_idsDate json_decode($row['c_designer_ids'], true)) {
  963.                     $row['c_designer_ids'] = $c_designer_idsDate;
  964.                 } else {
  965.                     $row['c_designer_ids'] = [];
  966.                 }
  967.                 // временно
  968.                 //$row['apply_id'] = explode(',', $row['apply_id']);
  969.                 if (!empty($data['offset'])) {
  970.                     $num++;
  971.                     if ($data['offset'] > ($num 1)) {
  972.                         continue;
  973.                     }
  974.                 }
  975.                 if (!empty($row['c_accessible'])) {
  976.                     $noInteriorFactory true;
  977.                 } else {
  978.                     $noInteriorFactory false;
  979.                 }
  980.                 if ($row['c_id'] == 3245628) {
  981.                     $row['c_name'] = App::trans('left_menu_glue');
  982.                 }
  983.                 //создаем клон из строки, но с данными из Коллекций для блатного удаления и фильтрации
  984.                 //обратить внимание при поиске по коллекциям возврщает полный результат и потом фильтрует возможно можно что-то перенести в sphinx или в where
  985.                 $iRows = [];
  986.                 if (!empty($row['i'])) {
  987.                     if (!empty($data['searchFilter']['getUsings'])) {
  988.                         $applyIds $data['searchFilter']['getUsings'] ?? []; // Массив ID для фильтрации, например [2, 3]
  989.                         $isSwimmingPoolFilter in_array(8$applyIds);
  990.                         $filteredInteriors array_filter($row['i'], function ($interior) use ($applyIds$isSwimmingPoolFilter) {
  991.                             // Если выбран фильтр бассейна (8), и артикул прошел фильтр ANY(apply_id)=8,
  992.                             // показываем все интерьеры, даже если apply_id = null (бассейн добавляется через UNION для swimming_pool = 1)
  993.                             if ($isSwimmingPoolFilter && empty($interior['apply_id'])) {
  994.                                 return true;
  995.                             }
  996.                             return !empty($interior['apply_id']) && in_array($interior['apply_id'], $applyIds);
  997.                         });
  998. // Переиндексация и обновление $row['i'], если есть результаты
  999.                         if (!empty($filteredInteriors)) {
  1000.                             $row['i'] = array_values($filteredInteriors);
  1001.                         } else {
  1002.                             // Если все интерьеры отфильтрованы, очищаем массив
  1003.                             $row['i'] = [];
  1004.                         }
  1005.                     }
  1006.                     $row['i'] = array_values($row['i']);
  1007.                     // Заменяем значения $row значениями $row[i][n]
  1008.                     foreach ($row['i'] as $v) {
  1009.                         $iRows[] = array_merge($row$v);
  1010.                     }
  1011.                 } else {
  1012.                     //если нет, то для дальнейшей проверки оставим старое значение
  1013.                     $iRows[] = $row;
  1014.                 }
  1015.                 foreach ($iRows as $intRow) {
  1016.                     $row $intRow;
  1017.                     if (
  1018.                         !empty($row['apply_id']) &&
  1019.                         !empty($data['searchFilter']['getUsings']) &&
  1020.                         count($data['searchFilter']) > &&
  1021.                         !(count(array_intersect([$row['apply_id']], $data['searchFilter']['getUsings'])) > 0)
  1022.                     ) {
  1023.                         $applyShow false;
  1024.                     } else {
  1025.                         $applyShow true;
  1026.                     }
  1027.                     if ($row['process'] == 1) {
  1028.                         $row['i_file'] = str_replace(['.jpeg''.jpg'], '.webp'$row['i_file']);
  1029.                     }
  1030.                     $noRestriction $this->getNoRestriction($data['searchFilter'], $row$oldTypeUsings ?? null);
  1031.                     // есть ограничение на показ интерьером, но выбран фильтр применения, пропускаем такой элемент
  1032.                     if (
  1033.                         !empty($data['searchFilter']['getUsings'])
  1034.                         && !$noRestriction
  1035.                     ) {
  1036.                         continue;
  1037.                     }
  1038.                     // базовая информация о коллекции
  1039.                     if (empty($collections[$row['coll']])) {
  1040.                         if ($row['c_status'] == 1) {
  1041.                             $dataReview[$row['coll']] = [
  1042.                                 'name' => App::trans(
  1043.                                     $row['c_header'] . '.short',
  1044.                                     App::getCurLocale(),
  1045.                                     [
  1046.                                         '%collection%' => $row['c_name'],
  1047.                                     ]
  1048.                                 ),
  1049.                                 'url' => App::generateUrl(
  1050.                                     'app_collection',
  1051.                                     [
  1052.                                         'factoryUrl' => $row['f_url'],
  1053.                                         'collectionUrl' => $row['c_url'],
  1054.                                     ]
  1055.                                 ),
  1056.                             ];
  1057.                         }
  1058.                         if (isset($data['searchFilter']['getTopMonth'])) {
  1059.                             $arrow $row['c_pop30'] > $row['c_last_pop30'] ? 'up' 'down';
  1060.                         } elseif (isset($data['searchFilter']['getTopWeek'])) {
  1061.                             $arrow $row['c_pop7'] > $row['c_last_pop7'] ? 'up' 'down';
  1062.                         } else {
  1063.                             $arrow false;
  1064.                         }
  1065.                         $collections[$row['coll']] = [
  1066.                             'c_id' => $row['c_id'],
  1067.                             'c_code' => $row['coll'],
  1068.                             'c_status' => $row['c_status'],
  1069.                             'c_name' => $row['c_name'],
  1070.                             'ratingMonth' => $row['rating_month'],
  1071.                             'arrow' => $arrow,
  1072.                             'c_header' => $row['c_header'],
  1073.                             'c_release_year' => $row['c_release_year'],
  1074.                             'c_url' => $row['c_url'],
  1075.                             'f_name' => $row['f_name'],
  1076.                             'f_url' => $row['f_id'] == 12 StrHelper::toLower($row['f_url']) : $row['f_url'],
  1077.                         ];
  1078.                         // если не пустое, то там массив с ID фильтров, иконки которых надо получить будет
  1079.                         $collections[$row['coll']]['c_awards'] = $row['c_awards'];
  1080.                         // если не пустое, то там массив с sub ID фильтров выставок
  1081.                         $collections[$row['coll']]['c_exhibition'] = $row['c_exhibition'];
  1082.                         $collections[$row['coll']]['date'] = date('d.m.Y'$row['publish_date']);
  1083.                         $collections[$row['coll']]['country'] = $row['country'];
  1084.                         $collections[$row['coll']]['country_code'] = $row['country_code'];
  1085.                         $collections[$row['coll']]['type'] = $row['type'];
  1086.                         $collections[$row['coll']]['material'] = $this->mapMaterial(
  1087.                             array_unique(explode(','$row['c_material'] ?? ''))
  1088.                         );
  1089.                         // вывел признак экспресс образца
  1090.                         $collections[$row['coll']]['hasExpressSample'] = !empty($row['c_express_sample']) && $row['c_express_sample'] == 1;
  1091.                         // добавил вывод prc_middle, что бы можно было проверить точность фильтрации
  1092.                         $prcCount = empty($row['prc_count']) ? null $row['prc_count'];
  1093.                         $prcVote = empty($row['prc_vote']) ? null $row['prc_vote'];
  1094.                         $prcMiddle 0;
  1095.                         if ($prcCount && $prcVote) {
  1096.                             $prcMiddle = ($prcVote $prcCount 0.01 $prcCount) * 100;
  1097.                         }
  1098.                         $collections[$row['coll']]['prc_count'] = $prcCount;
  1099.                         $collections[$row['coll']]['prc_vote'] = $prcVote;
  1100.                         $collections[$row['coll']]['prc_middle'] = $prcMiddle;
  1101.                         $collections[$row['coll']]['process'] = $row['process'] ?? 0;
  1102.                         $collections[$row['coll']]['alt'] = str_replace(
  1103.                             ['\\''"''\''],
  1104.                             '',
  1105.                             join(', ', [$row['f_name'], $row['c_name'], $row['i_name']])
  1106.                         );
  1107.                         $collections[$row['coll']]['author'] = empty($row['author']) ? null $row['author'];
  1108.                         $collections[$row['coll']]['sliding'] = empty($row['sliding']) ? [] : [$row['sliding']];
  1109.                         $collections[$row['coll']]['a_show'] = empty($data['searchFilter']['getUsings']) ? '1' '0';
  1110.                         // цены по умолчанию
  1111.                         $collections[$row['coll']]['price'] = (float)(max($row[$priceFields[0]], 1));
  1112.                         $collections[$row['coll']]['pr_min'] = (float)(max($row[$priceFields[2]], 1));
  1113.                         $collections[$row['coll']]['price_mq'] = (float)(max($row[$priceFields[1]], 1));
  1114.                         $collections[$row['coll']][$priceFields[4]] = (float)(max($row[$priceFields[4]], 1));
  1115.                         $collections[$row['coll']]['measureId'] = $row['measure'];
  1116.                         if (!empty($collections[$row['coll']]['price_mq']) && $row[$priceFields[3]] > 0) {
  1117.                             $collections[$row['coll']]['price'] = $collections[$row['coll']]['price_mq'];
  1118.                             $collections[$row['coll']]['measureId'] = 1;
  1119.                             $row['measure'] = 1;
  1120.                         }
  1121.                         $collections[$row['coll']]['measureText'] = $row['measure'] == && LocaleHelper::getUserMeasure() == 'ft' $ed[6] : $ed[$row['measure']];
  1122.                         //$collections[$row['coll']]['measureText'] = $ed[$row['measure']] == 'm²' && LocaleHelper::getUserMeasure() == 'ft' ? 'ft²' : $ed[$row['measure']];
  1123.                         if (in_array($country, ['ch''no''hk''sg'])) {
  1124.                             $collections[$row['coll']]['price'] = round(
  1125.                                 $collections[$row['coll']]['price'] - $collections[$row['coll']]['price'] * 18 118,
  1126.                                 2
  1127.                             );
  1128.                             $collections[$row['coll']]['pr_min'] = round(
  1129.                                 $collections[$row['coll']]['pr_min'] - $collections[$row['coll']]['pr_min'] * 18 118,
  1130.                                 2
  1131.                             );
  1132.                             $collections[$row['coll']]['price_mq'] = round(
  1133.                                 $collections[$row['coll']]['price_mq'] - $collections[$row['coll']]['price_mq'] * 18 118,
  1134.                                 2
  1135.                             );
  1136.                         }
  1137.                         // для Гонконга конвертируем из мальтийских цен по курсу
  1138.                         if ($country == 'hk') {
  1139.                             $collections[$row['coll']]['price'] = CurrencyRateHelper::convertPrice(
  1140.                                 'HKD',
  1141.                                 $collections[$row['coll']]['price']
  1142.                             );
  1143.                             $collections[$row['coll']]['pr_min'] = CurrencyRateHelper::convertPrice(
  1144.                                 'HKD',
  1145.                                 $collections[$row['coll']]['pr_min']
  1146.                             );
  1147.                             $collections[$row['coll']]['price_mq'] = CurrencyRateHelper::convertPrice(
  1148.                                 'HKD',
  1149.                                 $collections[$row['coll']]['price_mq']
  1150.                             );
  1151.                             $collections[$row['coll']][$priceFields[4]] = CurrencyRateHelper::convertPrice(
  1152.                                 'HKD',
  1153.                                 $collections[$row['coll']][$priceFields[4]]
  1154.                             );
  1155.                         }
  1156.                         // для Сингапура конвертируем из мальтийских цен по курсу
  1157.                         if ($country == 'sg') {
  1158.                             $collections[$row['coll']]['price'] = CurrencyRateHelper::convertPrice(
  1159.                                 'SGD',
  1160.                                 $collections[$row['coll']]['price']
  1161.                             );
  1162.                             $collections[$row['coll']]['pr_min'] = CurrencyRateHelper::convertPrice(
  1163.                                 'SGD',
  1164.                                 $collections[$row['coll']]['pr_min']
  1165.                             );
  1166.                             $collections[$row['coll']]['price_mq'] = CurrencyRateHelper::convertPrice(
  1167.                                 'SGD',
  1168.                                 $collections[$row['coll']]['price_mq']
  1169.                             );
  1170.                             $collections[$row['coll']][$priceFields[4]] = CurrencyRateHelper::convertPrice(
  1171.                                 'SGD',
  1172.                                 $collections[$row['coll']][$priceFields[4]]
  1173.                             );
  1174.                         }
  1175.                         // убираем копейки
  1176.                         $collections[$row['coll']]['price'] = round($collections[$row['coll']]['price']);
  1177.                         $collections[$row['coll']]['pr_min'] = round($collections[$row['coll']]['pr_min']);
  1178.                         $collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['price_mq']);
  1179.                         // минимальная цена по коллекции если, не установлены дополнительные фильтры
  1180.                         if ($minTypeAll) {
  1181.                             $collections[$row['coll']]['pr_min'] = round($collections[$row['coll']][$priceFields[4]]);
  1182.                             $collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['pr_min']);
  1183.                             $collections[$row['coll']]['price'] = round($collections[$row['coll']]['pr_min']);
  1184.                         } elseif (empty($collections[$row['coll']]['price_mq'])) {
  1185.                             $collections[$row['coll']]['price_mq'] = round($collections[$row['coll']]['price']);
  1186.                         }
  1187.                         // собираем коды ед.изм.
  1188.                         $collections[$row['coll']]['measure'] = $ed[$row['measure']] ?? (App::trans(
  1189.                             $measure == 'm' 'measure_mq' 'measure_ft'
  1190.                         ));
  1191.                         $collections['i_names'][$row['coll']] = [];
  1192.                         $collections[$row['coll']]['interiors'] = [];
  1193.                         $collections[$row['coll']]['articles'][] = $this->article($row);
  1194.                         $collections[$row['coll']]['slidingShow'] = 0;
  1195.                         if (
  1196.                             !empty($data['searchFilter']['getSurfaces'])
  1197.                             && in_array(8$data['searchFilter']['getSurfaces'])
  1198.                         ) {
  1199.                             $collections[$row['coll']]['slidingShow'] = 1;
  1200.                         }
  1201.                         $collections['a_names'][$row['coll']][] = $row['a_name'];
  1202.                         if (
  1203.                             empty($data['searchFilter']['inside'])
  1204.                             && !$noInteriorFactory
  1205.                             && ((empty($data['searchFilter'])
  1206.                                     || count($data['searchFilter']) <= 2
  1207.                                     && !empty($data['searchFilter']['getAlsoCollViewed'])
  1208.                                     || count($data['searchFilter']) == 1
  1209.                                     && (!empty($data['searchFilter']['factory'])
  1210.                                         || !empty($data['searchFilter'][''])
  1211.                                     )
  1212.                                 ) || $isValidFromMainInterior)
  1213.                             && !empty($row['is_main'])
  1214.                         ) {               // специальная заглушка для главной картинки коллекции на случай если не выбраны фильтры
  1215.                             [
  1216.                                 $mainInteriorId,
  1217.                                 $mainInteriorName,
  1218.                                 $mainInteriorFile,
  1219.                                 $fileSizeX,
  1220.                                 $fileSizeY,
  1221.                                 $iRating,
  1222.                             ] = explode('|'$row['is_main']);
  1223.                             if (!$fileSizeY == && !empty($mainInteriorName)) {
  1224.                                 $iName $mainInteriorName;
  1225.                                 $iFile $mainInteriorFile;
  1226.                                 if ($row['a_head'] ||  $isValidFromMainInterior || empty($data['searchFilter'])) {
  1227.                                     $collections['i_names'][$row['coll']][] = $iName;
  1228.                                     $collections[$row['coll']]['interiors_tmp'][] = [
  1229.                                         'i_id' => $mainInteriorId,
  1230.                                         'i_name' => $iName,
  1231.                                         'i_file' => $iFile,
  1232.                                         'i_rating' => $iRating,
  1233.                                         'x' => $fileSizeX,
  1234.                                         'y' => $fileSizeY,
  1235.                                     ];
  1236.                                 }
  1237.                             }
  1238.                         }
  1239.                         if (
  1240.                             !$noInteriorFactory
  1241.                             && !empty($row['i_name'])
  1242.                             && isset($row['i_id']) && $row['i_id'] !== null
  1243.                             && $noRestriction
  1244.                             && $applyShow
  1245.                             && !in_array($row['i_name'], $collections['i_names'][$row['coll']])
  1246.                             && (empty($data['searchFilter']['getUsings'])
  1247.                                 || (!empty($row['apply_id']) && in_array($row['apply_id'], $data['searchFilter']['getUsings']))
  1248.                                 || (in_array(8$data['searchFilter']['getUsings']) && empty($row['apply_id']))
  1249.                             )
  1250.                         ) {
  1251.                             $iName $row['i_name'];
  1252.                             $iFile $row['i_file'];
  1253.                             if ($row['a_head']) {
  1254.                                 $collections['i_names'][$row['coll']][] = $iName;
  1255.                                 $collections[$row['coll']]['interiors'][] = [
  1256.                                     'i_id' => $row['i_id'],
  1257.                                     'i_name' => $iName,
  1258.                                     'i_file' => $iFile,
  1259.                                     'x' => $row['fsi_x'],
  1260.                                     'y' => $row['fsi_y'],
  1261.                                     'i_rating' => $row['i_rating'],
  1262.                                 ];
  1263.                             }
  1264.                         }
  1265.                     } else {
  1266.                         // если запрошена фильтрация по коллекции, то выводим все артикулы
  1267.                         if (!empty($_GET['debug']) || !empty($data['searchFilter']['inside']) && !$NoWithArticles) {
  1268.                             $collections[$row['coll']]['articles'][] = $this->article($row);
  1269.                         }
  1270.                         if (
  1271.                             !empty($row['author']) &&
  1272.                             is_array($collections[$row['coll']]['author']) &&
  1273.                             !in_array($row['author'], $collections[$row['coll']]['author'])
  1274.                         ) {
  1275.                             $collections[$row['coll']]['author'] = $row['author'];
  1276.                         }
  1277.                         if (
  1278.                             !empty($row['sliding']) && !in_array(
  1279.                                 $row['sliding'],
  1280.                                 $collections[$row['coll']]['sliding']
  1281.                             )
  1282.                         ) {
  1283.                             $collections[$row['coll']]['sliding'][] = $row['sliding'];
  1284.                         }
  1285.                         // собираем коды ед.изм.
  1286.                         $collections[$row['coll']]['measure'] = $ed[$row['measure']] ?? (App::trans(
  1287.                             $measure == 'm' 'measure_mq' 'measure_ft'
  1288.                         ));
  1289.                         if (
  1290.                                 (!empty($data['searchFilter']['getPrcateg'])
  1291.                                     && (in_array(7$data['searchFilter']['getPrcateg'])
  1292.                                         || in_array(6$data['searchFilter']['getPrcateg'])
  1293.                                     )
  1294.                                 )
  1295.                                 || !empty($data['searchFilter']['coll']) || count(
  1296.                                     $collections[$row['coll']]['articles']
  1297.                                 ) == 0
  1298.                         ) {
  1299.                             /** см. выше для первого вхождения артикула в коллекцию */
  1300.                             if (
  1301.                                 empty($data['searchFilter']['getStyles'])
  1302.                                 || (!empty($data['searchFilter']['getStyles'])
  1303.                                     && in_array($row['a_style'], $data['searchFilter']['getStyles'])
  1304.                                 )
  1305.                             ) {
  1306.                                 if (!in_array($row['a_name'], $collections['a_names'][$row['coll']])) {
  1307.                                     $collections[$row['coll']]['articles'][] = $this->article($row);
  1308.                                 }
  1309.                             }
  1310.                         }
  1311.                         if (
  1312.                                 !$noInteriorFactory
  1313.                                 && !empty($row['i_name'])
  1314.                                 && isset($row['i_id']) && $row['i_id'] !== null
  1315.                                 && $noRestriction
  1316.                                 && $applyShow
  1317.                                 && !in_array($row['i_name'], $collections['i_names'][$row['coll']])
  1318.                                 && (
  1319.                                     empty($data['searchFilter']['getUsings'])
  1320.                                     || (!empty($row['apply_id']) && in_array($row['apply_id'], $data['searchFilter']['getUsings']))
  1321.                                     || (in_array(8$data['searchFilter']['getUsings']) && empty($row['apply_id']))
  1322.                                 )
  1323.                         ) {
  1324.                             if ($row['a_head']) {
  1325.                                 $collections['i_names'][$row['coll']][] = $row['i_name'];
  1326.                                 $collections[$row['coll']]['interiors'][] = [
  1327.                                     'i_id' => $row['i_id'],
  1328.                                     'i_name' => $row['i_name'],
  1329.                                     'i_file' => $row['i_file'],
  1330.                                     'x' => $row['fsi_x'],
  1331.                                     'y' => $row['fsi_y'],
  1332.                                     'i_rating' => $row['i_rating'],
  1333.                                 ];
  1334.                             }
  1335.                         }
  1336.                         $collections['a_names'][$row['coll']][] = $row['a_name'];
  1337.                     }
  1338.                 }
  1339.             }
  1340.         }
  1341.         unset($collections['i_names']);
  1342.         unset($collections['a_names']);
  1343.         foreach ($collections as $k => $v) {
  1344.             if ($NoWithArticles && !empty($collections[$k]['interiors'])) {
  1345.                 unset($collections[$k]['articles']);
  1346.             }
  1347.             usort($collections[$k]['interiors'], function ($a$b) {
  1348.                 return $b['i_rating'] <=> $a['i_rating'];  // DESC; для ASC поменяйте a и b местами
  1349.             });
  1350.             if ($limit) {
  1351.                 $collections[$k]['interiors'] = array_slice($collections[$k]['interiors'], 0$limit);
  1352.             }
  1353.             //Заглушку ставим только тогда когда у коллекции нет подходящих интерьеров https://te2.remote.team/discus/25909450-279B-15AB-A560-74C8D278134E?goto=true
  1354.             if (empty($collections[$k]['interiors']) && !empty($collections[$k]['interiors_tmp'])) {
  1355.                 $collections[$k]['interiors'] = $collections[$k]['interiors_tmp'];
  1356.             }
  1357.         }
  1358.         if (
  1359.             !empty($data['searchFilter']['getPrcateg'])
  1360.             && (in_array(6$data['searchFilter']['getPrcateg'])
  1361.                 || in_array(7$data['searchFilter']['getPrcateg'])
  1362.             )
  1363.         ) {
  1364.             $collections $this->setIndexesForArticlesInCollections($collections);
  1365.         }
  1366.         $collections array_values($collections);
  1367.         if ($getCount) {
  1368.             $fixfilter $this->getCount($calculate$realFilterProperty$newFiltersOnlyNoChild);
  1369.             if (!empty($fixfilter)) {
  1370.                 $res_enabledSize $fixfilter;
  1371.             } else {
  1372.                 $res_enabledSize = [];
  1373.             }
  1374.             $collections = [
  1375.                 'collections' => [],
  1376.                 'calculate' => $res_enabledSize,
  1377.             ];
  1378.         }
  1379.         if ($full) {
  1380.             return [
  1381.                 'res' => $collections,
  1382.                 'codes' => $dataReview,
  1383.             ];
  1384.         }
  1385.         return $collections;
  1386.     }
  1387.     /**
  1388.      * Подсчитывает Коллекции в свойстве
  1389.      * @param array $calculate - Собраные значения
  1390.      * @param array $realFilterProperty - фильтр связь ключей старые новые
  1391.      * @return array - подсчет коллекций
  1392.      * @throws Exception
  1393.      */
  1394.     private function getCount(array $calculate, array $realFilterProperty = []): array
  1395.     {
  1396.         $oldId 'id';
  1397.         $res = [];
  1398.         //перебераем массив с коллекциями не товарами
  1399.         foreach ($calculate as $coll => $values) {
  1400.             //перебираем их свойства
  1401.             foreach ($values as $key => $value) {
  1402.                 //перебираем их значение
  1403.                 foreach (array_unique($value) as $v) {
  1404.                     //тут вся логика с фильтром
  1405.                     if (isset($realFilterProperty[$key][$v])) {
  1406.                         // $realFilterProperty[$key][$v]['count']++;
  1407.                         if (isset($res[$key][$realFilterProperty[$key][$v][$oldId]])) {
  1408.                             $res[$key][$realFilterProperty[$key][$v][$oldId]]++;
  1409.                         } else {
  1410.                             $res[$key][$realFilterProperty[$key][$v][$oldId]] = 1;
  1411.                         }
  1412.                     } else {
  1413.                         //если такого фильтра не существует нужно создать и присвоить его свойству первое вхождение
  1414.                         if (isset($res[$key][$v])) {
  1415.                             $res[$key][$v]++;
  1416.                         } else {
  1417.                             $res[$key][$v] = 1;
  1418.                         }
  1419.                     }
  1420.                 }
  1421.             }
  1422.         }
  1423.         return $res;
  1424.     }
  1425.     /**
  1426.      * @param $row
  1427.      * @return array
  1428.      * @throws Exception
  1429.      */
  1430.     private function article($row): array
  1431.     {
  1432.         // сохраняем id артикула для выборки подробных данных артикулов подходящих под отбор
  1433.         $this->articlesId[] = $row['a_id'];
  1434.         return [
  1435.             'a_id' => $row['a_id'],
  1436.             'a_name' => $row['a_name'],
  1437.             'file' => $row['process'] == str_replace(['.jpeg''.jpg'], '.webp'$row['file']) : $row['file'],
  1438.             'a_x' => $row['fs_x'],
  1439.             'a_y' => $row['fs_y'],
  1440.             'b_g' => $row['border_grey'],
  1441.             'alt' => str_replace(['\\''"''\''], ''join(', ', [$row['f_name'], $row['c_name'], $row['a_name']])),
  1442.         ];
  1443.     }
  1444.     /**
  1445.      * @throws Exception
  1446.      */
  1447.     private function mapMaterial(array $collectionMaterials = []): array
  1448.     {
  1449.         $listMaterialCollection = [];
  1450.         foreach ($collectionMaterials as $materialId) {
  1451.             if (!empty($this->getMaterials()[$materialId])) {
  1452.                 $listMaterialCollection[] = $this->getMaterials()[$materialId];
  1453.             }
  1454.         }
  1455.         return $listMaterialCollection;
  1456.     }
  1457.     /**
  1458.      * @return array
  1459.      * @throws Exception
  1460.      */
  1461.     private function getMaterials(): array
  1462.     {
  1463.         if (count($this->materials) == 0) {
  1464.             $repoMaterialList $this->listMaterialRepository;
  1465.             $list $repoMaterialList->getList(true);
  1466.             /** @var ListMaterial $r */
  1467.             foreach ($list as $r) {
  1468.                 $materials App::trans('coll_preview_' $r['alias']);
  1469.                 $position strpos($materials'_');
  1470.                 if ($position !== false) {
  1471.                     $materials App::trans($r['alias']);
  1472.                 }
  1473.                 $this->materials[$r['id']] = $materials;
  1474.             }
  1475.         }
  1476.         return $this->materials;
  1477.     }
  1478.     private function getPriceFields(string $currencystring $countrystring $measure): array
  1479.     {
  1480.         if ($currency === 'EUR') {
  1481.             switch ($country) {
  1482.                 case 'de':
  1483.                     return ['price_euro_de''price_mq_euro_de''pr_min_euro_de''a_price_cat_de''price_sort_de'];
  1484.                 case 'at':
  1485.                     return ['price_euro_at''price_mq_euro_at''pr_min_euro_at''a_price_cat_at''price_sort_at'];
  1486.                 case 'fi':
  1487.                     return ['price_euro_fi''price_mq_euro_fi''pr_min_euro_fi''a_price_cat_fi''price_sort_fi'];
  1488.                 case 'fr':
  1489.                     return ['price_euro_fr''price_mq_euro_fr''pr_min_euro_fr''a_price_cat_fr''price_sort_fr'];
  1490.                 case 'it':
  1491.                     return ['price_euro_it''price_mq_euro_it''pr_min_euro_it''a_price_cat_it''price_sort_it'];
  1492.                 case 'be':
  1493.                     return ['price_euro_be''price_mq_euro_be''pr_min_euro_be''a_price_cat_be''price_sort_be'];
  1494.                 case 'ie':
  1495.                     return ['price_euro_ie''price_mq_euro_ie''pr_min_euro_ie''a_price_cat_ie''price_sort_ie'];
  1496.                 case 'nl':
  1497.                     return ['price_euro_nl''price_mq_euro_nl''pr_min_euro_nl''a_price_cat_nl''price_sort_nl'];
  1498.                 case 'es':
  1499.                     return ['price_euro_es''price_mq_euro_es''pr_min_euro_es''a_price_cat_es''price_sort_es'];
  1500.                 case 'ru':
  1501.                     return ['price_rue''price_mq_rue''pr_min_rue''a_price_cat_rue''price_sort_rub'];
  1502.                 case 'gb':
  1503.                     return ['price_gbe''price_mq_gbe''pr_min_gbe''a_price_cat_gbe''price_sort_gbp'];
  1504.                 case 'ch':
  1505.                     return ['price_che''price_mq_che''pr_min_che''a_price_cat_che''price_sort_chf'];
  1506.                 case 'se':
  1507.                     return ['price_see''price_mq_see''pr_min_see''a_price_cat_see''price_sort_sek'];
  1508.                 case 'pl':
  1509.                     return ['price_ple''price_mq_ple''pr_min_ple''a_price_cat_ple''price_sort_pln'];
  1510.                 case 'us':
  1511.                     if ($measure === 'ft') {
  1512.                         return [
  1513.                             'price_fq_use',
  1514.                             'price_fq_use',
  1515.                             'pr_min_f_use',
  1516.                             'a_price_cat_fq_use',
  1517.                             'price_sort_fq_usd'
  1518.                         ];
  1519.                     }
  1520.                     return ['price_use''price_mq_use''pr_min_use''a_price_cat_use''price_sort_usd'];
  1521.                 case 'ca':
  1522.                     if ($measure === 'ft') {
  1523.                         return ['price_cae''price_fq_cae''pr_min_cae''a_price_cat_fq_cae''price_sort_fq_cad'];
  1524.                     }
  1525.                     return ['price_cae''price_mq_cae''pr_min_cae''a_price_cat_cae''price_sort_cad'];
  1526.             }
  1527.             return ['price_euro''price_mq_euro''pr_min_euro''a_price_cat''price_sort'];
  1528.         }
  1529.         if ($country === 'ru' && $currency === 'RUB') {
  1530.             return ['price_rub''price_mq_rub''pr_min_rub''a_price_cat_rub''price_sort_rub'];
  1531.         }
  1532.         if ($country === 'gb' && $currency === 'GBP') {
  1533.             return ['price_gbp''price_mq_gbp''pr_min_gbp''a_price_cat_gbp''price_sort_gbp'];
  1534.         }
  1535.         if ($country === 'ch' && $currency === 'CHF') {
  1536.             return ['price_chf''price_mq_chf''pr_min_chf''a_price_cat_chf''price_sort_chf'];
  1537.         }
  1538.         if ($country === 'se' && $currency === 'SEK') {
  1539.             return ['price_sek''price_mq_sek''pr_min_sek''a_price_cat_sek''price_sort_sek'];
  1540.         }
  1541.         if ($country === 'dk' && $currency === 'DKK') {
  1542.             return ['price_dkk''price_mq_dkk''pr_min_dkk''a_price_cat_dkk''price_sort_dkk'];
  1543.         }
  1544.         if ($country === 'no' && $currency === 'NOK') {
  1545.             return ['price_nok''price_mq_nok''pr_min_nok''a_price_cat_nok''price_sort_nok'];
  1546.         }
  1547.         if ($country === 'pl' && $currency === 'PLN') {
  1548.             return ['price_pln''price_mq_pln''pr_min_pln''a_price_cat_pln''price_sort_pln'];
  1549.         }
  1550.         if ($country === 'us' && $currency === 'USD') {
  1551.             if ($measure === 'ft') {
  1552.                 return ['price_fq_usd''price_fq_usd''pr_min_f_usd''a_price_cat_fq_usd''price_sort_fq_usd'];
  1553.             }
  1554.             return ['price_usd''price_mq_usd''pr_min_usd''a_price_cat_usd''price_sort_usd'];
  1555.         }
  1556.         if ($country === 'ca' && $currency === 'CAD') {
  1557.             if ($measure === 'ft') {
  1558.                 return ['price_cad''price_fq_cad''pr_min_cad''a_price_cat_fq_cad''price_sort_fq_cad'];
  1559.             }
  1560.             return ['price_cad''price_mq_cad''pr_min_cad''a_price_cat_cad''price_sort_cad'];
  1561.         }
  1562.         return ['price_euro''price_mq_euro''pr_min_euro''a_price_cat''price_sort'];
  1563.     }
  1564.     /**
  1565.      * Ограничение на показ интерьеров
  1566.      *
  1567.      * @param array $searchFilter
  1568.      * @param array $row
  1569.      * @param array|null $oldTypeUsings
  1570.      * @return bool
  1571.      */
  1572.     private function getNoRestriction(array $searchFilter, array $row, ?array $oldTypeUsings): bool
  1573.     {
  1574.         $iTexture array_filter(array_map('intval'explode(',', (string)($row['i_texture'] ?? ''))));
  1575.         // В этой просьбе попросили исключить из ограничения фактуру по 17 кодом https://te.remote.team/#/discus/F4D2CA8B-BE66-7853-8FDC-2CFE011A151C/
  1576.         $iTexture[] = 17;
  1577.         // Если поиск по группе (например, 999) и интерьер содержит текстуру подгруппы,
  1578.         // то считаем, что интерьер подходит и под группу.
  1579.         if (!empty($searchFilter['getFacturas'])) {
  1580.             $facturas array_map('intval', (array)$searchFilter['getFacturas']);
  1581.             if (in_array(999$facturastrue)) {
  1582.                 $children $this->subFilters['getFacturas'][999] ?? [];
  1583.                 if (!empty($children)) {
  1584.                     $children array_map('intval', (array)$children);
  1585.                     if (count(array_intersect($iTexture$children)) > 0) {
  1586.                         $iTexture[] = 999;
  1587.                     }
  1588.                 }
  1589.             }
  1590.         }
  1591.         //внутри коллекции для интерьеров надо проверить, что привязаны заглавный артикулы
  1592.         if (!empty($searchFilter['inside']) && empty($row['a_head'])) {
  1593.             return true;
  1594.         }
  1595.         // ограничение на показ интерьера по признаку назначение
  1596.         if (
  1597.             !empty($oldTypeUsings)
  1598.             && (array_search(4$oldTypeUsings)
  1599.                 && !$row['i_wall_and_floor']
  1600.                 || !in_array($row['i_type'], $oldTypeUsings)
  1601.             )
  1602.         ) {
  1603.             return false;
  1604.         }
  1605.         // ограничение на показ интерьера по признаку стиль
  1606.         // внутри коллекции не используется это условие !!!!уже используется https://te2.remote.team/discus/C0B5DD6C-8487-9233-5238-08E2AF112A60?goto=true
  1607.         // так же это ограничение не должно работать если стиль "ручная работа"
  1608.         if (
  1609.             isset($row['i_style'])
  1610.             && $row['i_style'] == 0
  1611.             && !empty($searchFilter['getStyles'])
  1612.             && !in_array(14$searchFilter['getStyles'])
  1613.             && !in_array(14, [$row['a_style'], $row['styleida']])
  1614.         ) {
  1615.             return false;
  1616.         }
  1617.         // если выбран фильтр монохром, но у интерьера нет монохромной фактуры - скрываем интерьер
  1618.         if (
  1619.             !empty($searchFilter['getColors'])
  1620.             && in_array(99$searchFilter['getColors'])
  1621.             && !in_array(99$iTexture)
  1622.         ) {
  1623.             return false;
  1624.         }
  1625.         // ограничение на показ интерьеров при поиске по фактуре
  1626.         if (
  1627.             (
  1628.                 (empty($searchFilter['getTypes'])
  1629.                     || !in_array($row['type'], $searchFilter['getTypes'])
  1630.                 )
  1631.                 && (empty($searchFilter['getMaterials'])
  1632.                     || !in_array(99$searchFilter['getMaterials'])
  1633.                     || $row['material'] != 99
  1634.                 )
  1635.             )
  1636.             && empty($searchFilter['inside'])
  1637.         ) {
  1638.             if (
  1639.                 !empty($searchFilter['getFacturas'])
  1640.                 && count(array_intersect($iTexture$searchFilter['getFacturas'])) == 0
  1641.             ) {
  1642.                 return true;
  1643.             }
  1644.             // ограничение подбора интерьеров по некоторым фильтрам
  1645.             // исключаем случай, когда выбран фильтр монохром и у интерьера есть монохром https://te2.remote.team/discus/2C755E51-C93A-D6F6-21FE-641A6A4D1DF2
  1646. //            if (
  1647. //                !empty($searchFilter)
  1648. //                && (!empty($searchFilter['getColors'])
  1649. //                    || !empty($searchFilter['getMaterials'])
  1650. //                    || !empty($searchFilter['getSurfaces'])
  1651. //                )
  1652. //                && empty($row['type_filter'])
  1653. //                && !(
  1654. //                    !empty($searchFilter['getColors'])
  1655. //                    && in_array(99, $searchFilter['getColors'])
  1656. //                    && in_array(99, $iTexture)
  1657. //                )
  1658. //            ) {
  1659. //                return false;
  1660. //            }
  1661.             return true;
  1662.         }
  1663.         if (empty($searchFilter['getFacturas'])) {
  1664.             return true;
  1665.         }
  1666.         if (count(array_intersect($iTexture$searchFilter['getFacturas'])) > 0) {
  1667.             return true;
  1668.         }
  1669.         return false;
  1670.     }
  1671.     /**
  1672.      * @param array $collections
  1673.      * @return array
  1674.      */
  1675.     private function setIndexesForArticlesInCollections(array $collections): array
  1676.     {
  1677.         $n 0// для простановки индексов артикулов
  1678.         foreach ($collections as &$collection) {
  1679.             unset($collection['interiors']);
  1680.             if (!empty($collection['articles'])) {
  1681.                 foreach ($collection['articles'] as &$item) {
  1682.                     $item['num'] = $n;
  1683.                     $n++;
  1684.                 }
  1685.             }
  1686.         }
  1687.         return $collections;
  1688.     }
  1689.     //нужно узнать не сортирует ли человек случайно чтобы отсортировать за него
  1690.     /**
  1691.      * @return int
  1692.      * @throws Exception
  1693.      */
  1694.     public function getSearchSortId()
  1695.     {
  1696.         $sort App::getSession()->get('sort_catalog_tmp');
  1697.         if ($sort == null) {
  1698.             $sort App::getRequest()->get('sort');
  1699.         }
  1700.         if ($sort == null) {
  1701.             $sort App::getRequest()->cookies->get('sort_catalog');
  1702.         }
  1703.         if ($sort == null) {
  1704.             $sort 0;
  1705.         }
  1706.         return $sort;
  1707.     }
  1708. }