function GetLastMessage($toChatId, $fromUserId = false, $loadExtraData = false, $bTimeZone = true, $limit = true)
{
global $DB;
$fromUserId = intval($fromUserId);
if ($fromUserId <= 0)
$fromUserId = $this->user_id;
$toChatId = intval($toChatId);
if ($toChatId <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "ERROR_TO_CHAT_ID");
return false;
}
$orm = IMModelChatTable::getById($toChatId);
if (!($chatData = $orm->fetch()))
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
return false;
}
if ($chatData['TYPE'] == IM_MESSAGE_OPEN && !CIMMessenger::CheckEnableOpenChat())
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
return false;
}
if ($limit)
{
if ($DB->type == "MYSQL")
$sqlLimit = " AND M.DATE_CREATE > DATE_SUB(NOW(), INTERVAL 30 DAY)";
elseif ($DB->type == "MSSQL")
$sqlLimit = " AND M.DATE_CREATE > dateadd(day, -30, getdate())";
elseif ($DB->type == "ORACLE")
$sqlLimit = " AND M.DATE_CREATE > SYSDATE-30";
}
$readService = new IMV2MessageReadService($fromUserId);
$lastMessageIdInChat = $readService->getLastMessageIdInChat($toChatId);
$limitById = '';
$limitFetchMessages = 30;
$relations = CIMChat::GetRelationById($toChatId, false, $bTimeZone, false);
if (isset($relations[$fromUserId]))
{
if ($relations[$fromUserId]['START_ID'] > 0)
{
$limitById = 'AND M.ID >= '.intval($relations[$fromUserId]['START_ID']);
}
//if ($relations[$fromUserId]['STATUS'] != IM_STATUS_READ && $relations[$fromUserId]['COUNTER'] > $limitFetchMessages)
$messageCountFilter = BitrixMainORMQueryQuery::filter()
->where('ID', '>=', (int)$relations[$fromUserId]['START_ID'])
->where('ID', '>=', (int)$relations[$fromUserId]['LAST_ID'])
->where('ID', '<=', $lastMessageIdInChat)
->where('CHAT_ID', $toChatId)
;
$messageCount = BitrixImModelMessageTable::getCount($messageCountFilter);
$limitFetchMessages = max($messageCount, 30);
}
if (!$bTimeZone)
CTimeZone::Disable();
$lineId = 0;
$crmEntityType = null;
$crmEntityId = null;
if (
$chatData['TYPE'] == IM_MESSAGE_OPEN_LINE
&& BitrixMainLoader::includeModule('imopenlines')
)
{
$explodeData = explode('|', $chatData['ENTITY_DATA_1']);
$crmEntityType = ($explodeData[0] == 'Y') ? $explodeData[1] : null;
$crmEntityId = ($explodeData[0] == 'Y') ? intval($explodeData[2]) : null;
$lineId = BitrixImOpenLinesChat::parseLinesChatEntityId($chatData['ENTITY_ID'])['lineId'];
}
$strSql = "";
if ($chatData['TYPE'] == IM_MESSAGE_OPEN)
{
$strSql = "
SELECT
M.ID,
M.CHAT_ID,
M.MESSAGE,
".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE,
M.AUTHOR_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
R.USER_ID RID
FROM b_im_message M
INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN."'
LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$fromUserId."
WHERE
M.CHAT_ID = ".$toChatId."
".$limitById."
#LIMIT#
ORDER BY M.DATE_CREATE DESC
";
}
else if (
$chatData['TYPE'] == IM_MESSAGE_OPEN_LINE
&& BitrixMainLoader::includeModule('imopenlines')
&& BitrixImOpenLinesConfig::canJoin($lineId, $crmEntityType, $crmEntityId)
)
{
$strSql = "
SELECT
M.ID,
M.CHAT_ID,
M.MESSAGE,
".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE,
M.AUTHOR_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
R.USER_ID RID
FROM b_im_message M
INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN_LINE."'
LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$fromUserId."
WHERE
M.CHAT_ID = ".$toChatId."
".$limitById."
#LIMIT#
ORDER BY M.DATE_CREATE DESC
";
BitrixImDiskNoRelationPermission::add($toChatId, $fromUserId);
}
else if (isset($relations[$fromUserId]))
{
$strSql = "
SELECT
M.ID,
M.CHAT_ID,
M.MESSAGE,
".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE,
M.AUTHOR_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
'".$fromUserId."' RID
FROM b_im_message M
INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID
WHERE
M.CHAT_ID = ".$toChatId."
".$limitById."
#LIMIT#
ORDER BY M.DATE_CREATE DESC
";
}
if (!$bTimeZone)
CTimeZone::Enable();
$chatType = $chatData['TYPE'];
$chatRelationUserId = 0;
$arUsers = Array();
$arMessages = Array();
$arMessageId = Array();
$arUsersMessage = Array();
$arUnreadMessages = Array();
$readedList = Array();
if ($strSql)
{
$strSql = $DB->TopSql($strSql, $limitFetchMessages);
//LEFT JOIN b_im_message_param MP on MP.MESSAGE_ID = M.ID and MP.PARAM_NAME = 'FOR_USER_ID'
//and (MP.PARAM_VALUE is null or MP.PARAM_VALUE = '".$fromUserId."')
if ($limit)
{
$dbRes = $DB->Query(str_replace("#LIMIT#", $sqlLimit, $strSql), false, "File: ".__FILE__."
Line: ".__LINE__);
if (!$dbRes->SelectedRowsCount())
$dbRes = $DB->Query(str_replace("#LIMIT#", "", $strSql), false, "File: ".__FILE__."
Line: ".__LINE__);
}
else
{
$dbRes = $DB->Query(str_replace("#LIMIT#", "", $strSql), false, "File: ".__FILE__."
Line: ".__LINE__);
}
$lastReads = $readService
->getViewedService()
->getDateViewedByMessageIdForEachUser($lastMessageIdInChat, array_keys($relations))
;
while ($arRes = $dbRes->Fetch())
{
if ($arRes['CHAT_ENTITY_TYPE'] != 'LIVECHAT' && BitrixImUser::getInstance($fromUserId)->isConnector())
{
return false;
}
$arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
$chatType = $arRes['CHAT_TYPE'];
$chatRelationUserId = intval($arRes['RID']);
$arMessages[$arRes['ID']] = Array(
'id' => $arRes['ID'],
'chatId' => $arRes['CHAT_ID'],
'senderId' => $arRes['AUTHOR_ID'],
'recipientId' => $arRes['CHAT_ID'],
'date' => BitrixMainTypeDateTime::createFromTimestamp($arRes['DATE_CREATE']),
'text' => BitrixImText::parse($arRes['MESSAGE']),
'textLegacy' => BitrixImText::parseLegacyFormat($arRes['MESSAGE']),
);
$arMessageId[] = $arRes['ID'];
if ($arRes['AUTHOR_ID'] > 0)
{
$arUsers[] = $arRes['AUTHOR_ID'];
}
if (isset($relations[$fromUserId]) && $relations[$fromUserId]['LAST_ID'] < $arRes['ID'])
{
$arUnreadMessages['chat'.$arRes['CHAT_ID']][] = $arRes['ID'];
}
$arUsersMessage[$arRes['CHAT_ID']][] = $arRes['ID'];
foreach ($relations as $userId => $relation)
{
$readedList['chat'.$arRes['CHAT_ID']][$relation['USER_ID']] = Array(
'messageId' => $relation['LAST_ID'],
'date' => $lastReads[$userId] ?? null,
);
}
}
foreach ($arUsersMessage as $chatId => $messageIds)
{
$arUsersMessage[$chatId] = array_values(array_unique($messageIds));
}
}
if (
$chatType == IM_MESSAGE_OPEN && $chatRelationUserId <= 0
|| $chatType == IM_MESSAGE_OPEN_LINE && $chatRelationUserId <= 0
)
{
if (IMUser::getInstance($fromUserId)->isExtranet())
{
$arMessages = Array();
$arMessageId = Array();
$arUsersMessage = Array();
$loadExtraData = false;
}
else if (CModule::IncludeModule('pull'))
{
CPullWatch::Add($fromUserId, 'IM_PUBLIC_'.$toChatId, true);
}
}
$params = CIMMessageParam::Get($arMessageId);
$arFiles = Array();
foreach ($params as $messageId => $param)
{
$arMessages[$messageId]['params'] = $param;
if (
mb_strlen($arMessages[$messageId]['text']) <= 0
&& !isset($param['FILE_ID'])
&& !isset($param['KEYBOARD'])
&& !isset($param['ATTACH'])
)
{
$arMessages[$messageId]['text'] = GetMessage('IM_MESSAGE_DELETED');
$arMessages[$messageId]['params']['IS_DELETED'] = 'Y';
}
if (isset($param['FILE_ID']))
{
foreach ($param['FILE_ID'] as $fileId)
{
$arFiles[$fileId] = $fileId;
}
}
}
$arChatFiles = CIMDisk::GetFiles($toChatId, $arFiles);
$arMessages = CIMMessageLink::prepareShow($arMessages, $params);
$arResult = Array(
'chatId' => $toChatId,
'message' => $arMessages,
'usersMessage' => $arUsersMessage,
'unreadMessage' => $arUnreadMessages,
'users' => Array(),
'userInGroup' => Array(),
'readedList' => $readedList,
'files' => $arChatFiles
);
if (is_array($loadExtraData) || is_bool($loadExtraData) && $loadExtraData == true)
{
$bDepartment = true;
if (is_array($loadExtraData) && $loadExtraData['DEPARTMENT'] == 'N')
$bDepartment = false;
$arChat = self::GetChatData(array(
'ID' => $toChatId,
'USE_CACHE' => 'N'
));
if (
isset($arChat['chat'][$toChatId]) && $arChat['chat'][$toChatId]['message_type'] == IM_MESSAGE_OPEN
|| isset($arChat['chat'][$toChatId]) && $arChat['chat'][$toChatId]['message_type'] == IM_MESSAGE_OPEN_LINE
|| isset($arChat['userInChat'][$toChatId]) && in_array($fromUserId, $arChat['userInChat'][$toChatId])
)
{
$arResult['lines'] = $arChat['lines'];
$arResult['userInChat'] = $arChat['userInChat'];
$arResult['userChatBlockStatus'] = $arChat['userChatBlockStatus'];
$ar = CIMContactList::GetUserData(array(
'ID' => array_values(array_merge($arUsers, $arChat['userInChat'][$toChatId])),
'DEPARTMENT' => ($bDepartment? 'Y': 'N'),
'USE_CACHE' => 'N'
)
);
$arResult['users'] = $ar['users'];
$arResult['userInGroup'] = $ar['userInGroup'];
if ($arChat['chat'][$toChatId]['extranet'] === "")
{
$isExtranet = false;
foreach ($ar['users'] as $userData)
{
if ($userData['extranet'])
{
$isExtranet = true;
break;
}
}
IMModelChatTable::update($toChatId, Array('EXTRANET' => $isExtranet? "Y":"N"));
$arChat['chat'][$toChatId]['extranet'] = $isExtranet;
}
$arResult['chat'] = $arChat['chat'];
}
}
if ($chatData['ENTITY_TYPE'] == 'LINES' && $chatData['ENTITY_ID'] && CModule::IncludeModule('imopenlines'))
{
[, $lineId] = explode('|', $chatData["ENTITY_ID"]);
$configManager = new BitrixImOpenLinesConfig();
$arResult['openlines']['canVoteAsHead'][$lineId] = $configManager->canVoteAsHead($lineId);
}
else if ($chatData['ENTITY_TYPE'] == 'LIVECHAT' && $chatData['ENTITY_ID'] && CModule::IncludeModule('imopenlines'))
{
[$lineId, $userId] = explode('|', $chatData["ENTITY_ID"]);
$userCode = 'livechat|' . $lineId . '|' . $chatData['ID'] . '|' . $userId;
unset($lineId, $userId);
foreach ($arResult['users'] as $userId => $userData)
{
$arResult['users'][$userId] = BitrixImOpenLinesConnector::getOperatorInfo($lineId, $userId, $userCode);
}
}
return $arResult;
}