• Модуль: im
  • Путь к файлу: ~/bitrix/modules/im/classes/general/im_chat.php
  • Класс: CIMChat
  • Вызов: CIMChat::AddUser
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; }