user_id = intval($user_id); if ($user_id == 0) $this->user_id = intval($USER->GetID()); if (isset($arParams['HIDE_LINK']) && $arParams['HIDE_LINK'] == 'Y') $this->bHideLink = true; } function SearchMessage($searchText, $toUserId, $fromUserId = false, $bTimeZone = true) { global $DB; $fromUserId = intval($fromUserId); if ($fromUserId <= 0) $fromUserId = $this->user_id; $toUserId = intval($toUserId); if ($toUserId <= 0) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_ERROR_TO_USER_ID"), "ERROR_TO_USER_ID"); return false; } $searchText = trim($searchText); if (mb_strlen($searchText) < 3) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_SEARCH_EMPTY"), "ERROR_SEARCH_EMPTY"); return false; } $chatId = 0; $arMessages = Array(); $arMessageId = Array(); $arUnreadMessage = Array(); $arMessageFiles = Array(); $arUsers = Array(); $limitById = ''; if ($toUserId == $fromUserId) { $chat = new CIMChat(); $chatId = $chat->GetPersonalChat(); if (!$chatId) { return false; } $startId = 0; } else { $arRelation = \CIMChat::GetPrivateRelation($fromUserId, $toUserId); $chatId = $arRelation['CHAT_ID']; $startId = $arRelation['START_ID']; } if ($chatId > 0) { $where = [ '=CHAT_ID' => $chatId, '*%MESSAGE' => $searchText, ]; if ($this->checkFullText($searchText)) { $searchText = \Bitrix\Main\Search\Content::prepareStringToken($searchText); $where = [ '=CHAT_ID' => $chatId, '*INDEX.SEARCH_CONTENT' => $searchText, ]; } if ($startId) { $where['>=ID'] = intval($startId); } $orm = \Bitrix\Im\Model\MessageTable::getList( [ 'select' => [ 'ID', 'CHAT_ID', 'MESSAGE', 'AUTHOR_ID', 'NOTIFY_EVENT', 'DATE_CREATE' ], 'filter' => $where, 'order' => ['DATE_CREATE' => 'DESC', 'ID' => 'DESC'], 'limit' => 1000, ] ); while ($arRes = $orm->fetch()) { if ($fromUserId == $arRes['AUTHOR_ID']) { $arRes['TO_USER_ID'] = $toUserId; $arRes['FROM_USER_ID'] = $fromUserId; $convId = $arRes['TO_USER_ID']; } else { $arRes['TO_USER_ID'] = $fromUserId; $arRes['FROM_USER_ID'] = $toUserId; $convId = $arRes['FROM_USER_ID']; } $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['FROM_USER_ID'], 'recipientId' => $arRes['TO_USER_ID'], 'date' => $arRes['DATE_CREATE'], 'system' => $arRes['NOTIFY_EVENT'] == 'private'? 'N': 'Y', 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $arUsers[$convId][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; $chatId = $arRes['CHAT_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); } return Array('chatId' => $chatId, 'message' => $arMessages, 'unreadMessage' => $arUnreadMessage, 'usersMessage' => $arUsers, 'files' => $arMessageFiles); } function SearchDateMessage($searchDate, $toUserId, $fromUserId = false, $bTimeZone = true) { global $DB; $fromUserId = intval($fromUserId); if ($fromUserId <= 0) $fromUserId = $this->user_id; $toUserId = intval($toUserId); if ($toUserId <= 0) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_ERROR_TO_USER_ID"), "ERROR_TO_USER_ID"); return false; } $sqlHelper = Bitrix\Main\Application::getInstance()->getConnection()->getSqlHelper(); try { $dateStart = \Bitrix\Main\Type\DateTime::createFromUserTime($searchDate); $sqlDateStart = $sqlHelper->getCharToDateFunction($dateStart->format("Y-m-d H:i:s")); $dateEnd = $dateStart->add('1 DAY'); $sqlDateEnd = $sqlHelper->getCharToDateFunction($dateEnd->format("Y-m-d H:i:s")); } catch(\Bitrix\Main\ObjectException $e) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_SEARCH_DATE_EMPTY"), "ERROR_SEARCH_EMPTY"); return false; } $chatId = 0; $arMessages = Array(); $arMessageId = Array(); $arUnreadMessage = Array(); $arMessageFiles = Array(); $arUsers = Array(); $limitById = ''; if ($toUserId == $fromUserId) { $chat = new CIMChat(); $chatId = $chat->GetPersonalChat(); if (!$chatId) { return false; } $startId = 0; } else { $arRelation = \CIMChat::GetPrivateRelation($fromUserId, $toUserId); $chatId = $arRelation['CHAT_ID']; $startId = $arRelation['START_ID']; } if ($chatId > 0) { if ($startId > 0) { $limitById = 'AND M.ID >= '.intval($startId); } if (!$bTimeZone) CTimeZone::Disable(); $strSql = " SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID, ".$fromUserId." R1_USER_ID, ".$toUserId." R2_USER_ID, M.NOTIFY_EVENT FROM b_im_message M WHERE M.CHAT_ID = ".$chatId." AND M.DATE_CREATE >= ".$sqlDateStart." AND M.DATE_CREATE <= ".$sqlDateEnd." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; if (!$bTimeZone) CTimeZone::Enable(); $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); while ($arRes = $dbRes->Fetch()) { if ($fromUserId == $arRes['AUTHOR_ID']) { $arRes['TO_USER_ID'] = $arRes['R2_USER_ID']; $arRes['FROM_USER_ID'] = $arRes['R1_USER_ID']; $convId = $arRes['TO_USER_ID']; } else { $arRes['TO_USER_ID'] = $arRes['R1_USER_ID']; $arRes['FROM_USER_ID'] = $arRes['R2_USER_ID']; $convId = $arRes['FROM_USER_ID']; } $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['FROM_USER_ID'], 'recipientId' => $arRes['TO_USER_ID'], 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($arRes['DATE_CREATE']), 'system' => $arRes['NOTIFY_EVENT'] == 'private' ? 'N' : 'Y', 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $arUsers[$convId][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; $chatId = $arRes['CHAT_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); } return Array('chatId' => $chatId, 'message' => $arMessages, 'unreadMessage' => $arUnreadMessage, 'usersMessage' => $arUsers, 'files' => $arMessageFiles); } function GetMoreMessage($pageId, $toUserId, $fromUserId = false, $bTimeZone = true) { global $DB; $iNumPage = 1; if (intval($pageId) > 0) $iNumPage = intval($pageId); $fromUserId = intval($fromUserId); if ($fromUserId <= 0) $fromUserId = $this->user_id; $toUserId = intval($toUserId); if ($toUserId <= 0) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_ERROR_TO_USER_ID"), "ERROR_TO_USER_ID"); return false; } $chatId = 0; $arMessages = Array(); $arMessageId = Array(); $arUnreadMessage = Array(); $arMessageFiles = Array(); $arUsers = Array(); $limitById = ''; if ($toUserId == $fromUserId) { $chat = new CIMChat(); $chatId = $chat->GetPersonalChat(); if (!$chatId) { return false; } $startId = 0; } else { $arRelation = \CIMChat::GetPrivateRelation($fromUserId, $toUserId); $chatId = $arRelation['CHAT_ID'] ?? null; $startId = $arRelation['START_ID']; } if ($chatId > 0) { if ($startId > 0) { $limitById = 'AND M.ID >= '.intval($startId); } $sqlStr = " SELECT COUNT(M.ID) as CNT FROM b_im_message M WHERE M.CHAT_ID = ".$chatId." ".$limitById." "; $res_cnt = $DB->Query($sqlStr); $res_cnt = $res_cnt->Fetch(); $cnt = $res_cnt["CNT"]; if ($cnt > 0 && ceil($cnt/30) >= $iNumPage) { if (!$bTimeZone) CTimeZone::Disable(); $strSql =" SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID, M.NOTIFY_EVENT, ".$fromUserId." R1_USER_ID, ".$toUserId." R2_USER_ID FROM b_im_message M WHERE M.CHAT_ID = ".$chatId." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; if (!$bTimeZone) CTimeZone::Enable(); $dbRes = new CDBResult(); $dbRes->NavQuery($strSql, $cnt, Array('iNumPage' => $iNumPage, 'nPageSize' => 30)); while ($arRes = $dbRes->Fetch()) { if ($fromUserId == $arRes['AUTHOR_ID']) { $arRes['TO_USER_ID'] = $arRes['R2_USER_ID']; $arRes['FROM_USER_ID'] = $arRes['R1_USER_ID']; $convId = $arRes['TO_USER_ID']; } else { $arRes['TO_USER_ID'] = $arRes['R1_USER_ID']; $arRes['FROM_USER_ID'] = $arRes['R2_USER_ID']; $convId = $arRes['FROM_USER_ID']; } $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['FROM_USER_ID'], 'recipientId' => $arRes['TO_USER_ID'], 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($arRes['DATE_CREATE']), 'system' => $arRes['NOTIFY_EVENT'] == 'private'? 'N': 'Y', 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $arUsers[$convId][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; $chatId = $arRes['CHAT_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); } } return Array('chatId' => $chatId, 'message' => $arMessages, 'usersMessage' => $arUsers, 'files' => $arMessageFiles); } function RemoveMessage($messageId) { global $DB; return false; } function RemoveAllMessage($userId) { global $DB; $userId = intval($userId); if ($this->user_id == $userId) { return false; } $strSql =" SELECT MAX(M.ID)+1 MAX_ID, M.CHAT_ID, R1.ID R1_ID, R1.START_ID R1_START_ID, R2.ID R2_ID, R2.START_ID R2_START_ID FROM b_im_relation R1 INNER JOIN b_im_relation R2 on R2.CHAT_ID = R1.CHAT_ID INNER JOIN b_im_message M ON M.ID >= R1.START_ID AND M.CHAT_ID = R1.CHAT_ID WHERE R1.USER_ID = ".$this->user_id." AND R2.USER_ID = ".$userId." AND R1.MESSAGE_TYPE = '".IM_MESSAGE_PRIVATE."' GROUP BY M.CHAT_ID, R1.ID, R1.START_ID, R2.ID, R2.START_ID "; $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); if ($arRes = $dbRes->Fetch()) { $strSql = "UPDATE b_im_relation SET START_ID = ".intval($arRes['MAX_ID'])." WHERE ID = ".intval($arRes['R1_ID']); $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $counterService = new IM\V2\Message\CounterService($this->user_id); $counterService->deleteByChatId((int)$arRes['CHAT_ID']); if ($arRes['MAX_ID'] >= $arRes['R2_START_ID'] && $arRes['R2_START_ID'] > 0) { $messages = IM\Model\MessageTable::getList(array( 'select' => array('ID'), 'filter' => array( ' $arRes['R2_START_ID'], '=CHAT_ID' => $arRes['CHAT_ID'], ), )); while ($messageInfo = $messages->fetch()) { IM\Model\MessageTable::delete($messageInfo['ID']); } } $primaryKey = ['USER_ID' => $this->user_id, 'ITEM_TYPE' => IM_MESSAGE_PRIVATE, 'ITEM_ID' => $userId]; IM\Model\RecentTable::update($primaryKey, ['ITEM_MID' => 0]); } return true; } /* CHAT */ function HideAllChatMessage($chatId) { global $DB; $chatId = intval($chatId); $limitById = ''; $ar = \CIMChat::GetRelationById($chatId, $this->user_id, true, false); if ($ar && $ar['START_ID'] > 0) { $limitById = 'AND M.ID >= '.intval($ar['START_ID']); } $strSql =" SELECT MAX(M.ID)+1 MAX_ID, R1.ID R1_ID FROM b_im_relation R1 INNER JOIN b_im_message M ON M.CHAT_ID = R1.CHAT_ID WHERE R1.CHAT_ID = ".$chatId." AND R1.USER_ID = ".$this->user_id." ".$limitById." GROUP BY M.CHAT_ID, R1.ID "; $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); if ($arRes = $dbRes->Fetch()) { $strSql = "UPDATE b_im_relation SET START_ID = ".intval($arRes['MAX_ID'])." WHERE ID = ".intval($arRes['R1_ID']); $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $counterService = new IM\V2\Message\CounterService($this->user_id); $counterService->deleteByChatId((int)$arRes['CHAT_ID']); $chatType = $ar ? $ar['MESSAGE_TYPE'] : IM_MESSAGE_CHAT; $primaryKey = ['USER_ID' => $this->user_id, 'ITEM_TYPE' => $chatType, 'ITEM_ID' => $chatId]; IM\Model\RecentTable::update($primaryKey, ['ITEM_MID' => 0]); } return true; } function SearchChatMessage($searchText, $chatId, $bTimeZone = true) { $chatId = intval($chatId); $searchText = trim($searchText); if ($searchText == '') { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_SEARCH_EMPTY"), "ERROR_SEARCH_EMPTY"); return false; } if (!\Bitrix\Im\Dialog::hasAccess('chat'.$chatId, $this->user_id)) { return false; } $where = Array( '=CHAT_ID' => $chatId, '*%MESSAGE' => $searchText, ); if($this->checkFullText($searchText)) { $where = Array( '=CHAT_ID' => $chatId, '*INDEX.SEARCH_CONTENT' => \Bitrix\Main\Search\Content::prepareStringToken($searchText), ); } $ar = \CIMChat::GetRelationById($chatId, $this->user_id, true, false); if ($ar && $ar['START_ID'] > 0) { $where['>=ID'] = intval($ar['START_ID']); } $orm = \Bitrix\Im\Model\MessageTable::getList( [ 'select' => [ 'ID', 'CHAT_ID', 'MESSAGE', 'AUTHOR_ID', 'DATE_CREATE' ], 'filter' => $where, 'order' => ['DATE_CREATE' => 'DESC', 'ID' => 'DESC'], 'limit' => 1000, ] ); $arMessages = Array(); $arMessageId = Array(); $arUnreadMessage = Array(); $usersMessage = Array(); while ($arRes = $orm->fetch()) { $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['AUTHOR_ID'], 'recipientId' => $arRes['CHAT_ID'], 'date' => $arRes['DATE_CREATE'], 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $usersMessage[$arRes['CHAT_ID']][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); return Array('chatId' => $chatId, 'message' => $arMessages, 'unreadMessage' => $arUnreadMessage, 'usersMessage' => $usersMessage, 'files' => $arMessageFiles); } function SearchDateChatMessage($searchDate, $chatId, $bTimeZone = true) { global $DB; $chatId = intval($chatId); $sqlHelper = Bitrix\Main\Application::getInstance()->getConnection()->getSqlHelper(); try { $dateStart = \Bitrix\Main\Type\DateTime::createFromUserTime($searchDate); $sqlDateStart = $sqlHelper->getCharToDateFunction($dateStart->format("Y-m-d H:i:s")); $dateEnd = $dateStart->add('1 DAY'); $sqlDateEnd = $sqlHelper->getCharToDateFunction($dateEnd->format("Y-m-d H:i:s")); } catch(\Bitrix\Main\ObjectException $e) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_HISTORY_SEARCH_DATE_EMPTY"), "ERROR_SEARCH_EMPTY"); return false; } $limitById = ''; $ar = \CIMChat::GetRelationById($chatId, $this->user_id, true, false); if ($ar && $ar['START_ID'] > 0) { $limitById = 'AND M.ID >= '.intval($ar['START_ID']); } if (!$bTimeZone) CTimeZone::Disable(); $strSql =" SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID FROM b_im_relation R1 INNER JOIN b_im_message M ON M.CHAT_ID = R1.CHAT_ID WHERE R1.CHAT_ID = ".$chatId." AND R1.USER_ID = ".$this->user_id." AND M.DATE_CREATE >= ".$sqlDateStart." AND M.DATE_CREATE <= ".$sqlDateEnd." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; if (!$bTimeZone) CTimeZone::Enable(); $dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__); $arMessages = Array(); $arMessageId = Array(); $arUnreadMessage = Array(); $usersMessage = Array(); while ($arRes = $dbRes->Fetch()) { $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['AUTHOR_ID'], 'recipientId' => $arRes['CHAT_ID'], 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($arRes['DATE_CREATE']), 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $usersMessage[$arRes['CHAT_ID']][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); return Array('chatId' => $chatId, 'message' => $arMessages, 'unreadMessage' => $arUnreadMessage, 'usersMessage' => $usersMessage, 'files' => $arMessageFiles); } /** * @param $pageId * @param $chatId * @param bool $bTimeZone * @return array */ function GetMoreChatMessage($pageId, $chatId, $bTimeZone = true) { global $DB; $iNumPage = 1; if (intval($pageId) > 0) $iNumPage = intval($pageId); $chatId = intval($chatId); $orm = IM\Model\ChatTable::getById($chatId); if (!($chatData = $orm->fetch())) { $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS"); return false; } $limitById = ''; $ar = \CIMChat::GetRelationById($chatId, $this->user_id, true, false); if ($ar && $ar['START_ID'] > 0) { $limitById = 'AND M.ID >= '.intval($ar['START_ID']); } if (!$bTimeZone) CTimeZone::Disable(); if ($chatData['TYPE'] == IM_MESSAGE_OPEN) { $strCountSql =" SELECT COUNT(M.ID) as CNT FROM b_im_message M INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN."' WHERE M.CHAT_ID = ".$chatId." ".$limitById." "; $strResultSql =" SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID, C.ENTITY_TYPE CHAT_ENTITY_TYPE 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 = ".$this->user_id." WHERE M.CHAT_ID = ".$chatId." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; } else if ($chatData['TYPE'] == IM_MESSAGE_OPEN_LINE && \Bitrix\Main\Loader::includeModule('imopenlines') && \Bitrix\ImOpenLines\Config::canJoin($chatId)) { $strCountSql =" SELECT COUNT(M.ID) as CNT FROM b_im_message M INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN_LINE."' WHERE M.CHAT_ID = ".$chatId." ".$limitById." "; $strResultSql =" SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID, C.ENTITY_TYPE CHAT_ENTITY_TYPE 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 = ".$this->user_id." WHERE M.CHAT_ID = ".$chatId." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; } else { $strCountSql =" SELECT COUNT(M.ID) as CNT FROM b_im_message M INNER JOIN b_im_relation R1 ON M.CHAT_ID = R1.CHAT_ID WHERE R1.CHAT_ID = ".$chatId." AND R1.USER_ID = ".$this->user_id." ".$limitById." "; $strResultSql =" SELECT M.ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID, C.ENTITY_TYPE CHAT_ENTITY_TYPE FROM b_im_message M LEFT JOIN b_im_chat C ON M.CHAT_ID = C.ID WHERE M.CHAT_ID = ".$chatId." ".$limitById." ORDER BY M.DATE_CREATE DESC, M.ID DESC "; } if (!$bTimeZone) CTimeZone::Enable(); $res_cnt = $DB->Query($strCountSql); $res_cnt = $res_cnt->Fetch(); $cnt = $res_cnt["CNT"]; $arMessages = Array(); $arMessageFiles = Array(); $arMessageId = Array(); $usersMessage = Array(); if ($cnt > 0 && ceil($cnt/30) >= $iNumPage) { $dbRes = new CDBResult(); $dbRes->NavQuery($strResultSql, $cnt, Array('iNumPage' => $iNumPage, 'nPageSize' => 30)); while ($arRes = $dbRes->Fetch()) { if ($arRes['CHAT_ENTITY_TYPE'] != 'LIVECHAT' && \Bitrix\Im\User::getInstance($this->user_id)->isConnector()) { return false; } $arMessages[$arRes['ID']] = Array( 'id' => $arRes['ID'], 'chatId' => $arRes['CHAT_ID'], 'senderId' => $arRes['AUTHOR_ID'], 'recipientId' => $arRes['CHAT_ID'], 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($arRes['DATE_CREATE']), 'system' => $arRes['AUTHOR_ID'] > 0? 'N': 'Y', 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $usersMessage[$arRes['CHAT_ID']][] = $arRes['ID']; $arMessageId[] = $arRes['ID']; $arUsersIds[] = $arRes['AUTHOR_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); } $users = CIMContactList::GetUserData(array( 'ID' => $arUsersIds, 'DEPARTMENT' => 'Y', 'USE_CACHE' => 'N', 'PHONES' => IsModuleInstalled('voximplant')? 'Y': 'N' )); return Array( 'chatId' => $chatId, 'message' => $arMessages, 'usersMessage' => $usersMessage, 'users' => $users['users'], 'userInGroup' => $users['userInGroup'], 'phones' => $users['phones'], 'files' => $arMessageFiles ); } /* COMMON */ public function GetMessagesByDate($chatId, $date, $messageStart = 0, $timezone = true) { $chatId = intval($chatId); $messageStart = intval($messageStart); if ($date instanceof \Bitrix\Main\Type\DateTime) { $checkDate = $date; $dateSql = $checkDate->format("Y-m-d H:i:s"); } else { $checkDate = new \Bitrix\Main\Type\DateTime($date, "Y-m-d H:i:s"); $dateSql = $checkDate->format("Y-m-d H:i:s"); if ($dateSql != $date) { return false; } } $chatData = CIMChat::GetChatData(Array('ID' => $chatId, 'USER_ID' => $this->user_id)); if (empty($chatData['chat'])) return false; $dialogId = 0; $chatType = IM_MESSAGE_CHAT; if ($chatData['chat'][$chatId]['type'] == 'private') { $chatType = IM_MESSAGE_PRIVATE; foreach ($chatData['userInChat'][$chatId] as $userId) { if ($userId != $this->user_id) { $dialogId = $userId; break; } } if (!$dialogId) { return false; } } else { $dialogId = 'chat'.$chatId; } $chatSql = str_pad($chatId, 11, '0', STR_PAD_LEFT); global $DB; if (!$timezone) CTimeZone::Disable(); $sql = " SELECT IF (M.ID > 0, 'Y', 'N') MESSAGE_EXISTS, IF (M.ID > R.LAST_ID, 'N', 'Y') MESSAGE_READ, C.TYPE CHAT_TYPE, MS.MESSAGE_ID ID, M.CHAT_ID, M.MESSAGE, ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." DATE_CREATE, M.AUTHOR_ID FROM b_im_message_param MS LEFT JOIN b_im_message M ON M.ID = MS.MESSAGE_ID LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID and R.USER_ID = ".$this->user_id." LEFT JOIN b_im_chat C ON C.ID = M.CHAT_ID WHERE MS.PARAM_NAME='TS' and MS.PARAM_VALUE between '".$chatSql." ".$dateSql."' and '".$chatSql." 9999-99-99 99:99:99' ".($messageStart > 0? 'MS.MESSAGE_ID >= '.$messageStart: "")." "; if (!$timezone) CTimeZone::Enable(); $result = $DB->Query($sql, false, "File: ".__FILE__."
Line: ".__LINE__); $arMessages = Array(); $arMessageUnread = Array(); $arMessageDelete = Array(); $arMessageId = Array(); $usersMessage = Array(); $arUsersIds = Array(); while ($message = $result->Fetch()) { if ($message['MESSAGE_EXISTS'] == 'N') { $arMessageDelete[] = $message['ID']; continue; } if ($message['MESSAGE_READ'] == 'N') { $arMessageUnread[$dialogId][] = $message['ID']; } if ($message['CHAT_TYPE'] == IM_MESSAGE_PRIVATE) { $recipientId = $message['AUTHOR_ID'] == $this->user_id? $dialogId: $this->user_id; } else { $recipientId = $message['CHAT_ID']; } $arMessages[$message['ID']] = Array( 'id' => $message['ID'], 'chatId' => $message['CHAT_ID'], 'senderId' => $message['AUTHOR_ID'], 'recipientId' => $recipientId, 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($message['DATE_CREATE']), 'system' => $message['AUTHOR_ID'] > 0? 'N': 'Y', 'text' => \Bitrix\Im\Text::parse($message['MESSAGE']), 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']) ); $usersMessage[$dialogId][] = $message['ID']; $arMessageId[] = $message['ID']; $arUsersIds[] = $message['AUTHOR_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); $users = CIMContactList::GetUserData(array( 'ID' => $arUsersIds, 'DEPARTMENT' => 'Y', 'USE_CACHE' => 'N', 'PHONES' => IsModuleInstalled('voximplant')? 'Y': 'N' )); return Array( 'chatId' => $chatId, 'dialogId' => $dialogId, 'message' => $arMessages, 'usersMessage' => $usersMessage, 'unreadMessage' => $arMessageUnread, 'messageDelete' => $arMessageDelete, 'files' => $arMessageFiles, 'users' => $users['users'], 'userInGroup' => $users['userInGroup'], 'phones' => $users['phones'], 'lines' => $chatType == IM_MESSAGE_PRIVATE? Array(): $chatData['lines'], 'chat' => $chatType == IM_MESSAGE_PRIVATE? Array(): $chatData['chat'], 'userInChat' => $chatType == IM_MESSAGE_PRIVATE? Array(): $chatData['userInChat'], 'userCallStatus' => $chatType == IM_MESSAGE_PRIVATE? Array(): $chatData['userCallStatus'], 'userChatBlockStatus' => $chatType == IM_MESSAGE_PRIVATE? Array(): $chatData['userChatBlockStatus'], ); } public function GetRelatedMessages($messageId, $previous = 10, $next = 10, $timezone = true, $textParser = true) { $message = \Bitrix\Im\Model\MessageTable::getList(Array( 'select' => Array( 'ID','DATE_CREATE', 'CHAT_ID', 'AUTHOR_ID', 'CHAT_TYPE' => 'CHAT.TYPE', 'CHAT_ENTITY_TYPE' => 'CHAT.ENTITY_TYPE', 'CHAT_ENTITY_DATA_1' => 'CHAT.ENTITY_DATA_1', ), 'filter' => Array( '=ID' => $messageId )) )->fetch(); if (!$message) { return false; } $relations = CIMChat::GetRelationById($message['CHAT_ID'], false, true, false); if (!isset($relations[$this->user_id])) { if ( $message['CHAT_ENTITY_TYPE'] == 'LINES' && \Bitrix\Main\Loader::includeModule('imopenlines') ) { $explodeData = explode('|', $message['CHAT_ENTITY_DATA_1']); $crmEntityType = ($explodeData[0] == 'Y') ? $explodeData[1] : null; $crmEntityId = ($explodeData[0] == 'Y') ? intval($explodeData[2]) : null; if (!\Bitrix\ImOpenLines\Config::canJoin($message['CHAT_ID'], $crmEntityType, $crmEntityId)) { return false; } } else { return false; } } elseif ((int)$messageId < (int)$relations[$this->user_id]['START_ID']) { return false; } $dialogId = 0; if ($message['CHAT_TYPE'] == IM_MESSAGE_PRIVATE) { if($message['CHAT_ENTITY_TYPE'] == IM_CHAT_TYPE_PERSONAL) { $dialogId = $this->user_id; } if ($message['AUTHOR_ID'] != $this->user_id) { $dialogId = $message['AUTHOR_ID']; } else { foreach ($relations as $userId => $data) { if ($userId != $this->user_id) { $dialogId = $userId; break; } } if (!$dialogId) { return false; } } } else { $dialogId = 'chat'.$message['CHAT_ID']; } $previousMessages = $this->GetPreviousMessages($messageId, $message['CHAT_ID'], $message['DATE_CREATE'], $previous, $timezone); $nextMessages = $this->GetNextMessages($messageId, $message['CHAT_ID'], $message['DATE_CREATE'], $next, $timezone); $startId = (int)($relations[$this->user_id]['START_ID'] ?? 0); if ($startId > 0) { $previousMessages = array_filter($previousMessages, static fn (array $message) => (int)$message['ID'] >= $startId); } $messages = array_replace($previousMessages, $nextMessages); $chatId = $message['CHAT_ID']; $arMessages = Array(); $arMessageFiles = Array(); $arMessageId = Array(); $usersMessage = Array(); $arUsersIds = Array(); foreach ($messages as $mess) { if ($message['CHAT_TYPE'] == IM_MESSAGE_PRIVATE) { $recipientId = $mess['AUTHOR_ID'] == $this->user_id? $dialogId: $this->user_id; } else { $recipientId = $mess['CHAT_ID']; } $arMessages[$mess['ID']] = Array( 'id' => $mess['ID'], 'chatId' => $mess['CHAT_ID'], 'senderId' => $mess['AUTHOR_ID'], 'recipientId' => $recipientId, 'date' => \Bitrix\Main\Type\DateTime::createFromTimestamp($mess['DATE_CREATE']), 'system' => $mess['AUTHOR_ID'] > 0? 'N': 'Y', 'text' => $textParser? \Bitrix\Im\Text::parse($mess['MESSAGE']): $mess['MESSAGE'], 'textLegacy' => $textParser? \Bitrix\Im\Text::parseLegacyFormat($mess['MESSAGE']): $mess['MESSAGE'] ); $usersMessage[$dialogId][] = $mess['ID']; $arMessageId[] = $mess['ID']; $arUsersIds[] = $mess['AUTHOR_ID']; } $params = CIMMessageParam::Get($arMessageId); $arFiles = Array(); foreach ($params as $messageId => $param) { $arMessages[$messageId]['params'] = $param; if (isset($param['FILE_ID'])) { foreach ($param['FILE_ID'] as $fileId) { $arFiles[$fileId] = $fileId; } } } $arMessageFiles = CIMDisk::GetFiles($chatId, $arFiles); $arMessages = CIMMessageLink::prepareShow($arMessages, $params); $users = CIMContactList::GetUserData(array( 'ID' => $arUsersIds, 'DEPARTMENT' => 'Y', 'USE_CACHE' => 'N', 'PHONES' => IsModuleInstalled('voximplant')? 'Y': 'N' )); return Array( 'chatId' => $chatId, 'dialogId' => $dialogId, 'message' => $arMessages, 'usersMessage' => $usersMessage, 'files' => $arMessageFiles, 'users' => $users['users'], 'userInGroup' => $users['userInGroup'], 'phones' => $users['phones'], ); } private function GetPreviousMessages($messageId, $chatId = null, $dateCreate = null, $limit = 10, $timezone = true) { global $DB; if (is_null($chatId) || !is_object($dateCreate)) { $message = \Bitrix\Im\Model\MessageTable::getList(Array('select' => Array('DATE_CREATE', 'CHAT_ID'), 'filter' => Array('=ID' => $messageId)))->fetch(); if (!$message) return false; $chatId = $message['CHAT_ID']; $dateCreate = $message['DATE_CREATE']; } else { $chatId = intval($chatId); } $limit = intval($limit)+1; if (!$timezone) CTimeZone::Disable(); $sql = "SELECT ID, CHAT_ID, MESSAGE, ".$DB->DatetimeToTimestampFunction('DATE_CREATE')." DATE_CREATE, AUTHOR_ID FROM b_im_message WHERE CHAT_ID = ".$chatId." and DATE_CREATE <= '".$dateCreate->format('Y-m-d H:i:s')."' ORDER BY CHAT_ID, DATE_CREATE desc LIMIT ".$limit; if (!$timezone) CTimeZone::Enable(); $result = $DB->Query($sql, false, "File: ".__FILE__."
Line: ".__LINE__); $messages = array(); while ($message = $result->Fetch()) { $messages[$message['ID']] = $message; } asort($messages); return $messages; } private function GetNextMessages($messageId, $chatId = null, $dateCreate = null, $limit = 10, $timezone = true) { global $DB; if (is_null($chatId) || !is_object($dateCreate)) { $message = \Bitrix\Im\Model\MessageTable::getList(Array('select' => Array('DATE_CREATE', 'CHAT_ID'), 'filter' => Array('=ID' => $messageId)))->fetch(); if (!$message) return false; $chatId = $message['CHAT_ID']; $dateCreate = $message['DATE_CREATE']; } else { $chatId = intval($chatId); } $limit = intval($limit)+1; if (!$timezone) CTimeZone::Disable(); $sql = "SELECT ID, CHAT_ID, MESSAGE, ".$DB->DatetimeToTimestampFunction('DATE_CREATE')." DATE_CREATE, AUTHOR_ID FROM b_im_message WHERE CHAT_ID = ".$chatId." and DATE_CREATE >= '".$dateCreate->format('Y-m-d H:i:s')."' ORDER BY CHAT_ID, DATE_CREATE asc LIMIT ".$limit; if (!$timezone) CTimeZone::Enable(); $result = $DB->Query($sql, false, "File: ".__FILE__."
Line: ".__LINE__); $messages = array(); while ($message = $result->Fetch()) { $messages[$message['ID']] = $message; } return $messages; } private function checkFullText($searchText) { $indexEnabled = \Bitrix\Main\Config\Option::get('im', 'message_history_index'); if ( $indexEnabled && \CIMMessenger::IsMysqlDb() && \Bitrix\Main\Search\Content::canUseFulltextSearch($searchText) && \Bitrix\Im\Model\MessageIndexTable::getEntity()->fullTextIndexEnabled("SEARCH_CONTENT") ) { return true; } return false; } } ?>