public function AddUser($chatId, $userId, $hideHistory = null, $skipMessage = false, $skipRecent = false)
{
global $DB;
$chatId = intval($chatId);
if ($chatId <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "EMPTY_CHAT_ID");
return false;
}
$arUserId = Array();
if (is_array($userId))
{
$arUserId = CIMContactList::PrepareUserIds($userId);
}
else if (intval($userId) > 0)
{
$arUserId[intval($userId)] = intval($userId);
}
if ($this->user_id > 0)
{
$arUserId[$this->user_id] = $this->user_id;
}
if (count($arUserId) <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_USER_ID"), "EMPTY_USER_ID");
return false;
}
if ($this->user_id > 0 && !IsModuleInstalled('intranet') && CModule::IncludeModule('socialnetwork') && CSocNetUser::IsFriendsAllowed())
{
$arFriendUsers = Array();
$dbFriends = CSocNetUserRelations::GetList(array(),array("USER_ID" => $this->user_id, "RELATION" => SONET_RELATIONS_FRIEND), false, false, array("ID", "FIRST_USER_ID", "SECOND_USER_ID", "DATE_CREATE", "DATE_UPDATE", "INITIATED_BY"));
while ($arFriends = $dbFriends->Fetch())
{
$friendId = $this->user_id == $arFriends["FIRST_USER_ID"]? $arFriends["SECOND_USER_ID"]: $arFriends["FIRST_USER_ID"];
$arFriendUsers[$friendId] = $friendId;
}
foreach ($arUserId as $id => $uid)
{
if ($uid == $this->user_id)
continue;
if (!isset($arFriendUsers[$uid]) && CIMSettings::GetPrivacy(CIMSettings::PRIVACY_CHAT, $uid) == CIMSettings::PRIVACY_RESULT_CONTACT)
unset($arUserId[$id]);
}
if (count($arUserId) <= 0)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_USER_ID_BY_PRIVACY"), "EMPTY_USER_ID_BY_PRIVACY");
return false;
}
}
if ($this->user_id > 0)
{
$strSql = "
SELECT
C.ID CHAT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.TITLE CHAT_TITLE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.EXTRANET CHAT_EXTRANET,
C.DISK_FOLDER_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
C.MESSAGE_COUNT CHAT_MESSAGE_COUNT,
".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." CHAT_DATE_CREATE
FROM b_im_chat C
WHERE C.TYPE = '".IM_MESSAGE_OPEN."' AND C.ID = ".$chatId."
";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
$arRes = $dbRes->Fetch();
if ($arRes)
{
if (BitrixImUser::getInstance()->isExtranet())
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_AUTHORIZE_ERROR"), "AUTHORIZE_ERROR");
return false;
}
}
else
{
$strSql = "
SELECT
R.CHAT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.TITLE CHAT_TITLE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.EXTRANET CHAT_EXTRANET,
C.DISK_FOLDER_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_ID CHAT_ENTITY_ID,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
C.MESSAGE_COUNT CHAT_MESSAGE_COUNT,
".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." CHAT_DATE_CREATE
FROM b_im_relation R
LEFT JOIN b_im_chat C ON R.CHAT_ID = C.ID
WHERE
".($this->user_id > 0? "R.USER_ID = ".$this->user_id." AND ": "")."
R.MESSAGE_TYPE IN ('".IM_MESSAGE_OPEN."','".IM_MESSAGE_CHAT."','".IM_MESSAGE_OPEN_LINE."')
AND R.CHAT_ID = ".$chatId."
";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
$arRes = $dbRes->Fetch();
}
}
else
{
$strSql = "
SELECT
C.ID CHAT_ID,
C.PARENT_MID CHAT_PARENT_MID,
C.TITLE CHAT_TITLE,
C.AUTHOR_ID CHAT_AUTHOR_ID,
C.EXTRANET CHAT_EXTRANET,
C.DISK_FOLDER_ID,
C.TYPE CHAT_TYPE,
C.ENTITY_TYPE CHAT_ENTITY_TYPE,
C.ENTITY_ID CHAT_ENTITY_ID,
C.ENTITY_DATA_1 CHAT_ENTITY_DATA_1,
C.ENTITY_DATA_2 CHAT_ENTITY_DATA_2,
C.ENTITY_DATA_3 CHAT_ENTITY_DATA_3,
C.MESSAGE_COUNT CHAT_MESSAGE_COUNT,
".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." CHAT_DATE_CREATE
FROM b_im_chat C
WHERE C.TYPE IN ('".IM_MESSAGE_OPEN."','".IM_MESSAGE_CHAT."','".IM_MESSAGE_OPEN_LINE."') AND C.ID = ".$chatId."
";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
$arRes = $dbRes->Fetch();
}
if (!$arRes)
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_AUTHORIZE_ERROR"), "AUTHORIZE_ERROR");
return false;
}
$arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
$chatEntityType = $arRes['CHAT_ENTITY_TYPE'] ;
$chatParentMessageId = $arRes['CHAT_PARENT_MID'] ;
if ($chatEntityType == 'LINES')
{
foreach ($arUserId as $id => $uid)
{
if (
!BitrixImUser::getInstance($uid)->isConnector() &&
(BitrixImUser::getInstance($uid)->isExtranet() || BitrixImUser::getInstance($uid)->isNetwork())
)
{
unset($arUserId[$id]);
}
}
}
$extranetFlag = false;
if (!in_array($chatEntityType, Array('LINES', 'LIVECHAT')))
{
$extranetFlag = $arRes["CHAT_EXTRANET"] == ""? "": ($arRes["CHAT_EXTRANET"] == "Y"? true: false);
}
$chatTitle = BitrixImText::decodeEmoji($arRes['CHAT_TITLE']);
$chatAuthorId = intval($arRes['CHAT_AUTHOR_ID']);
$chatType = $arRes['CHAT_TYPE'];
$arRelation = self::GetRelationById($chatId, false, true, false);
$arExistUser = Array();
foreach ($arRelation as $relation)
$arExistUser[] = $relation['USER_ID'];
$arUserId = array_diff($arUserId, $arExistUser);
if (empty($arUserId))
{
$GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_NOTHING_TO_ADD"), "NOTHING_TO_ADD");
return false;
}
$arUserSelect = $arUserId;
if ($this->user_id > 0)
{
$arUserSelect[] = $this->user_id;
}
if ($chatEntityType === 'VIDEOCONF')
{
$wasUserBlocked = IMModelBlockUserTable::getList(
[
'select' => ['ID'],
'filter' => [
'=CHAT_ID' => $chatId,
'@USER_ID' => new BitrixMainDBSqlExpression(implode(', ', $arUserId))
]
]
)->fetchAll();
if (count($wasUserBlocked) === 1)
{
IMModelBlockUserTable::delete($wasUserBlocked[0]['ID']);
}
else if (count($wasUserBlocked) > 1)
{
foreach ($wasUserBlocked as $blockedUser)
{
IMModelBlockUserTable::delete($blockedUser['ID']);
}
}
}
$arUsers = CIMContactList::GetUserData(array(
'ID' => array_values($arUserSelect),
'DEPARTMENT' => 'N',
'USE_CACHE' => 'N'
));
$arUsers = $arUsers['users'];
if ($extranetFlag !== true)
{
$isExtranet = false;
if ($chatEntityType !== 'VIDEOCONF')
{
foreach ($arUsers as $userData)
{
if ($userData['extranet'])
{
$isExtranet = true;
break;
}
}
}
if ($isExtranet || $extranetFlag === "")
{
IMModelChatTable::update($chatId, Array('EXTRANET' => $isExtranet? "Y":"N"));
}
$extranetFlag = $isExtranet;
}
$arUsersName = Array();
foreach ($arUserId as $uid)
{
$arUsersName[] = '[USER='.$uid.'][/USER]';
}
$message = '';
if ($this->user_id > 0)
{
$message = GetMessage("IM_CHAT_JOIN_".$arUsers[$this->user_id]['gender'], Array('#USER_1_NAME#' => htmlspecialcharsback($arUsers[$this->user_id]['name']), '#USER_2_NAME#' => implode(', ', $arUsersName)));
}
else
{
if ($skipMessage)
{
$message = '';
}
else if ($chatId == self::GetGeneralChatId())
{
if (self::GetGeneralChatAutoMessageStatus(self::GENERAL_MESSAGE_TYPE_JOIN))
{
if (count($arUsersName) > 1)
{
$message = GetMessage("IM_CHAT_GENERAL_JOIN_PLURAL", Array('#USERS_NAME#' => implode(', ', $arUsersName)));
}
else
{
$arUserList = array_values($arUserId);
$joinMessage = "IM_CHAT_GENERAL_JOIN";
if ($arUsers[$arUserList[0]]['gender'] == 'F')
{
$joinMessage .= '_F';
}
$message = GetMessage($joinMessage, Array('#USER_NAME#' => implode(', ', $arUsersName)));
}
}
}
else
{
if (count($arUsersName) > 1)
{
$message = GetMessage("IM_CHAT_SELF_JOIN", Array('#USERS_NAME#' => implode(', ', $arUsersName)));
}
else
{
$arUserList = array_values($arUserId);
$message = GetMessage("IM_CHAT_SELF_JOIN_".$arUsers[$arUserList[0]]['gender'], Array('#USER_NAME#' => implode(', ', $arUsersName)));
}
}
}
$fileMaxId = 0;
if ((int)$arRes['DISK_FOLDER_ID'] > 0)
{
$fileMaxId = CIMDisk::getMaxFileId($chatId);
}
$startId = 0;
$maxId = 0;
$strSql = "SELECT MAX(ID) ID FROM b_im_message WHERE CHAT_ID = ".$chatId." GROUP BY CHAT_ID";
$dbRes = $DB->Query($strSql, false, "File: ".__FILE__."
Line: ".__LINE__);
if ($arMax = $dbRes->Fetch())
{
$startId = $arMax['ID']+1;
$maxId = $arMax['ID'];
}
$publicPullWatch = false;
if (($chatType == IM_MESSAGE_OPEN || $chatType == IM_MESSAGE_OPEN_LINE) && CModule::IncludeModule("pull"))
{
$publicPullWatch = true;
}
if ($chatEntityType == 'LINES' || $arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN_LINE)
{
$hideHistory = false;
}
else if (is_null($hideHistory))
{
$hideHistory = CIMSettings::GetStartChatMessage() == CIMSettings::START_MESSAGE_LAST && $arRes['CHAT_TYPE'] == IM_MESSAGE_CHAT;
}
if ($this->user_id > 0 && !$hideHistory && $arRelation[$this->user_id]['START_ID'] > 0)
{
$hideHistory = true;
$startId = $arRelation[$this->user_id]['START_ID'];
}
foreach ($arUserId as $uid)
{
if ($publicPullWatch)
{
CPullWatch::Delete($uid, 'IM_PUBLIC_'.$chatId);
}
$hideHistoryFlag = $hideHistory;
if ($chatEntityType != 'LINES' && $arRes['CHAT_TYPE'] != IM_MESSAGE_PRIVATE && BitrixImUser::getInstance($uid)->isExtranet())
{
$hideHistoryFlag = true;
}
$startCounter = 0;
if ($hideHistoryFlag && $startId > 0)
{
$startCounter = (int)$arRes['CHAT_MESSAGE_COUNT'];
}
$orm = IMModelRelationTable::add(array(
"CHAT_ID" => $chatId,
"MESSAGE_TYPE" => $arRes['CHAT_TYPE'],
"USER_ID" => $uid,
"START_ID" => $hideHistoryFlag? $startId: 0,
"LAST_ID" => $maxId,
//"LAST_SEND_ID" => $maxId,
"LAST_FILE_ID" => $hideHistoryFlag? $fileMaxId: 0,
"START_COUNTER" => $startCounter
));
$relationId = $orm->getId();
if ($arRes['CHAT_TYPE'] != IM_MESSAGE_OPEN)
{
CIMContactList::CleanChatCache($uid);
}
}
if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
{
CIMContactList::CleanAllChatCache();
}
$newUsersCount = $this->getChatActiveUserCount($chatId);
$this->updateChatUserCount($chatId, $newUsersCount);
if (CModule::IncludeModule("pull"))
{
$pushMessage = Array(
'module_id' => 'im',
'command' => 'chatUserAdd',
'params' => Array(
'chatId' => $chatId,
'dialogId' => 'chat'.$chatId,
'chatTitle' => $chatTitle,
'chatOwner' => $chatAuthorId,
'chatExtranet' => $extranetFlag == 'Y',
'users' => $arUsers,
'newUsers' => array_values($arUserId),
'userCount' => $newUsersCount
),
'extra' => BitrixImCommon::getPullExtra()
);
if ($chatEntityType == 'LINES')
{
foreach ($arRelation as $rel)
{
if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
{
unset($arRelation[$rel["USER_ID"]]);
}
}
}
BitrixPullEvent::add(array_merge(array_keys($arRelation), array_keys($arUsers)), $pushMessage);
if ($chatType == IM_MESSAGE_OPEN || $chatType == IM_MESSAGE_OPEN_LINE)
{
CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pushMessage);
}
}
if ($message)
{
$lastId = self::AddMessage(Array(
"TO_CHAT_ID" => $chatId,
"MESSAGE" => $message,
"FROM_USER_ID" => $this->user_id,
"SYSTEM" => 'Y',
"RECENT_ADD" => $skipRecent? 'N': 'Y',
"PARAMS" => Array(
"CODE" => 'CHAT_JOIN',
"NOTIFY" => $chatEntityType == 'LINES'? 'Y': 'N',
),
"PUSH" => 'N',
"SKIP_USER_CHECK" => 'Y',
));
}
else
{
$lastId = 0;
}
CIMDisk::ChangeFolderMembers($chatId, $arUserId);
foreach ($arUserId as $uid)
{
if (IMUser::getInstance($uid)->isBot())
{
IMBot::changeChatMembers($chatId, $uid);
IMBot::onJoinChat('chat'.$chatId, Array(
'CHAT_TYPE' => $chatType,
'MESSAGE_TYPE' => $chatType,
'BOT_ID' => $uid,
'USER_ID' => $this->user_id,
'CHAT_ID' => $chatId,
"CHAT_AUTHOR_ID" => $arRes['CHAT_AUTHOR_ID'],
"CHAT_ENTITY_TYPE" => $arRes['CHAT_ENTITY_TYPE'],
"CHAT_ENTITY_ID" => $arRes['CHAT_ENTITY_ID'],
"ACCESS_HISTORY" => $hideHistoryFlag? false: true,
));
}
}
if (
in_array($arRes['CHAT_TYPE'], [BitrixImChat::TYPE_OPEN, BitrixImChat::TYPE_GROUP])
&& $arRes['CHAT_ENTITY_TYPE'] != 'LIVECHAT'
)
{
self::updateChatIndex($chatId);
}
if (!empty($chatEntityType))
{
$eventCode = str_replace('_', '', ucfirst(ucwords(mb_strtolower($chatEntityType), '_')));
foreach(GetModuleEvents("im", "OnChatUserAddEntityType".$eventCode, true) as $arEvent)
{
ExecuteModuleEventEx($arEvent, array([
'CHAT_ID' => $chatId,
'NEW_USERS' => $arUserId,
]));
}
}
IMV2Chat::cleanAccessCache($chatId);
return true;
}