-
Роман ЦукановРазработчик
-
Дата публикации21.06.2020
-
Категория1С-Битрикс

Сложные фильтры в битриксе не так очевидны, как кажется. Логика OR прекрасно работает, а вот AND…
На сайте помимо всего прочего присутствуют два инфоблока: центры оказания услуг с координатами на карте и контактами и непосредственно инфоблок самих услуг, оказываемых данными центрами. Чтобы связать центры и услуги, у инфоблока центров есть дополнительное множественное свойство SERVICES типа «Привязка к элементам» инфоблока услуг. На странице фильтрации присутствуют чекбоксы данных услуг.
Задача заключается в том, чтобы при выборе нескольких услуг отображались только те центры, к которым привязаны именно все выбранные в фильтре услуги, а не какая-либо одна из них. Иными словами в выборке должна срабатывать логика «И», а не «ИЛИ». Нам нужно получить список ID элементов, которые мы потом скормим компоненту для корректного отображения результатов.
К сожалению, более-менее актуальные официальные мануалы по D7 не пестрят информативностью. Пришлось курить форумы, на которых мы узнали,что проблема с 2014 года так и не решилась, а люди на оф форумах пишут костыли, которые у нас не сработали бы. Спустя пол дня мы таки нашли рабочее решение. Собрали его из нескольких различных инструкций.
Итак, представляем Вам рабочее решение данной задачи, собранное по крупицам из разных источников.
if(!empty($_GET['services'])){
$arrItemsIds = array();
$arrFilter = array(
"IBLOCK_ID" => 33,
"=ACTIVE" => "Y",
);
foreach ($_GET['services'] as $key => $serviceId) {
$arrFilter[] = array("ID" => CIBlockElement::SubQuery("ID", array("IBLOCK_ID" => 33, "PROPERTY_SERVICES" => $serviceId)));
}
$iterator = \CIBlockElement::GetList(
array(),
$arrFilter,
false,
false,
array('ID')
);
while ($arItem = $iterator->Fetch()) {
$arrItemsIds[] = $arItem['ID'];
}
$GLOBALS['arrFilterСto'][] = array('ID' => $arrItemsIds);
}
Что происходит выше?
Сначала проверяем на пустоту наш массив $_GET. Под ключом «services» летят выбранные в фильтре услуги. Далее, на строчках 4-7 определяем базовые настройки фильтра (нужны только активные элементы инфоблока, IBLOCK_ID которого равен 33). Бежим циклом по нашему массиву $_GET[‘services’] и динамически дособираем наш массив фильтрации $arrFilter используя подзапросы.
Ну а дальше все просто: с помощью метода GetList вытаскиваем ID необходимых нам элементов и присваиваем их значение нашему глобальному фильтру.
Спасибо за обратную связь. Отлично, что мы старались не зря)
Большое спасибо! Рабочее решение.
Спасибо за фидбек. Рады, что кому-то пригодилось.
Спасибо тебе за код! Прям моя задача была!