Как использовать arFilter, в Битрикс API

Без лишних вступлений, перейдем к одному из очень важных понятий – фильтрация элементов в Битриксе

Битрикс arFilter

Вы уже знаете как выводить элементы и разделы. В документации 1С-Битрикс мы можем ясно видеть, что, не только приравнивание значений нам доступно но и:

  • “!” – не равно
  • “<” – меньше
  • “<=” – меньше либо равно
  • “>” – больше
  • “>=” – больше либо равно
  • “><” – между

На моей практике использовать “между” мне не доводилось 🙂 . А вот с остальным все гораздо проще, чем может показаться на первый взгляд. Вам важно уловить несколько очень важных вещей, которые сделают ваш код чуть лучше.

Используя arFilter вы избавите себя от лишних проверок

И это действительно так. Предположим, что у нас уже есть свойство которое устанавливает, есть ли товар в наличии, и вам необходимо написать условие:

Если количество товара больше 0 или свойство Наличие = Да, то показываем товар

Так вот, если не знать про сложную логику фильтра (о которой я расскажу чуть ниже), то мы бы писали через старые добрые “if, else“, причем уже после получения параметров – но, этого можно избежать еще на этапе выборки данных.

Если использовать в скриптах arFilter и arSelect – вы исключите лишние данные

На самом деле этот код:

Array("ID" => "ASC", " ACTIVE" => "Y"),
Array("IBLOCK_ID" => 14, 'PROPERTY_SALELEADER_VALUE' => 'да'),
false,
false,
Array('ID', 'NAME', 'CODE')

наглядно показывает, что ничего лишнего мы не будем передавать (важно не только указывать условия в фильтре, но и только те поля которые вы будете использовать, arSelect, или в данном случае последний массив). Записывать “больше-меньше” нужно таким вот образом:

'>=CATALOG_PRICE_1' => '250',

Для остальных условий – аналогично, пишем перед свойством >, <, >=, <=, ! и вуаля 🙂 .

Как написать фильтр со сложной логикой 1С-Битрикс

Вот мы и подошли к самому интересному и не очевидному. Сложный фильтр может принимать 2 значения AND и OR (И и ИЛИ). При этом сложность условия, опять же, ограничивается лишь вашей фантазией 🙂 . Не будем ходить далеко, возьмем пример из документации:

$arFilter = array(
    "IBLOCK_ID" => $IBLOCK_ID,
    "SECTION_CODE" => "orange",
    "INCLUDE_SUBSECTIONS" => "Y",
    array(
        "LOGIC" => "OR",
        array("<PROPERTY_RADIUS" => 50, "=PROPERTY_CONDITION" => "Y"),
        array(">=PROPERTY_RADIUS" => 50, "!=PROPERTY_CONDITION" => "Y"),
    ),
);

Итак, для сложного фильтра, нам нужно создать массив, указать значение LOGIC в значение OR или AND, и после запятой создать 2 сравниваемых массива. Как видите, тут есть практически все условия о которых мы говорили выше (меньше, равно, больше или равно, не равно).

Битрикс $arFilter – как использовать подзапросы

Ситуация следующая – у нас есть каталог с оптовыми ценами, и есть товары с торговыми предложениями. Используем подзапросы при помощи CIBlockElement::SubQuery:

$arSubQuery = Array('IBLOCK_ID' => 33, '>CATALOG_PRICE_3' => 0);

$arSort = Array('SHOW_COUNTER' => 'DESC');
$arFilter = Array(
	'SECTION_ID' => $arResult['ID'],
	'INCLUDE_SUBSECTIONS' => 'Y',
	'PROPERTY_SALELEADER_VALUE' => 'да',
	'ACTIVE' => 'Y',
	array(
		"LOGIC" => "OR",
		array('>CATALOG_QUANTITY' => 0),
		array('PROPERTY_PRODAZA_VALUE' => 'Да'),
	),
	array (
		"LOGIC" => "OR",
		array('>CATALOG_PRICE_3' => 0, 'IBLOCK_ID' => 6),
		array('ID' => CIBlockElement::SubQuery('PROPERTY_CML2_LINK', $arSubQuery)),
	)
);

Первый “сложный” фильтр проверяет есть ли товар в наличии, а второй – выбирает только те товары, у которых оптовая цена (‘CATALOG_PRICE_3’) больше 0.

Надеюсь вам стало более понятно как работает $arFilter и что с ним можно делать, а если у вас остались вопросы не стесняйтесь задавать их в комментариях 🙂 .

ПС в статье идет речь НЕ ПРО УМНЫЙ ФИЛЬТР 🙂

автор: Dmitriy

З 2011 року займаюся веб-розробкою. Зараз я – PHP Full Stack Developer.
Обговорити ваш проект, а також дізнатися більше про мене ви можете на цьому сайті:
dev.forwww.com

Email: dmitriyribka@gmail.com

