- Модуль: im
- Путь к файлу: ~/bitrix/modules/im/lib/chat.php
- Класс: BitrixImChat
- Вызов: Chat::getRelation
static function getRelation($chatId, $params = [])
{
$chatId = intval($chatId);
if ($chatId <= 0)
{
return false;
}
$connection = BitrixMainApplication::getInstance()->getConnection();
$selectFields = '';
if (isset($params['SELECT']))
{
$params['SELECT'][] = 'ID';
$params['SELECT'][] = 'USER_ID';
$map = BitrixImModelRelationTable::getMap();
foreach ($params['SELECT'] as $key => $value)
{
if (is_int($key) && isset($map[$value]))
{
$selectFields .= "R.{$value}, ";
unset($map[$value]);
}
else if (!is_int($key) && isset($map[$key]))
{
$value = (string)$value;
$selectFields .= "R.{$key} '{$connection->getSqlHelper()->forSql($value)}', ";
unset($map[$value]);
}
}
}
if (!$selectFields)
{
$selectFields = 'R.*, ';
}
$withUserFields = false;
if (isset($params['USER_DATA']) && $params['USER_DATA'] == 'Y')
{
$withUserFields = true;
$list = Array('ACTIVE', 'EXTERNAL_AUTH_ID');
foreach ($list as $key)
{
$selectFields .= "U.{$key} USER_DATA_{$key}, ";
}
}
$skipUsers = false;
$skipUserInactiveSql = '';
if (isset($params['SKIP_INACTIVE_USER']) && $params['SKIP_INACTIVE_USER'] === 'Y')
{
$skipUsers = true;
$skipUserInactiveSql = "AND U.ACTIVE = 'Y'";
}
$skipUserTypes = $params['SKIP_USER_TYPES'] ?? [];
if (isset($params['SKIP_CONNECTOR']) && $params['SKIP_CONNECTOR'] === 'Y')
{
$skipUserTypes[] = 'imconnector';
}
$skipUserTypesSql = '';
if (!empty($skipUserTypes))
{
$skipUsers = true;
if (count($skipUserTypes) === 1)
{
$skipUserTypesSql = "AND (U.EXTERNAL_AUTH_ID != '".$connection->getSqlHelper()->forSql($skipUserTypes[0])."' OR U.EXTERNAL_AUTH_ID IS NULL)";
}
else
{
$skipUserTypes = array_map(function($type) use ($connection) {
return $connection->getSqlHelper()->forSql($type);
}, $skipUserTypes);
$skipUserTypesSql = "AND (U.EXTERNAL_AUTH_ID NOT IN ('".implode("','", $skipUserTypes)."') OR U.EXTERNAL_AUTH_ID IS NULL)";
}
}
$whereFields = '';
if (isset($params['FILTER']))
{
$map = BitrixImModelRelationTable::getMap();
foreach ($params['FILTER'] as $key => $value)
{
if (!isset($map[$key]))
{
continue;
}
if (is_int($value))
{
}
else if (is_bool($value))
{
$value = $value? "'Y'": "'N'";
}
else if (is_string($value))
{
$value = "'{$connection->getSqlHelper()->forSql($value)}'";
}
else
{
continue;
}
$whereFields .= " AND R.{$key} = {$value}";
}
}
/*$skipUnmodifiedRecords = false;
if (isset($params['SKIP_RELATION_WITH_UNMODIFIED_COUNTERS']) && $params['SKIP_RELATION_WITH_UNMODIFIED_COUNTERS'] == 'Y')
{
$skipUnmodifiedRecords = true;
}*/
/*$sqlSelectCounter = 'R.LAST_ID, R.COUNTER, R.COUNTER PREVIOUS_COUNTER';
$customCounter = false;
$customMaxId = 0;
$customMinId = 0;
$counters = [];
if (isset($params['REAL_COUNTERS']) && $params['REAL_COUNTERS'] != 'N' || $skipUnmodifiedRecords)
{
if (is_array($params['REAL_COUNTERS']) && isset($params['REAL_COUNTERS']['LAST_ID']))
{
$sqlSelectCounter = "R.COUNTER PREVIOUS_COUNTER, (
SELECT COUNT(1) FROM b_im_message M WHERE M.CHAT_ID = R.CHAT_ID AND M.ID > ".intval($params['REAL_COUNTERS']['LAST_ID'])."
) COUNTER";
}
else
{
$customCounter = true;
$query = $connection->query("
SELECT ID FROM b_im_message
WHERE CHAT_ID = {$chatId}
ORDER BY DATE_CREATE DESC, ID DESC
LIMIT 100
");
$messageCounter = 0;
while ($row = $query->fetch())
{
if (!$customMaxId)
{
$customMaxId = $row['ID'];
}
$counters[$row['ID']] = $messageCounter++;
$customMinId = $row['ID'];
}
}
}*/
$limit = '';
if (isset($params['LIMIT']))
{
$limit = 'LIMIT '.(int)$params['LIMIT'];
}
$offset = '';
if (isset($params['OFFSET']))
{
$offset = 'OFFSET '.(int)$params['OFFSET'];
}
$orderField = 'R.ID';
if (isset($params['LAST_USER_ID']) && (int)$params['LAST_USER_ID'] >= 0)
{
$lastUserId = (int)$params['LAST_USER_ID'];
$whereFields .= " AND R.USER_ID > {$lastUserId}";
$orderField = 'R.USER_ID';
}
$selectFields = rtrim($selectFields, ', ');
$sql = "
SELECT {$selectFields}
FROM b_im_relation R
".($withUserFields && !$skipUsers? "LEFT JOIN b_user U ON R.USER_ID = U.ID": "")."
".($skipUsers? "INNER JOIN b_user U ON R.USER_ID = U.ID {$skipUserInactiveSql} {$skipUserTypesSql}": "")."
WHERE R.CHAT_ID = {$chatId} {$whereFields}
ORDER BY {$orderField} ASC
{$limit} {$offset}
";
$relations = array();
$query = $connection->query($sql);
while ($row = $query->fetch())
{
/*if ($customCounter)
{
if (isset($counters[$row['LAST_ID']]))
{
$row['COUNTER'] = $counters[$row['LAST_ID']];
}
else if ($row['LAST_ID'] < $customMinId)
{
$row['COUNTER'] = count($counters);
}
else if ($row['LAST_ID'] > $customMaxId)
{
$row['COUNTER'] = 0;
}
}
else
{
$row['COUNTER'] = $row['COUNTER'] > 99? 100: (int)$row['COUNTER'];
}
$row['PREVIOUS_COUNTER'] = (int)$row['PREVIOUS_COUNTER'];
if ($skipUnmodifiedRecords && $row['COUNTER'] == $row['PREVIOUS_COUNTER'])
{
continue;
}*/
foreach ($row as $key => $value)
{
if (mb_strpos($key, 'USER_DATA_') === 0)
{
$row['USER_DATA'][mb_substr($key, 10)] = $value;
unset($row[$key]);
}
}
$relations[$row['USER_ID']] = $row;
}
// region New counter
// todo: select counter only if it's need
if (!isset($params['WITHOUT_COUNTERS']) || $params['WITHOUT_COUNTERS'] !== 'Y')
{
$userIds = array_keys($relations);
$readService = new ReadService();
$counters = $readService->getCounterService()->getByChatForEachUsers($chatId, $userIds);
$lastIdInChat = $readService->getViewedService()->getLastMessageIdInChat($chatId) ?? 0;
$lastReads = $readService->getViewedService()->getDateViewedByMessageIdForEachUser($lastIdInChat, $userIds);
foreach ($relations as $userId => $relation)
{
$counter = $counters[$userId] ?? 0;
$counter = $counter > 99 ? 100 : $counter;
$relations[$userId]['COUNTER'] = $counter;
$relations[$userId]['LAST_READ'] = $lastReads[$userId] ?? null;
}
}
// endregion
return $relations;
}