static function getQuery(array $options = []): Query
{
$selectFields = [
'ID', 'ACTIVE', 'LAST_NAME', 'NAME', 'SECOND_NAME', 'LOGIN', 'EMAIL', 'TITLE',
'PERSONAL_GENDER', 'PERSONAL_PHOTO', 'WORK_POSITION',
'CONFIRM_CODE', 'EXTERNAL_AUTH_ID'
];
if (isset($options['selectFields']) && is_array($options['selectFields']))
{
$allowedFields = static::getAllowedFields();
foreach ($options['selectFields'] as $field)
{
if (is_string($field) && array_key_exists($field, $allowedFields))
{
$selectFields[] = $allowedFields[$field];
}
}
}
$query = UserTable::query();
$query->setSelect(array_unique($selectFields));
$intranetInstalled = ModuleManager::isModuleInstalled('intranet');
if ($intranetInstalled)
{
$query->addSelect('UF_DEPARTMENT');
}
$activeUsers = array_key_exists('activeUsers', $options) ? $options['activeUsers'] : true;
if (is_bool($activeUsers))
{
$query->where('ACTIVE', $activeUsers ? 'Y' : 'N');
}
if (isset($options['onlyWithEmail']) && is_bool(isset($options['onlyWithEmail'])))
{
$query->addFilter(($options['onlyWithEmail'] ? '!' : '').'EMAIL', false);
}
if (isset($options['invitedUsers']) && is_bool(isset($options['invitedUsers'])))
{
$query->addFilter(($options['invitedUsers'] ? '!' : '').'CONFIRM_CODE', false);
}
if (!empty($options['searchQuery']) && is_string($options['searchQuery']))
{
$query->registerRuntimeField(
new Reference(
'USER_INDEX',
BitrixMainUserIndexTable::class,
Join::on('this.ID', 'ref.USER_ID'),
['join_type' => 'INNER']
)
);
$query->whereMatch(
'USER_INDEX.SEARCH_USER_CONTENT',
FilterHelper::matchAgainstWildcard(
Content::prepareStringToken($options['searchQuery']), '*', 1
)
);
}
else if (!empty($options['searchByEmail']) && is_string($options['searchByEmail']))
{
$query->whereLike('EMAIL', $options['searchByEmail'].'%');
}
$currentUserId = (
!empty($options['currentUserId']) && is_int($options['currentUserId'])
? $options['currentUserId']
: $GLOBALS['USER']->getId()
);
$isIntranetUser = $intranetInstalled && self::isIntranetUser($currentUserId);
if ($intranetInstalled)
{
$emptyValue = serialize([]);
$emptyValue2 = serialize([0]);
$query->registerRuntimeField(new ExpressionField(
'IS_INTRANET_USER',
'IF(
(%s IS NOT NULL AND %s != '' . $emptyValue . '' AND %s != '' . $emptyValue2 . '') AND
(%s IS NULL OR %s NOT IN ('' . implode('', '', UserTable::getExternalUserTypes()) . '')), 'Y', 'N'
)',
['UF_DEPARTMENT', 'UF_DEPARTMENT', 'UF_DEPARTMENT', 'EXTERNAL_AUTH_ID', 'EXTERNAL_AUTH_ID'])
);
$query->registerRuntimeField(new ExpressionField(
'IS_EXTRANET_USER',
'IF(
(%s IS NULL OR %s = '' . $emptyValue . '' OR %s = '' . $emptyValue2 . '') AND
(%s IS NULL OR %s NOT IN ('' . implode('', '', UserTable::getExternalUserTypes()) . '')), 'Y', 'N'
)',
['UF_DEPARTMENT', 'UF_DEPARTMENT', 'UF_DEPARTMENT', 'EXTERNAL_AUTH_ID', 'EXTERNAL_AUTH_ID'])
);
$query->registerRuntimeField(
new Reference(
'INVITATION',
InvitationTable::class,
Join::on('this.ID', 'ref.USER_ID')->where('ref.ORIGINATOR_ID', $currentUserId),
['join_type' => 'LEFT']
)
);
$extranetUsersQuery = (empty($options['searchByEmail']) ? self::getExtranetUsersQuery($currentUserId) : null);
$intranetUsersOnly = isset($options['intranetUsersOnly']) && $options['intranetUsersOnly'] === true;
$extranetUsersOnly = isset($options['extranetUsersOnly']) && $options['extranetUsersOnly'] === true;
$emailUsersOnly = isset($options['emailUsersOnly']) && $options['emailUsersOnly'] === true;
$networkUsersOnly = isset($options['networkUsersOnly']) && $options['networkUsersOnly'] === true;
$emailUsers =
isset($options['emailUsers']) && is_bool($options['emailUsers']) ? $options['emailUsers'] : true
;
$myEmailUsers =
isset($options['myEmailUsers']) && is_bool($options['myEmailUsers']) && $options['myEmailUsers']
;
$networkUsers =
!(isset($options['networkUsers']) && is_bool($options['networkUsers'])) || $options['networkUsers']
;
if ($isIntranetUser)
{
if (isset($options['departmentId']) && is_int($options['departmentId']))
{
$query->addFilter('UF_DEPARTMENT', $options['departmentId']);
}
if ($emailUsersOnly)
{
$query->where('EXTERNAL_AUTH_ID', 'email');
if ($myEmailUsers)
{
$query->whereNotNull('INVITATION.ID');
}
}
else if ($networkUsersOnly)
{
$query->where('EXTERNAL_AUTH_ID', 'replica');
}
else if ($intranetUsersOnly)
{
$query->where('IS_INTRANET_USER', 'Y');
}
else if ($extranetUsersOnly)
{
$query->where('IS_EXTRANET_USER', 'Y');
if ($extranetUsersQuery)
{
$query->whereIn('ID', $extranetUsersQuery);
}
}
else
{
$filter = Query::filter()->logic('or');
if (
empty($options['searchByEmail'])
&& !CSocNetUser::isCurrentUserModuleAdmin()
)
{
$filter->where('IS_INTRANET_USER', 'Y');
}
else
{
$filter->addCondition(Query::filter()
->logic('or')
->whereNotIn('EXTERNAL_AUTH_ID', UserTable::getExternalUserTypes())
->whereNull('EXTERNAL_AUTH_ID')
);
}
if ($emailUsers === true)
{
if ($myEmailUsers)
{
$filter->addCondition(Query::filter()
->where('EXTERNAL_AUTH_ID', 'email')
->whereNotNull('INVITATION.ID')
);
}
else
{
$filter->where('EXTERNAL_AUTH_ID', 'email');
}
}
if ($networkUsers === true)
{
$filter->where('EXTERNAL_AUTH_ID', 'replica');
}
if ($extranetUsersQuery)
{
$filter->whereIn('ID', $extranetUsersQuery);
$filter->addCondition(Query::filter()
->where(Query::filter()
->logic('or')
->whereNull('EXTERNAL_AUTH_ID')
->whereNot('EXTERNAL_AUTH_ID', 'email')
)
->whereNotNull('INVITATION.ID')
);
}
$query->where($filter);
}
}
else
{
if ($intranetUsersOnly)
{
$query->where('IS_INTRANET_USER', 'Y');
}
else if ($extranetUsersOnly)
{
$query->where('IS_EXTRANET_USER', 'Y');
}
else
{
$query->addFilter('!=EXTERNAL_AUTH_ID', UserTable::getExternalUserTypes());
}
if ($extranetUsersQuery)
{
$query->whereIn('ID', $extranetUsersQuery);
}
else
{
$query->where(new ExpressionField('EMPTY_LIST', '1'), '!=', 1);
}
}
}
else
{
$query->addFilter('!=EXTERNAL_AUTH_ID', UserTable::getExternalUserTypes());
}
$userIds = [];
$userFilter = isset($options['userId']) ? 'userId' : (isset($options['!userId']) ? '!userId' : null);
if (isset($options[$userFilter]))
{
if (is_array($options[$userFilter]) && !empty($options[$userFilter]))
{
foreach ($options[$userFilter] as $id)
{
$userIds[] = (int)$id;
}
$userIds = array_unique($userIds);
if (!empty($userIds))
{
if ($userFilter === 'userId')
{
$query->whereIn('ID', $userIds);
}
else
{
$query->whereNotIn('ID', $userIds);
}
}
}
else if (!is_array($options[$userFilter]) && (int)$options[$userFilter] > 0)
{
if ($userFilter === 'userId')
{
$query->where('ID', (int)$options[$userFilter]);
}
else
{
$query->whereNot('ID', (int)$options[$userFilter]);
}
}
}
if (
$userFilter === 'userId'
&& empty($options['order'])
&& count($userIds) > 1
)
{
$query->registerRuntimeField(
new ExpressionField(
'ID_SEQUENCE',
'FIELD(%s, ' . implode(',', $userIds) . ')',
'ID'
)
);
$query->setOrder('ID_SEQUENCE');
}
elseif (!empty($options['order']) && is_array($options['order']))
{
$query->setOrder($options['order']);
}
else
{
$query->setOrder(['LAST_NAME' => 'asc']);
}
if (isset($options['limit']) && is_int($options['limit']))
{
$query->setLimit($options['limit']);
}
elseif ($userFilter !== 'userId' || empty($userIds))
{
$query->setLimit(100);
}
return $query;
}