18 коментаря

  1. Добрый день!
    А как использовать умный фильтр – к всему инфоблоку???
    Есть Каталог Аккумуляторы – вот при включение умного фильтра – он у меня появляется только когда зайду в какого нибудь производителя 🙁
    Может подскажите – как его вывести что бы фильтрация производилась по всем производителям – и параметрам которые указаны (ток, кллемы и т.д)

    1. Добрый день, Андрей. В данной статье было не совсем про умный фильтр, но, если я вас правильно понял, вам нужно зайти в инфоблок, свойства, и в настройках свойства поставить галочку “показывать в умном фильтре”. У меня умный фильтр, который работает в каталоге, на странице раздела показывает доступные варианты фильтрации, проверьте, помогло ли.

  2. Добрый день!
    А не подскажете, как реализовать показ в умном фильтре только товаров в наличии? То есть добавить в него флажок “Только в наличии”. Переменная CATALOG_QUANTITY в которой указано количество товара. Как запихнуть это дело в сам фильтр? Или есть более продуманное решение? За ранее спасибо за ответ!

    1. Честно говоря не знаю, по идее умный фильтр работает только по свойствам, которые потом можно отобразить для выбора в админке. К сожалению у меня нет готового решения, так бы поделился.

      1. Ну на других сайтах (с битриксом) это же как то реализовано в умном фильтре… У меня есть такое условие в карточке товара:
        ” 0 ){?>
        <a href="#" data-item="” data-quantity=”1″ class=”button sm to-cart” alt=”” rel=”nofollow”>Купить

        <a href="#" class="button sm order" alt="” rel=”nofollow”>Под заказ

        Что оно делает и так видно, но сколько я не пытался эту переменную подставить в фильтр, ничего не выходит… либо я не туда вставляю, либо он не хочет понимать эту переменную… Уже весь мозг себе сломал, чтоб реализовать такую возможность. Вот и обратился за помощью, авось кто-нибудь сталкивался и подскажет.

  3. Реально ли с помощью $arFilter извлечь элементы, у которых есть множественное свойства типа файл. и в поле описания файла (description) упоминается слово, например “население”?
    Я думал что нибудь типа $arFilter = Array(‘IBLOCK_ID’=>$IBLOCK_ID, ‘PROPERTY’=>Array(‘SRC’=>’%населени%’));

    1. Честно говоря не пробовал, так бы вам подсказал. Но если это не получилось в самом фильтре, я бы рекомендовал делать проверки уже после. Но т.к. это может занять много времени в некоторых случаях, то можно написать скрипт который бы записывал отдельное свойство, например, тип “список” и называется “население”, а запускался по cron. Таким образом вы еще на уровне фильтрации сможете сделать выборку, ну это конечно крайний вариант 🙂

  4. Здравствуйте! Подскажите пожалуйста как применить фильтр по клику на ссылку. Хочу сделать так чтоб при клике в catalog.section на элемент выводились похожие по параметрам элементы.

    1. Здравствуйте. Вам лучше использовать комплексный компонент каталог, там сразу по клику на раздел будет фильтрация по разделам. А если вы хотите написать свой фильтр, то получается что по клику на раздел нужно передавать айди секции. Если рассматривать пример через GET переменные, то ссылки будут в виде ‘/catalog/section/?section_id=5’ – и потом вам нужно передавать в фильтр уже айди секции, то есть – ‘SECTION_ID’ => $_GET[‘section_id’] – но как по мне это ужасный вариант, и я бы все таки рекомендовал кастомизировать стандартный комплексный компонент каталога =)

      1. Спасибо. Помогите, пожалуйста, сформировать фильтр корректно. Затупил нещадно.
        Вот код:
        $arSubQuery = Array(‘IBLOCK_ID’ => 3, ‘>PROPERTY_UF_QUANTITY’ => 0);
        $arFilter = $arFilter2 = array(
        “IBLOCK_ID” => “2”,
        “ACTIVE” => “Y”,
        array(
        “LOGIC” => “AND”,
        array(‘ID’ => CIBlockElement::SubQuery(‘PROPERTY_CML2_LINK’, $arSubQuery)),
        ),
        );

        “IBLOCK_ID” => “2” – инфоблок с товарами, “IBLOCK_ID” => “3” – инфоблок с товарными предложениями, UF_QUANTITY – свойство количество в товарном предложении. Пытаюсь отфильтровать товары с наличием и что-то не выходит никак.

  5. Здравствуйте помогите пожалуйста ни как не могу отфильтровать через LOGIC OR
    [ ‘LOGIC’=>’OR’,
    [‘UF_CRM_1637672620’=>$user_id[‘result’][0][‘ID’]],
    [‘UF_CRM_1638186920’=>$user_id[‘result’][0][‘ID’]]
    ]

    1. Попробуйте сделать, как на этом примере, только со своими полями
      global $arrFilter;
      $arrFilter = Array(
      array(
      “LOGIC” => “OR”,
      array(“NAME” => ‘%’.trim($_REQUEST[‘s’]).’%’),
      array(“PROPERTY_ART” => ‘%’.trim($_REQUEST[‘s’]).’%’),
      )
      );

Залишити відповідь