Если у вас возникли какие либо вопросы которые вы не смогли решить по нашим публикациям самостоятельно,
то ждем ваше обращение в нашей службе тех поддержки.
Выбор пользователей: сложная логика в фильтре.
При использовании CUser::GetList нет возможности фильтровать пользователей, используя логику в фильтре. ORM в новом ядре и класс Bitrix\Main\UserTable позволяет решить эту проблему. Допустим, нам нужно выбрать пользователя 20, а также пользователей имеющих значение пользовательского поля UF_SHMS = 770 Код будет следующий:
Все хорошо до тех пор, пока мы не решим применить фильтрацию по группам. Например, дополнительно, выбрать пользователей с UF_SHMS= 770, состоящих в группе 6. Соответствие группа-пользователь хранится в таблице b_user_group. Для работы с этой таблицей есть класс Bitrix\Main\UserGroupTable. Одному пользователю из b_user может соответствовать несколько записей в b_user_group.
Итого имеем отношение один ко многим. В учебном курсе сказано, что при таком отношении «нужно лишь использовать специальный синтаксис» и приведен пример для параметра select. Это же работает и для filter. Используем
Из-за того, что пользователь может состоять в нескольких группах. Получим несколько одинаковых записей. Это решается добавлением параметра "data_doubling"=>false в getList
`main_user_uts_object`.`UF_SHMS` = 770 AND `main_user`.`ID` IN (SELECT `main_user_tmp355191381`.`ID` AS `ID` FR OM `b_user` `main_user_tmp355191381` LEFT JOIN `b_user_group` `main_user_user_group_user_tmp355191381` ON `main_user_user_group_user_tmp355191381`.`USER_ID` = `main_user_tmp355191381`.`ID` WHERE `main_user_user_group_user_tmp355191381`.`GROUP_ID` = 6)
Фильтрация по группе с ID = 6 это не совсем корректно, так как есть ещё ограничение по времени привязки к группам. Поэтому полный фильтр будет такой:
Все бы хорошо, но на каждый встречающийся Bitrix\Main\UserGroupTable:USER делается один подзапрос, т.е. будет
WHERE `ID` IN (.. WHERE .. GROUP_ID` = 6 `ID` IN (.. WHERE … DATE_ACTIVE_FROM` IS NULL `ID` IN (.. WHERE … DATE_ACTIVE_TO` IS NULL `ID` IN (.. WHERE … DATE_ACTIVE_FROM` <= NOW() `ID` IN (.. WHERE … DATE_ACTIVE_TO` >= NOW()
Это не совсем то, что нам нужно. Поэтому используем свой подзапрос:
echo getSqlForGroup(6); выберет нам пользователей 6 группы
SELECT DISTINCT(USER_ID) AS `D_USER_ID` FR OM `b_user_group` `main_user_group` WH ERE `main_user_group`.`GROUP_ID` = 6 AND ( (`main_user_group`.`DATE_ACTIVE_FROM` IS NULL) OR `main_user_group`.`DATE_ACTIVE_FROM` <= NOW() ) AND ( (`main_user_group`.`DATE_ACTIVE_TO` IS NULL) OR `main_user_group`.`DATE_ACTIVE_TO` >= NOW() )