20use Bitrix\Im\Model\EO_Chat;
26use Bitrix\Im\V2\Common\ContextCustomer;
27use Bitrix\Im\V2\Common\ActiveRecordImplementation;
28use Bitrix\Im\V2\Common\RegistryEntryImplementation;
48 use RegistryEntryImplementation;
49 use ActiveRecordImplementation
66 self::IM_TYPE_PRIVATE,
68 self::IM_TYPE_COMMENT,
69 self::IM_TYPE_OPEN_LINE,
71 self::IM_TYPE_CHANNEL,
73 self::IM_TYPE_COPILOT,
77 'PRIVATE' => self::IM_TYPE_PRIVATE,
78 'CHAT' => self::IM_TYPE_CHAT,
79 'COMMENT' => self::IM_TYPE_COMMENT,
80 'OPENLINE' => self::IM_TYPE_OPEN_LINE,
81 'SYSTEM' => self::IM_TYPE_SYSTEM,
82 'NOTIFY' => self::IM_TYPE_SYSTEM,
83 'CHANNEL' => self::IM_TYPE_CHANNEL,
84 'OPEN' => self::IM_TYPE_OPEN,
85 'COPILOT' => self::IM_TYPE_COPILOT,
101 self::ENTITY_TYPE_LINE,
102 self::ENTITY_TYPE_LIVECHAT,
103 self::ENTITY_TYPE_FAVORITE,
104 self::ENTITY_TYPE_VIDEOCONF,
128 'conferencePassword',
144 private const CHUNK_SIZE = 1000;
262 $this->initByDefault();
266 $this->
load($source);
269 $this->messageRegistry =
new Registry;
289 if (isset(self::$chatStaticCache[$chatId]))
291 return self::$chatStaticCache[$chatId];
301 self::$chatStaticCache[$chatId] = $chat;
303 return self::$chatStaticCache[$chatId];
308 unset(self::$chatStaticCache[$id]);
311 Im\V2\Chat\EntityLink::cleanCache($id);
316 if (isset(self::$chatStaticCache[$chatId]))
318 self::$chatStaticCache[$chatId]->accessCache = [];
325 $result = $this->defaultSave();
327 if (!$result->isSuccess())
334 self::cleanCache($id);
347 return isset($this->chatId);
358 !count($this->usersIds ?? [])
359 || in_array($this->entityType, [self::ENTITY_TYPE_LINE, self::ENTITY_TYPE_LIVECHAT])
360 || in_array($this->type, [self::IM_TYPE_OPEN_LINE])
366 $userIds = \CIMContactList::PrepareUserIds($this->usersIds);
367 $users = \CIMContactList::GetUserData([
368 'ID' => array_values($userIds),
372 foreach ($users[
'users'] as $user)
374 if ($user[
'extranet'])
385 if (is_array($userIds) && count($userIds))
387 $userIds = filter_var(
391 'flags' => FILTER_REQUIRE_ARRAY,
392 'options' => [
'min_range' => 1]
396 foreach ($userIds as $key => $userId)
398 if (!is_int($userId))
400 unset($userIds[$key]);
405 $this->usersIds = array_unique($userIds);
412 return $this->usersIds;
419 return $this->aliasName;
424 $this->aliasName = $aliasName;
436 return $alias[
'ALIAS'] ??
null;
441 if (!isset($this->markedId))
446 return $this->markedId;
451 if (isset($this->role))
458 $this->role = self::ROLE_OWNER;
465 if ($selfRelation ===
null)
467 $this->role = self::ROLE_GUEST;
469 elseif ($selfRelation->getManager())
471 $this->role = self::ROLE_MANAGER;
475 $this->role = self::ROLE_MEMBER;
485 CGlobalCounter::Increment(
'im_chat_color_id', CGlobalCounter::ALL_SITES,
false);
486 $chatColorId = CGlobalCounter::GetValue(
'im_chat_color_id', CGlobalCounter::ALL_SITES);
503 if (isset($this->accessCache[$userId]))
505 return $this->accessCache[$userId];
510 $this->accessCache[$userId] =
false;
517 return $this->accessCache[$userId];
530 $userId = $this->getContext()->getUserId();
532 elseif (is_numeric($user))
534 $userId = (int)$user;
536 elseif ($user instanceof
User)
538 $userId = $user->getId();
554 return $this->messageRegistry;
563 if (isset($this->messageRegistry[$messageId]))
565 return $this->messageRegistry[$messageId];
571 $loadResult = $message->load($messageId);
572 if ($loadResult->isSuccess())
620 public function riseInRecent(
Message $message): void
623 foreach ($this->getRelations() as $relation)
630 if ($this->getEntityType() == self::ENTITY_TYPE_LINE)
632 if (
User::getInstance($relation->getUserId())->getExternalAuthId() ==
'imconnector')
638 \CIMContactList::SetRecent([
639 'ENTITY_ID' => $this->getChatId(),
641 'CHAT_TYPE' => $this->getType(),
642 'USER_ID' => $relation->getUserId(),
643 'CHAT_ID' => $relation->getChatId(),
644 'RELATION_ID' => $relation->getId(),
647 if ($relation->getUserId() == $message->
getAuthorId())
661 public static function fillRole(array $chats, ?
int $userId =
null): void
665 $userId ??= Im\V2\Entity\User\User::getCurrent()->getId();
667 foreach ($chats as $chat)
669 if ($chat->getAuthorId() === $userId)
671 $chat->role = self::ROLE_OWNER;
675 $id = $chat->getId();
676 $chatIdsToFill[$id] = $id;
680 if (empty($chatIdsToFill))
685 $result = RelationTable::query()
686 ->setSelect([
'CHAT_ID',
'MANAGER'])
687 ->where(
'USER_ID', $userId)
688 ->whereIn(
'CHAT_ID', $chatIdsToFill)
693 foreach ($result as $row)
695 $isManager[(int)$row[
'CHAT_ID']] = $row[
'MANAGER'] ===
'Y';
698 foreach ($chats as $chat)
700 if (!isset($chatIdsToFill[$chat->getId()]))
704 if (!isset($isManager[$chat->getId()]))
706 $chat->role = self::ROLE_GUEST;
708 elseif ($isManager[$chat->getId()])
710 $chat->role = self::ROLE_MANAGER;
714 $chat->role = self::ROLE_MEMBER;
724 Im\Recent::readAll($userId);
726 if (Main\Loader::includeModule(
'pull'))
728 \Bitrix\Pull\Event::add($userId, [
730 'command' =>
'readAllChats',
738 public function read(
bool $onlyRecent =
false,
bool $byEvent =
false):
Result
744 $lastId = $this->
getReadService()->getLastMessageIdInChat($this->chatId);
746 return (
new Result())->setResult([
747 'CHAT_ID' => $this->chatId,
748 'LAST_ID' => $lastId,
749 'COUNTER' => $this->
getReadService()->getCounterService()->getByChat($this->chatId),
750 'VIEWED_MESSAGES' => [],
766 if (isset($messages))
770 if ($messages->count() === 0)
772 return $result->addError(
new MessageError(MessageError::MESSAGE_NOT_FOUND));
778 $readResult = isset($messages) ? $readService->
read($messages, $this) : $readService->
readAllInChat($this->chatId);
779 $counter = $readResult->getResult()[
'COUNTER'] ?? 0;
780 $viewedMessages = $readResult->getResult()[
'VIEWED_MESSAGES'] ??
new MessageCollection();
784 $notOwnMessages = $viewedMessages->filter(fn (
Message $message) => $message->
getAuthorId() !== $this->getContext()->getUserId());
786 if (Main\Loader::includeModule(
'pull'))
788 CIMNotify::DeleteBySubTag(
"IM_MESS_{$this->getChatId()}_{$this->getContext()->getUserId()}",
false,
false);
789 CPushManager::DeleteFromQueueBySubTag($this->getContext()->
getUserId(),
'IM_MESS');
790 $this->
sendPushRead($notOwnMessages, $lastId, $counter);
795 return $result->setResult([
796 'CHAT_ID' => $this->chatId,
797 'LAST_ID' => $lastId,
798 'COUNTER' => $counter,
799 'VIEWED_MESSAGES' => $notOwnMessages->getIds(),
807 $readResult = $readService->
readTo($message);
808 $counter = $readResult->getResult()[
'COUNTER'] ?? 0;
810 $viewedMessages = $readResult->getResult()[
'VIEWED_MESSAGES'];
812 foreach ($viewedMessages as $messageId)
814 $viewedMessage =
new Message();
815 $viewedMessage->setMessageId((
int)$messageId);
816 $messageCollection->add($viewedMessage);
821 if (Main\Loader::includeModule(
'pull'))
823 CIMNotify::DeleteBySubTag(
"IM_MESS_{$this->getChatId()}_{$this->getContext()->getUserId()}",
false,
false);
824 CPushManager::DeleteFromQueueBySubTag($this->getContext()->
getUserId(),
'IM_MESS');
825 $this->
sendPushRead($messageCollection, $lastId, $counter);
831 return $result->setResult([
832 'CHAT_ID' => $this->chatId,
833 'LAST_ID' => $lastId,
834 'COUNTER' => $counter,
835 'VIEWED_MESSAGES' => $viewedMessages,
843 if ($message->
getChatId() !== $this->chatId)
845 return $result->addError(
new MessageError(MessageError::MESSAGE_NOT_FOUND));
850 $counter = $readService->
unreadTo($message)->getResult()[
'COUNTER'];
852 $lastMessageStatuses = $this->
getReadService()->getViewedService()->getMessageStatuses($lastMessageIds);
860 return $result->setResult([
861 'CHAT_ID' => $this->chatId,
862 'LAST_ID' => $lastId,
863 'COUNTER' => $counter,
864 'UNREAD_TO' => $message->
getId(),
865 'LAST_MESSAGE_STATUSES' => $lastMessageStatuses,
876 if ($this->
getType() === self::ENTITY_TYPE_LIVECHAT || !$this->getContext()->getUser()->isConnector())
885 if (!Main\Loader::includeModule(
'pull'))
891 Event::add($this->
getUsersForPush(), $pushFormatter->formatStartRecordVoice($this));
896 $selfRelation = $this->
getSelfRelation([
'SELECT' => [
'ID',
'CHAT_ID',
'USER_ID',
'NOTIFY_BLOCK']]);
898 $muted = isset($selfRelation) ? $selfRelation->getNotifyBlock() :
false;
899 \Bitrix\Pull\Event::add($this->getContext()->
getUserId(), [
901 'command' =>
'readMessageChat',
906 'counter' => $counter,
907 'muted' => $muted ??
false,
909 'lines' => $this->
getType() === IM_MESSAGE_OPEN_LINE,
910 'viewedMessages' => $messages->
getIds(),
920 'command' =>
'readMessageChatOpponent',
924 'chatId' => $this->chatId,
925 'userId' => $this->getContext()->getUserId(),
926 'userName' => $this->getContext()->getUser()->getName(),
928 'date' => (
new DateTime())->format(
'c'),
929 'viewedMessages' => $messages->
getIds(),
930 'chatMessageStatus' => $this->
getReadService()->getChatMessageStatus($this->chatId),
932 'extra' => \Bitrix\Im\Common::getPullExtra()
939 protected function sendEventRead(
int $startId,
int $endId,
int $counter,
bool $byEvent): void
941 foreach (\GetModuleEvents(
"im",
"OnAfterChatRead",
true) as $arEvent)
943 \ExecuteModuleEventEx($arEvent, array(Array(
944 'CHAT_ID' => $this->chatId,
947 'START_ID' => $startId,
950 'USER_ID' => $this->getContext()->
getUserId(),
951 'BY_EVENT' => $byEvent
956 protected function sendPushUnreadSelf(
int $unreadToId,
int $lastId,
int $counter, ?array $lastMessageStatuses): void
959 $muted = isset($selfRelation) ? $selfRelation->getNotifyBlock() :
false;
960 \Bitrix\Pull\Event::add($this->getContext()->
getUserId(), [
962 'command' =>
'unreadMessageChat',
965 'chatId' => $this->chatId,
968 'counter' => $counter,
969 'muted' => $muted ??
false,
971 'lines' => $this->
getType() === IM_MESSAGE_OPEN_LINE,
972 'unreadToId' => $unreadToId,
973 'lastMessageStatuses' => $lastMessageStatuses ?? [],
976 'push' => [
'badge' =>
'Y'],
983 $lastMessagesRaw = Im\Model\MessageTable::query()
985 ->where(
'ID',
'>=', $lowerBound)
986 ->where(
'ID',
'<=', $upperBound)
987 ->where(
'CHAT_ID', $this->chatId)
988 ->setOrder([
'DATE_CREATE' =>
'DESC',
'ID' =>
'DESC'])
992 $lastMessageIds = [];
993 foreach ($lastMessagesRaw as $row)
995 $lastMessageIds[] = (int)$row[
'ID'];
998 return $lastMessageIds;
1006 if (isset($lastMessageViewsByGroups[
'USERS'][$this->getContext()->
getUserId()]))
1008 return $lastMessageViewsByGroups[
'FOR_VIEWERS'];
1011 return $lastMessageViewsByGroups[
'FOR_NOT_VIEWERS'];
1016 $defaultViewInfo = [
1018 'FIRST_VIEWERS' => [],
1019 'COUNT_OF_VIEWERS' => 0,
1023 'FOR_VIEWERS' => $defaultViewInfo,
1024 'FOR_NOT_VIEWERS' => $defaultViewInfo,
1031 if ($lastMessageInChat === 0)
1033 return $defaultValue;
1036 $messageViewers = $readService->
getViewedService()->getMessageViewersIds($lastMessageInChat);
1037 $countOfView = count($messageViewers);
1041 foreach ($messageViewers as $messageViewer)
1043 if (count($firstViewers) >= 2)
1048 $firstViewers[$messageViewer] = $messageViewer;
1051 $datesOfViews = $readService->
getViewedService()->getDateViewedByMessageIdForEachUser($lastMessageInChat, $firstViewers);
1053 $firstViewersWithDate = [];
1055 foreach ($firstViewers as $viewer)
1057 $firstViewersWithDate[] = [
1058 'USER_ID' => $viewer,
1059 'USER_NAME' => Im\V2\Entity\User\User::getInstance($viewer)->getName(),
1060 'DATE' => $datesOfViews[$viewer] ?? null
1064 $viewsInfoByGroups = [
'USERS' => $messageViewers];
1065 $viewInfoForViewers = [
1066 'MESSAGE_ID' => $lastMessageInChat,
1067 'FIRST_VIEWERS' => $firstViewersWithDate,
1068 'COUNT_OF_VIEWERS' => $countOfView - 1,
1070 $viewInfoForNotViewers = $viewInfoForViewers;
1071 ++$viewInfoForNotViewers[
'COUNT_OF_VIEWERS'];
1072 $viewsInfoByGroups[
'FOR_VIEWERS'] = $viewInfoForViewers;
1073 $viewsInfoByGroups[
'FOR_NOT_VIEWERS'] = $viewInfoForNotViewers;
1075 return $viewsInfoByGroups;
1080 $userId = $this->getContext()->getUserId();
1081 $isLineChat = $this->
getEntityType() === self::ENTITY_TYPE_LINE;
1084 foreach ($relations as $relation)
1086 if ($skipSelf && $relation->getUserId() === $userId)
1090 if ($skipBot && $relation->getUser()->isBot())
1094 if ($isLineChat && $relation->getUser()->isConnector())
1098 $userIds[] = $relation->getUserId();
1116 'field' =>
'chatId',
1117 'set' =>
'setChatId',
1118 'get' =>
'getChatId',
1127 'default' =>
'getDefaultType',
1128 'beforeSave' =>
'beforeSaveType',
1131 'field' =>
'authorId',
1132 'set' =>
'setAuthorId',
1133 'get' =>
'getAuthorId',
1135 'CHAT_AUTHOR_ID' => [
1136 'alias' =>
'AUTHOR_ID',
1140 'get' =>
'getColor',
1141 'set' =>
'setColor',
1142 'beforeSave' =>
'checkColor',
1148 'set' =>
'setTitle',
1149 'get' =>
'getTitle',
1150 'beforeSave' =>
'checkTitle',
1154 'field' =>
'description',
1155 'get' =>
'getDescription',
1156 'set' =>
'setDescription',
1159 'field' =>
'parentChatId',
1160 'get' =>
'getParentId',
1161 'set' =>
'setParentId',
1164 'field' =>
'parentMessageId',
1165 'get' =>
'getParentMessageId',
1166 'set' =>
'setParentMessageId',
1169 'field' =>
'extranet',
1170 'get' =>
'getExtranet',
1171 'set' =>
'setExtranet',
1172 'default' =>
'getDefaultExtranet',
1175 'field' =>
'avatarId',
1176 'get' =>
'getAvatarId',
1177 'set' =>
'setAvatarId',
1179 'PIN_MESSAGE_ID' => [
1180 'field' =>
'pinMessageId',
1181 'get' =>
'getPinMessageId',
1182 'set' =>
'setPinMessageId',
1185 'field' =>
'callType',
1186 'get' =>
'getCallType',
1187 'set' =>
'setCallType',
1190 'field' =>
'callNumber',
1191 'get' =>
'getCallNumber',
1192 'set' =>
'setCallNumber',
1195 'field' =>
'entityType',
1196 'get' =>
'getEntityType',
1197 'set' =>
'setEntityType',
1198 'default' =>
'getDefaultEntityType',
1201 'field' =>
'entityId',
1202 'get' =>
'getEntityId',
1203 'set' =>
'setEntityId',
1205 'ENTITY_DATA_1' => [
1206 'field' =>
'entityData1',
1207 'get' =>
'getEntityData1',
1208 'set' =>
'setEntityData1',
1210 'ENTITY_DATA_2' => [
1211 'field' =>
'entityData2',
1212 'get' =>
'getEntityData2',
1213 'set' =>
'setEntityData2',
1215 'ENTITY_DATA_3' => [
1216 'field' =>
'entityData3',
1217 'get' =>
'getEntityData3',
1218 'set' =>
'setEntityData3',
1220 'DISK_FOLDER_ID' => [
1221 'field' =>
'diskFolderId',
1222 'get' =>
'getDiskFolderId',
1223 'set' =>
'setDiskFolderId',
1225 'MESSAGE_COUNT' => [
1226 'field' =>
'messageCount',
1227 'get' =>
'getMessageCount',
1228 'set' =>
'setMessageCount',
1231 'field' =>
'userCount',
1232 'get' =>
'getUserCount',
1233 'set' =>
'setUserCount',
1235 'PREV_MESSAGE_ID' => [
1236 'field' =>
'prevMessageId',
1237 'get' =>
'getPrevMessageId',
1238 'set' =>
'setPrevMessageId',
1240 'LAST_MESSAGE_ID' => [
1241 'field' =>
'lastMessageId',
1242 'get' =>
'getLastMessageId',
1243 'set' =>
'setLastMessageId',
1245 'LAST_MESSAGE_STATUS' => [
1246 'field' =>
'lastMessageStatus',
1247 'get' =>
'getLastMessageStatus',
1248 'set' =>
'setLastMessageStatus',
1249 'default' =>
'getDefaultLastMessageStatus',
1252 'field' =>
'dateCreate',
1253 'get' =>
'getDateCreate',
1254 'set' =>
'setDateCreate',
1255 'default' =>
'getDefaultDateCreate',
1257 'MANAGE_USERS_ADD' => [
1258 'field' =>
'manageUsersAdd',
1259 'get' =>
'getManageUsersAdd',
1260 'set' =>
'setManageUsersAdd',
1261 'default' =>
'getDefaultManageUsersAdd',
1263 'MANAGE_USERS_DELETE' => [
1264 'field' =>
'manageUsersDelete',
1265 'get' =>
'getManageUsersDelete',
1266 'set' =>
'setManageUsersDelete',
1267 'default' =>
'getDefaultManageUsersDelete',
1270 'field' =>
'manageUI',
1271 'get' =>
'getManageUI',
1272 'set' =>
'setManageUI',
1273 'default' =>
'getDefaultManageUI',
1275 'MANAGE_SETTINGS' => [
1276 'field' =>
'manageSettings',
1277 'get' =>
'getManageSettings',
1278 'set' =>
'setManageSettings',
1279 'default' =>
'getDefaultManageSettings',
1281 'DISAPPEARING_TIME' => [
1282 'field' =>
'disappearingTime',
1283 'get' =>
'getDisappearingTime',
1284 'set' =>
'setDisappearingTime',
1287 'field' =>
'canPost',
1288 'get' =>
'getCanPost',
1289 'set' =>
'setCanPost',
1290 'default' =>
'getDefaultCanPost',
1293 'get' =>
'getUserIds',
1294 'set' =>
'setUserIds',
1297 'field' =>
'aliasName',
1298 'get' =>
'getAliasName',
1299 'set' =>
'setAliasName',
1300 'loadFilter' =>
'prepareAliasToLoad',
1304 'set' =>
'setRelations',
1315 return ChatTable::class;
1350 if ($params[
'CHAT_ID'] <= 0)
1355 $connection = \Bitrix\Main\Application::getConnection();
1357 $context = $context ?? Locator::getContext();
1359 if ($context->getUserId() == 0)
1361 $res = $connection->query(
"
1364 C.PARENT_ID as CHAT_PARENT_ID,
1365 C.PARENT_MID as CHAT_PARENT_MID,
1366 C.TITLE as CHAT_TITLE,
1367 C.AUTHOR_ID as CHAT_AUTHOR_ID,
1368 C.TYPE as CHAT_TYPE,
1369 C.AVATAR as CHAT_AVATAR,
1370 C.COLOR as CHAT_COLOR,
1371 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
1372 C.ENTITY_ID as CHAT_ENTITY_ID,
1373 C.ENTITY_DATA_1 as CHAT_ENTITY_DATA_1,
1374 C.ENTITY_DATA_2 as CHAT_ENTITY_DATA_2,
1375 C.ENTITY_DATA_3 as CHAT_ENTITY_DATA_3,
1376 C.EXTRANET as CHAT_EXTRANET,
1377 C.PREV_MESSAGE_ID as CHAT_PREV_MESSAGE_ID,
1381 WHERE C.ID = ".(
int)$params[
'CHAT_ID'].
"
1386 if (empty($params[
'FROM_USER_ID']))
1388 $params[
'FROM_USER_ID'] = $context->getUserId();
1391 $params[
'FROM_USER_ID'] = (int)$params[
'FROM_USER_ID'];
1392 if ($params[
'FROM_USER_ID'] <= 0)
1397 $res = $connection->query(
"
1400 C.PARENT_ID as CHAT_PARENT_ID,
1401 C.PARENT_MID as CHAT_PARENT_MID,
1402 C.TITLE as CHAT_TITLE,
1403 C.AUTHOR_ID as CHAT_AUTHOR_ID,
1404 C.TYPE as CHAT_TYPE,
1405 C.AVATAR as CHAT_AVATAR,
1406 C.COLOR as CHAT_COLOR,
1407 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
1408 C.ENTITY_ID as CHAT_ENTITY_ID,
1409 C.ENTITY_DATA_1 as CHAT_ENTITY_DATA_1,
1410 C.ENTITY_DATA_2 as CHAT_ENTITY_DATA_2,
1411 C.ENTITY_DATA_3 as CHAT_ENTITY_DATA_3,
1412 C.EXTRANET as CHAT_EXTRANET,
1413 C.PREV_MESSAGE_ID as CHAT_PREV_MESSAGE_ID,
1415 R.MANAGER as IS_MANAGER
1417 LEFT JOIN b_im_relation R
1419 AND R.USER_ID = ".$params[
'FROM_USER_ID'].
"
1420 WHERE C.ID = ".(
int)$params[
'CHAT_ID'].
"
1424 if ($row = $res->fetch())
1426 $result->setResult([
1427 'ID' => (
int)$row[
'CHAT_ID'],
1428 'TYPE' => $row[
'CHAT_TYPE'],
1429 'ENTITY_TYPE' => $row[
'CHAT_ENTITY_TYPE'],
1430 'ENTITY_ID' => $row[
'CHAT_ENTITY_ID'],
1451 public static function getSharedChatsWithUser(
int $userId,
int $limit = 50,
int $offset = 0, ?
int $currentUserId =
null): array
1453 $currentUserId ??= Im\V2\Entity\User\User::getCurrent()->getId();
1457 $recentCollection = Im\Model\RecentTable::query()
1458 ->setSelect([
'ITEM_ID',
'DATE_MESSAGE'])
1459 ->registerRuntimeField(
1462 RelationTable::class,
1463 Join::on(
'this.ITEM_ID',
'ref.CHAT_ID')
1464 ->where(
'this.USER_ID', $currentUserId)
1465 ->where(
'ref.USER_ID', $userId)
1466 ->whereIn(
'this.ITEM_TYPE', [self::IM_TYPE_CHAT, self::IM_TYPE_OPEN]),
1467 [
'join_type' => Join::TYPE_INNER]
1470 ->setOrder([
'DATE_MESSAGE' =>
'DESC'])
1472 ->setOffset($offset)
1476 foreach ($recentCollection as $recentItem)
1478 $chat = self::getInstance($recentItem->getItemId());
1483 $chat->dateMessage = $recentItem->getDateMessage();
1484 $chats[$chat->getId()] = $chat;
1499 $this->chatId = $chatId;
1506 return $this->chatId;
1520 $this->dialogId = $dialogId;
1527 $this->
setType(self::IM_TYPE_CHAT);
1534 $this->
setType(self::IM_TYPE_PRIVATE);
1549 if ($this->dialogId || !$this->
getChatId())
1551 return $this->dialogId;
1554 $this->dialogId =
'chat'. $this->
getChatId();
1556 return $this->dialogId;
1570 if (!in_array($type, self::IM_TYPES))
1572 if (in_array($type, array_keys(self::IM_TYPES_TRANSLATE),
true))
1574 $type = self::IM_TYPES_TRANSLATE[$type];
1582 $this->type = $type;
1602 if (!in_array($this->type, self::IM_TYPES,
true))
1613 $this->authorId = $authorId;
1619 return $this->authorId;
1624 return Im\V2\Entity\User\User::getInstance($this->
getAuthorId());
1630 $this->title = $title ? mb_substr(trim($title), 0, 255) :
null;
1636 return $this->title;
1641 return $this->title;
1647 $this->description = $description ? trim($description) :
null;
1653 return $this->description;
1659 $this->color = $color ? trim($color) :
null;
1665 return $this->color;
1688 $this->parentChatId = $parentChatId > 0 ? $parentChatId : 0;
1694 return $this->parentChatId;
1700 $this->parentMessageId = $messageId > 0 ? $messageId : 0;
1706 return $this->parentMessageId;
1712 $this->extranet = is_bool($extranet) ? $extranet :
null;
1718 return $this->extranet;
1729 $this->avatarId = is_integer($avatarId) ? $avatarId :
null;
1735 return $this->avatarId;
1738 public function getAvatar(
int $size = 200,
bool $addBlankPicture =
false): string
1740 $url = $addBlankPicture?
'/bitrix/js/im/images/blank.gif':
'';
1744 $arFileTmp = \CFile::ResizeImageGet(
1746 [
'width' => $size,
'height' => $size],
1747 BX_RESIZE_IMAGE_EXACT,
1752 if (!empty($arFileTmp[
'src']))
1754 $url = $arFileTmp[
'src'];
1763 $this->pinMessageId = is_integer($pinMessageId) ? $pinMessageId :
null;
1769 return $this->pinMessageId;
1775 $this->callType = is_integer($callType) ? $callType :
null;
1781 return $this->callType;
1787 $this->callNumber = $callNumber ? trim($callNumber) :
null;
1793 return $this->callNumber;
1799 $this->entityType = $entityType ? trim($entityType) :
null;
1805 if ($this->entityType)
1807 return $this->entityType;
1821 $this->entityId = $entityId ? trim($entityId) :
null;
1827 return $this->entityId;
1833 $this->entityData1 = $entityData1 ? trim($entityData1) :
null;
1839 return $this->entityData1;
1845 $this->entityData2 = $entityData2 ? trim($entityData2) :
null;
1851 return $this->entityData2;
1857 $this->entityData3 = $entityData3 ? trim($entityData3) :
null;
1863 return $this->entityData3;
1869 $this->diskFolderId = is_integer($diskFolderId) ? $diskFolderId :
null;
1875 return $this->diskFolderId;
1880 $this->isDiskFolderFilled =
true;
1881 $this->diskFolder = $folder;
1888 if ($folder ===
null)
1899 if (!Main\Loader::includeModule(
'disk'))
1904 if ($this->isDiskFolderFilled)
1906 return $this->diskFolder;
1912 if ($diskFolderId !==
null && $diskFolderId !== 0)
1914 $folder = \Bitrix\Disk\Folder::getById($diskFolderId);
1915 if (!($folder instanceof Folder) || (
int)$folder->getStorageId() !== \CIMDisk::GetStorageId())
1928 $storage = \CIMDisk::GetStorage();
1935 $folderModel = $storage->addFolder(
1937 'NAME' =>
"chat{$this->getId()}",
1938 'CREATED_BY' => $this->getContext()->
getUserId(),
1947 $accessProvider = new \Bitrix\Im\Access\ChatAuthProvider;
1948 $accessProvider->updateChatCodesByRelations($this->
getId());
1951 return $folderModel;
1956 $accessProvider = new \Bitrix\Im\Access\ChatAuthProvider;
1957 $driver = \Bitrix\Disk\Driver::getInstance();
1958 $rightsManager = $driver->getRightsManager();
1962 'ACCESS_CODE' => $accessProvider->generateAccessCode($this->
getId()),
1963 'TASK_ID' => $rightsManager->getTaskIdByName($rightsManager::TASK_EDIT)
1966 return $accessCodes;
1971 return (
int)\Bitrix\Main\Config\Option::get(
'im',
'disk_storage_id', 0);
1977 $this->messageCount = $messageCount > 0 ? $messageCount : 0;
1985 return $this->messageCount;
2001 'MESSAGE_COUNT' =>
new Main\DB\
SqlExpression(
'?# + ?i',
'MESSAGE_COUNT', $increment),
2026 Params::CHAT_LAST_DATE =>
new DateTime()
2030 \CIMMessageParam::SendPull($this->
getParentMessageId(), [Params::CHAT_MESSAGE, Params::CHAT_LAST_DATE]);
2039 $this->userCount = $userCount > 0 ? $userCount : 0;
2047 return $this->userCount;
2053 $this->prevMessageId = $prevMessageId > 0 ? $prevMessageId : 0;
2059 return $this->prevMessageId;
2065 $this->lastMessageId = $lastMessageId > 0 ? $lastMessageId : 0;
2073 return $this->lastMessageId;
2078 $this->lastFileId ??= \CIMDisk::GetMaxFileId($this->
getId());
2080 return $this->lastFileId;
2086 $this->lastMessageStatus = $lastMessageStatus ? trim($lastMessageStatus) :
null;
2092 return $this->lastMessageStatus;
2097 return \IM_MESSAGE_STATUS_RECEIVED;
2103 $this->dateCreate = $dateCreate ? $dateCreate :
null;
2109 return $this->dateCreate;
2119 if ($this->readService ===
null)
2122 $this->readService->setContext($this->context);
2125 return $this->readService;
2134 $optionsHash = md5(serialize($options));
2136 if (isset($this->relations[$optionsHash]))
2138 return $this->relations[$optionsHash];
2141 $filter = $options[
'FILTER'] ?? [];
2142 $filter[
'CHAT_ID'] = $this->
getChatId();
2146 $options[
'ORDER'] ?? [],
2147 $options[
'LIMIT'] ??
null,
2152 $this->relations[$optionsHash] = $relations;
2154 return $this->relations[$optionsHash];
2159 $emptyOptionsHash = md5(serialize([]));
2160 $this->relations[$emptyOptionsHash] = $relations;
2167 $userId = $this->getContext()->getUserId();
2169 $emptyOptionsHash = md5(serialize([]));
2170 if (isset($this->relations[$emptyOptionsHash]))
2172 return $this->relations[$emptyOptionsHash]->getByUserId($userId, $this->
getChatId() ?? 0);
2175 $options[
'FILTER'][
'USER_ID'] = $options[
'FILTER'][
'USER_ID'] ?? $userId;
2184 foreach ($relations as $relation)
2186 if ($relation->getUser()->getExternalAuthId() === Im\Bot::EXTERNAL_AUTH_ID)
2188 $botInChat[$relation->getUserId()] = $relation->getUserId();
2206 $manageUsersAdd = mb_strtoupper($manageUsersAdd);
2209 [self::MANAGE_RIGHTS_MEMBER, self::MANAGE_RIGHTS_OWNER, self::MANAGE_RIGHTS_MANAGERS],
2215 $this->manageUsersAdd = $manageUsersAdd ;
2222 return $this->manageUsersAdd;
2228 return self::MANAGE_RIGHTS_MEMBER;
2237 $manageUsersDelete = mb_strtoupper($manageUsersDelete);
2240 [self::MANAGE_RIGHTS_MEMBER, self::MANAGE_RIGHTS_OWNER, self::MANAGE_RIGHTS_MANAGERS],
2246 $this->manageUsersDelete = $manageUsersDelete ;
2253 return $this->manageUsersDelete;
2259 return self::MANAGE_RIGHTS_MANAGERS;
2268 $manageUI = mb_strtoupper($manageUI);
2271 [self::MANAGE_RIGHTS_MEMBER, self::MANAGE_RIGHTS_OWNER, self::MANAGE_RIGHTS_MANAGERS],
2277 $this->manageUI = $manageUI;
2284 return $this->manageUI;
2289 return self::MANAGE_RIGHTS_MEMBER;
2298 $manageSettings = mb_strtoupper($manageSettings);
2299 if (!in_array($manageSettings, [self::MANAGE_RIGHTS_OWNER, self::MANAGE_RIGHTS_MANAGERS],
true))
2303 $this->manageSettings = $manageSettings ;
2310 return $this->manageSettings;
2315 return self::MANAGE_RIGHTS_OWNER;
2320 if (is_numeric($disappearingTime) && (
int)$disappearingTime > -1)
2322 $this->disappearingTime = $disappearingTime;
2330 return $this->disappearingTime;
2339 $canPost = mb_strtoupper($canPost);
2343 self::MANAGE_RIGHTS_NONE,
2344 self::MANAGE_RIGHTS_MEMBER,
2345 self::MANAGE_RIGHTS_OWNER,
2346 self::MANAGE_RIGHTS_MANAGERS
2353 $this->canPost = $canPost;
2360 return $this->canPost;
2365 return self::MANAGE_RIGHTS_MEMBER;
2372 self::MANAGE_RIGHTS_MEMBER =>
Loc::getMessage(
'IM_CHAT_CAN_POST_ALL'),
2373 self::MANAGE_RIGHTS_OWNER =>
Loc::getMessage(
'IM_CHAT_CAN_POST_OWNER'),
2374 self::MANAGE_RIGHTS_MANAGERS =>
Loc::getMessage(
'IM_CHAT_CAN_POST_MANAGERS')
2385 $userId = $this->getContext()->getUserId();
2390 case self::MANAGE_RIGHTS_MEMBER:
2393 'USER_ID' => $userId,
2397 case self::MANAGE_RIGHTS_MANAGERS:
2400 'USER_ID' => $userId,
2405 case self::MANAGE_RIGHTS_OWNER:
2419 return $this->withContextUser(0)->addUsers([$this->getContext()->
getUserId()], [],
false);
2426 public function addUsers(array $userIds, array $managerIds = [], ?
bool $hideHistory =
null,
bool $withMessage =
true,
bool $skipRecent =
false): self
2428 if (empty($userIds) || !$this->
getChatId())
2435 if (empty($usersToAdd))
2455 if (empty($usersToAdd))
2460 $currentUserId = $this->getContext()->getUserId();
2462 foreach ($usersToAdd as $userId)
2464 $userCodes[] =
"[USER={$userId}][/USER]";
2466 $userCodesString = implode(
', ', $userCodes);
2468 $addsOnlyHimself = count($usersToAdd) === 1 && (isset($usersToAdd[$currentUserId]) || $currentUserId === 0);
2469 if ($addsOnlyHimself)
2471 $userIdToAdd = current($usersToAdd);
2472 $userToAdd = Im\V2\Entity\User\User::getInstance($userIdToAdd);
2473 $messageText =
Loc::getMessage(
"IM_CHAT_SELF_JOIN_{$userToAdd->getGender()}", [
'#USER_NAME#' => $userCodesString]);
2475 elseif ($currentUserId === 0 && count($usersToAdd) > 1)
2477 $messageText =
Loc::getMessage(
'IM_CHAT_SELF_JOIN', [
'#USERS_NAME#' => $userCodesString]);
2481 $currentUser = Im\V2\Entity\User\User::getInstance($currentUserId);
2483 "IM_CHAT_JOIN_{$currentUser->getGender()}",
2485 '#USER_1_NAME#' => htmlspecialcharsback($currentUser->getName()),
2486 '#USER_2_NAME#' => $userCodesString
2491 \CIMChat::AddMessage([
2492 "TO_CHAT_ID" => $this->
getId(),
2493 "MESSAGE" => $messageText,
2494 "FROM_USER_ID" => $currentUserId,
2496 "RECENT_ADD" => $skipRecent ?
'N' :
'Y',
2498 "CODE" =>
'CHAT_JOIN',
2499 "NOTIFY" => $this->
getEntityType() === self::ENTITY_TYPE_LINE?
'Y':
'N',
2502 "SKIP_USER_CHECK" =>
'Y',
2508 if (!\
Bitrix\Main\Loader::includeModule(
'pull'))
2514 'module_id' =>
'im',
2515 'command' =>
'chatUserAdd',
2518 'dialogId' =>
'chat' . $this->
getChatId(),
2519 'chatTitle' => \Bitrix\Im\Text::decodeEmoji($this->
getTitle() ??
''),
2523 'newUsers' => array_values($usersToAdd),
2526 'extra' => \Bitrix\Im\Common::getPullExtra()
2532 foreach ($oldRelations as $relation)
2534 if ($relation->getUser()->getExternalAuthId() ===
'imconnector')
2536 unset($allUsersIds[$relation->getUserId()]);
2540 \Bitrix\Pull\Event::add(array_values($allUsersIds), $pushMessage);
2542 return $pushMessage;
2549 foreach ($usersToAdd as $userId)
2559 $userCount = RelationTable::getCount(
2560 Main\ORM\
Query\Query::filter()
2561 ->where(
'CHAT_ID', $this->
getId())
2562 ->where(
'USER.ACTIVE',
true)
2567 \CIMDisk::ChangeFolderMembers($this->
getId(), $usersToAdd);
2568 self::cleanAccessCache($this->
getId());
2574 protected function addUsersToRelation(array $usersToAdd, array $managerIds = [], ?
bool $hideHistory =
null)
2576 if (empty($usersToAdd))
2581 $hideHistory ??=
false;
2584 foreach ($managerIds as $managerId)
2586 $managersMap[$managerId] = $managerId;
2590 foreach ($usersToAdd as $userId)
2592 $user = Im\V2\Entity\User\User::getInstance($userId);
2593 $hideHistory = (!static::EXTRANET_CAN_SEE_HISTORY && $user->isExtranet()) ?
true : $hideHistory;
2596 ->setChatId($this->
getId())
2597 ->setMessageType($this->
getType())
2598 ->setUserId($userId)
2600 ->setStatus(\IM_STATUS_READ)
2601 ->fillRestriction($hideHistory, $this)
2603 if (isset($managersMap[$userId]))
2605 $relation->setManager(
true);
2607 $relations->add($relation);
2609 $relations->save(
true);
2610 $this->relations = [];
2615 $usersAlreadyInChat = $this->
getRelations()->getUserIds();
2618 foreach ($userIds as $userId)
2620 $userId = (int)$userId;
2621 if (!isset($usersAlreadyInChat[$userId]) && $userId > 0)
2623 $user = Im\V2\Entity\User\User::getInstance($userId);
2624 if ($user->isExist() && $user->isActive())
2626 $usersToAdd[$userId] = $userId;
2636 if (empty($usersToAdd))
2641 foreach ($usersToAdd as $userId)
2644 if ($relation ===
null)
2648 if ($relation->getUser()->isBot())
2650 IM\Bot::changeChatMembers($this->
getId(), $userId);
2651 IM\Bot::onJoinChat(
'chat'.$this->
getId(), [
2652 'CHAT_TYPE' => $this->
getType(),
2653 'MESSAGE_TYPE' => $this->
getType(),
2654 'BOT_ID' => $userId,
2655 'USER_ID' => $this->getContext()->
getUserId(),
2656 'CHAT_ID' => $this->
getId(),
2660 "ACCESS_HISTORY" => (
int)$relation->getStartCounter() === 0,
2670 foreach(GetModuleEvents(
"im",
"OnChatUserAddEntityType".$eventCode,
true) as $arEvent)
2672 ExecuteModuleEventEx($arEvent, array([
2673 'CHAT_ID' => $this->
getId(),
2674 'NEW_USERS' => $usersToAdd,
2680 public function deleteUser(
int $userId,
bool $withMessage =
true,
bool $skipRecent =
false,
bool $withNotification =
true):
Result
2683 $userRelation = $this->getRelations()->getByUserId($userId, $this->
getId());
2685 if ($userRelation ===
null)
2695 \CIMContactList::DeleteRecent($this->
getId(),
true, $userId);
2696 \Bitrix\Im\LastSearch::delete(
'chat' . $this->
getId(), $userId);
2698 $userRelation->delete();
2706 if ($withNotification && $this->getContext()->
getUserId() !== $userId)
2723 if ($messageText ===
'')
2728 \CIMChat::AddMessage([
2729 "TO_CHAT_ID" => $this->
getId(),
2730 "MESSAGE" => $messageText,
2731 "FROM_USER_ID" => $this->getContext()->
getUserId(),
2733 "RECENT_ADD" => $skipRecent ?
'N' :
'Y',
2735 "CODE" =>
'CHAT_LEAVE',
2739 "SKIP_USER_CHECK" =>
"Y",
2745 if ($userId === $this->getContext()->
getUserId())
2749 $gender = $this->getContext()->getUser()->getGender();
2750 $userName = $this->getContext()->getUser()->getName();
2751 $userName =
"[USER={$this->getContext()->getUserId()}]{$userName}[/USER]";
2752 $notificationCallback = fn (?
string $languageId =
null) =>
Loc::getMessage(
2753 'IM_CHAT_KICK_NOTIFICATION_'. $gender,
2754 [
"#USER_NAME#" => $userName],
2758 $notificationFields = [
2759 'TO_USER_ID' => $userId,
2760 'FROM_USER_ID' => 0,
2761 'NOTIFY_TYPE' => IM_NOTIFY_SYSTEM,
2762 'NOTIFY_MODULE' =>
'im',
2764 'NOTIFY_MESSAGE' => $notificationCallback,
2766 CIMNotify::Add($notificationFields);
2771 $currentUser = $this->getContext()->getUser();
2772 if ($this->getContext()->
getUserId() === $userId)
2774 return Loc::getMessage(
"IM_CHAT_LEAVE_{$currentUser->getGender()}", [
'#USER_NAME#' => htmlspecialcharsback($currentUser->getName())]);
2777 $user = Im\V2\Entity\User\User::getInstance($userId);
2779 return Loc::getMessage(
"IM_CHAT_KICK_{$currentUser->getGender()}", [
'#USER_1_NAME#' => htmlspecialcharsback($currentUser->getName()),
'#USER_2_NAME#' => htmlspecialcharsback($user->getName())]);
2784 $this->relations = [];
2793 $userCount = RelationTable::getCount(
2794 Main\ORM\
Query\Query::filter()
2795 ->where(
'CHAT_ID', $this->
getId())
2796 ->where(
'USER.ACTIVE',
true)
2801 \CIMDisk::ChangeFolderMembers($this->
getId(), $deletedUserId,
false);
2802 self::cleanAccessCache($this->
getId());
2810 $user = Im\V2\Entity\User\User::getInstance($userId);
2813 IM\Bot::changeChatMembers($this->
getId(), $userId);
2814 IM\Bot::onLeaveChat(
'chat'.$this->
getId(), [
2815 'CHAT_TYPE' => $this->
getType(),
2816 'MESSAGE_TYPE' => $this->
getType(),
2817 'BOT_ID' => $userId,
2818 'USER_ID' => $this->getContext()->
getUserId(),
2830 foreach(GetModuleEvents(
"im",
"OnChatUserDeleteEntityType".$eventCode,
true) as $arEvent)
2832 ExecuteModuleEventEx($arEvent, array([
2833 'CHAT_ID' => $this->
getId(),
2834 'USER_ID' => $userId,
2842 if (!\
Bitrix\Main\Loader::includeModule(
'pull'))
2848 'module_id' =>
'im',
2849 'command' =>
'chatUserLeave',
2852 'dialogId' =>
'chat' . $this->
getChatId(),
2853 'chatTitle' => \Bitrix\Im\Text::decodeEmoji($this->
getTitle() ??
''),
2854 'userId' => $userId,
2858 'extra' => \Bitrix\Im\Common::getPullExtra()
2864 foreach ($oldRelations as $relation)
2866 if ($relation->getUser()->getExternalAuthId() ===
'imconnector')
2868 unset($allUsersIds[$relation->getUserId()]);
2872 \Bitrix\Pull\Event::add(array_values($allUsersIds), $pushMessage);
2874 return $pushMessage;
2881 $authorRelation = $relations->getByUserId($currentAuthorId, $this->
getId());
2882 if ($authorRelation !==
null)
2884 $authorRelation->setManager(
false);
2886 $otherRealUserRelation = $relations->filter(
static function (
Relation $relation) use ($currentAuthorId) {
2889 return $user->getId() !== $currentAuthorId
2890 && $user->isActive()
2892 && !$user->isExtranet()
2893 && !$user->isConnector()
2897 if (!$otherRealUserRelation instanceof
Relation)
2902 $this->
setAuthorId($otherRealUserRelation->getUserId());
2903 $otherRealUserRelation->setManager(
true);
2904 $relations->save(
true);
2909 if (!$this->
getChatId() || empty($userIds) || !count($userIds))
2914 $userIds = filter_var(
2916 FILTER_VALIDATE_INT,
2918 'flags' => FILTER_REQUIRE_ARRAY,
2919 'options' => [
'min_range' => 1],
2923 foreach ($userIds as $key => $userId)
2925 if (!is_int($userId))
2927 unset($userIds[$key]);
2937 RelationTable::deleteByFilter([
2938 [
'=USER_ID' => $userIds],
2942 $removedCount = $connection->getAffectedRowsCount();
2950 if ($extranetFlag = $this->
getExtranet() ??
false)
2952 $extranetFlag =
false;
2953 foreach ($relations as $relation)
2955 if ($extranetFlag = $relation->getUser()->isExtranet())
2963 ->setExtranet($extranetFlag)
2964 ->setUserCount($relations->count())
2967 if (\
Bitrix\Main\Loader::includeModule(
'pull'))
2970 'module_id' =>
'im',
2971 'command' =>
'chatUsersRemove',
2974 'dialogId' =>
'chat' . $this->
getChatId(),
2975 'chatExtranet' => $extranetFlag,
2976 'userCount' => $relations->count()
2978 'extra' => \Bitrix\Im\Common::getPullExtra()
2981 $allUsersIds = $relations->getUserIds();
2984 foreach ($relations as $relation)
2986 if ($relation->getUser()->getExternalAuthId() ===
'imconnector')
2988 unset($allUsersIds[$relation[
'userId']]);
2992 \Bitrix\Pull\Event::add(array_values($allUsersIds), $pushMessage);
2993 if ($this->
getType() === self::IM_TYPE_OPEN || $this->
getType() === self::IM_TYPE_OPEN_LINE)
2995 \CPullWatch::AddToStack(
'IM_PUBLIC_' . $this->
getChatId(), $pushMessage);
3002 public function setManagers(array $managerIds): self
3004 if (!$this->getChatId() || empty($managerIds) || !count($managerIds))
3009 $managerIds = filter_var(
3011 FILTER_VALIDATE_INT,
3013 'flags' => FILTER_REQUIRE_ARRAY,
3014 'options' => [
'min_range' => 1],
3018 foreach ($managerIds as $key => $managerId)
3020 if (!is_int($managerId))
3022 unset($managerIds[$key]);
3026 $relations = $this->getRelations([
3027 'CHAT_ID' => $this->getChatId(),
3031 $unsetManagerIds = [];
3033 foreach ($relations as $relation)
3035 if (in_array($relation->getUserId(), $managerIds,
true))
3037 $relationIds[] = $relation->getPrimaryId();
3039 elseif ($relation->getManager())
3041 $unsetManagerIds[] = $relation->getPrimaryId();
3046 if ($unsetManagerIds)
3048 RelationTable::updateMulti(
3056 RelationTable::updateMulti(
3077 $this->defaultSaveContext($context);
3088 return (
new \
Bitrix\Im\V2\
Message($startMessageId))->setChatId($this->
getId())->setMessageId($startMessageId);
3093 if ($this->isFilledNonCachedData)
3099 $this->isFilledNonCachedData =
true;
3111 return Im\V2\Chat\EntityLink::getInstance($this);
3128 'id' => $this->
getId(),
3131 'messageType' => $this->
getType(),
3132 'role' => mb_strtolower($this->
getRole()),
3134 'entityLink' => $this->
getEntityLink()->toRestFormat($option),
3138 'manageUi' => mb_strtolower($this->
getManageUI()),
3140 'canPost' => mb_strtolower($this->
getCanPost()),
3143 if ($option[
'CHAT_WITH_DATE_MESSAGE'] ??
false)
3145 $commonFields[
'dateMessage'] = $this->dateMessage;
3147 if ($option[
'CHAT_SHORT_FORMAT'] ??
false)
3149 return $commonFields;
3152 $additionalFields = [
3165 'aiProvider' =>
null,
3168 return array_merge($commonFields, $additionalFields);
3176 foreach ($relations as $relation)
3178 if ($relation->getManager() ??
false)
3180 $userIds[] = $relation->getUserId();
3191 if ($selfRelation ===
null)
3196 if ($selfRelation->getNotifyBlock() ??
false)
3198 return [$this->getContext()->getUserId()];
3219 $options = \CIMChat::GetChatOptions();
3226 return $options[
'DEFAULT'];
3237 if ($selfRelation ===
null)
3242 return $selfRelation->getUnreadId() ?? 0;
3248 if ($selfRelation ===
null)
3253 return $selfRelation->getLastId() ?? 0;
3263 $index = \Bitrix\Im\Internals\ChatIndex::create()
3265 ->setTitle(mb_substr($this->
getTitle() ??
'', 0, 255))
3266 ->setUserList($this->getUserNamesForIndex())
3268 \Bitrix\Im\Model\ChatTable::addIndexRecord($index);
3280 $index = \Bitrix\Im\Internals\ChatIndex::create()
3282 ->setUserList($this->getUserNamesForIndex())
3284 \Bitrix\Im\Model\ChatTable::updateIndexRecord($index);
3289 private function getUserNamesForIndex(): array
3291 $relations = $this->getRelations([
'LIMIT' => 100]);
3294 foreach ($relations as $relation)
3296 $users[] = $relation->getUser()->getName() ??
'';
3320 $messageIds = $messageCollection->getIds();
3321 $messageCollection->delete();
3323 foreach (array_chunk($messageIds, self::CHUNK_SIZE) as $messageIdsChunk)
3325 Im\Model\MessageParamTable::deleteBatch([
3326 '=MESSAGE_ID' => $messageIdsChunk,
3330 Im\V2\Link\Url\UrlCollection::deleteByChatsIds([$chatId]);
3331 Im\V2\Chat::cleanCache($chatId);
3335 $folderModel = \Bitrix\Disk\Folder::getById($chatFolderId);
3338 $folderModel->deleteTree(\
Bitrix\Disk\SystemUser::SYSTEM_USER_ID);
3345 private function hideChat():
Result
3349 if (!$this->getChatId())
3355 foreach($this->getRelations() as $relation)
3357 \CIMContactList::DeleteRecent($this->getChatId(),
true, $relation->getUserId());
3361 $pushList[] = $relation->getUserId();
3367 && \
Bitrix\Main\Loader::includeModule(
"pull")
3370 \Bitrix\Pull\Event::add($pushList, [
3371 'module_id' =>
'im',
3372 'command' =>
'chatHide',
3375 'dialogId' =>
'chat' . $this->getChatId(),
3376 'chatId' => $this->getId(),
3377 'lines' => $this->getType() === self::IM_TYPE_OPEN_LINE,
3391 $result = $this->
save();
3393 if (!$result->isSuccess())
3398 if (isset($oldAvatarId) && $oldAvatarId > 0)
3400 CFile::Delete($oldAvatarId);
3403 $avatarFile = CFile::ResizeImageGet(
3406 BX_RESIZE_IMAGE_EXACT,
3411 if (!empty($avatarFile[
'src']))
3413 $imageUrl = $avatarFile[
'src'];
3416 'module_id' =>
'im',
3417 'command' =>
'chatAvatar',
3420 'avatar' => $imageUrl,
3434 public function updateAvatar(
string $avatarBase64,
bool $withMessage =
true,
bool $skipRecent =
false):
Result
3436 if (isset($avatarBase64) && $avatarBase64)
3438 $avatar = CRestUtil::saveFile($avatarBase64);
3439 $imageCheck = (new \Bitrix\Main\File\Image($avatar[
"tmp_name"]))->getInfo();
3442 || !$imageCheck->getWidth()
3443 || $imageCheck->getWidth() > 5000
3444 || !$imageCheck->getHeight()
3445 || $imageCheck->getHeight() > 5000
3450 if (!$avatar || mb_strpos($avatar[
'type'],
"image/") !== 0)
3456 $avatar[
'MODULE_ID'] =
'im';
3457 $avatarId = CFile::saveFile($avatar,
'im');
3465 $result = $this->
updateAvatarId($avatarId, $withMessage, $skipRecent);
3467 return $result->setResult($avatarId);
3472 $currentUser = $this->getContext()->getUser();
3475 "IM_CHAT_AVATAR_CHANGE_{$currentUser->getGender()}",
3476 [
'#USER_NAME#' => htmlspecialcharsback($currentUser->getName())]
3479 if ($messageText ===
'')
3484 \CIMChat::AddMessage([
3485 "TO_CHAT_ID" => $this->
getId(),
3486 "MESSAGE" => $messageText,
3487 "FROM_USER_ID" => $this->getContext()->
getUserId(),
3489 "RECENT_ADD" => $skipRecent ?
'N' :
'Y',
3491 "CODE" =>
'CHAT_LEAVE',
3495 "SKIP_USER_CHECK" =>
"Y",
3501 $options = \CIMChat::GetChatOptions();
3504 $defaultAllowed = (bool)($chatOptions[
'DEFAULT'][$action] ??
true);
3506 if (isset($entityType, $options[$entityType]))
3508 return (
bool)($chatOptions[$entityType][$action] ?? $defaultAllowed);
3511 return $defaultAllowed;
3514 public function canDo(
string $action): bool
3516 $userRights = $this->
getRole();
3518 if ($this->getContext()->getUser()->isAdmin())
3549 return Im\V2\Chat\Permission::compareRole($userRights, $manageRights);
static getPublicLink($type, $alias)
static getColorByNumber($number)
static isSafeColor($code)
static getCodeByNumber($number)
static toJson($array, $camelCase=true)
static getChatId($dialogId, $userId=null)
static isUnread(int $userId, string $itemType, string $dialogId)
const ACTIONS_MANAGE_USERS_DELETE
const ACTIONS_MANAGE_USERS_ADD
const ACTIONS_MANAGE_SETTINGS
const ACTIONS_MANAGE_CAN_POST
setLastMessageId(int $lastMessageId)
read(bool $onlyRecent=false, bool $byEvent=false)
static getRestEntityName()
setPrimaryId(int $primaryId)
const ENTITY_TYPE_LIVECHAT
setRelations(RelationCollection $relations)
static fillRole(array $chats, ?int $userId=null)
Registry $messageRegistry
setCanPost(string $canPost)
sendMessageUsersAdd(array $usersToAdd, bool $skipRecent=false)
setDialogId(string $dialogId)
toRestFormat(array $option=[])
updateAvatarId(int $avatarId, bool $withMessage=true, bool $skipRecent=false)
const MANAGE_RIGHTS_MEMBER
getDefaultLastMessageStatus()
setUserIds(?array $userIds)
setAvatarId(?int $avatarId)
const ENTITY_TYPE_GENERAL
unreadToMessage(Message $message)
updateMessage(Message $message)
sendPushUserDelete(int $userId, RelationCollection $oldRelations)
static cleanAccessCache(int $chatId)
setExtranet(?bool $extranet)
sendPushUpdateMessage(Message $message)
setManageUsersDelete(string $manageUsersDelete)
sendPushReadSelf(MessageCollection $messages, int $lastId, int $counter)
static array $chatStaticCache
setEntityData3(?string $entityData3)
static getSharedChatsWithUser(int $userId, int $limit=50, int $offset=0, ?int $currentUserId=null)
sendNotificationUserDelete(int $userId)
getUsersForPush(bool $skipBot=false, bool $skipSelf=true)
setEntityData1(?string $entityData1)
const ENTITY_TYPE_VIDEOCONF
__construct($source=null)
updateParentMessageCount()
checkAllowedAction(string $action)
setParentChatId(int $parentChatId)
sendMessage($message, $sendingConfig=null)
setPinMessageId(?int $pinMessageId)
prepareAliasToLoad($alias)
const MANAGE_RIGHTS_MANAGERS
readTo(Message $message, bool $byEvent=false)
incrementMessageCount(int $increment=1)
string $manageUsersDelete
setDateCreate(?DateTime $dateCreate)
setPrevMessageId(int $prevMessageId)
setMessageCount(int $messageCount)
bool $isFilledNonCachedData
filterUsersToAdd(array $userIds)
sendEventRead(int $startId, int $endId, int $counter, bool $byEvent)
sendEventUserDelete(int $userId)
addUsers(array $userIds, array $managerIds=[], ?bool $hideHistory=null, bool $withMessage=true, bool $skipRecent=false)
addUsersToRelation(array $usersToAdd, array $managerIds=[], ?bool $hideHistory=null)
readAllMessages(bool $byEvent=false)
sendEventUsersAdd(array $usersToAdd)
setEntityData2(?string $entityData2)
getLastMessageViewsByGroups()
sendPushReadOpponent(MessageCollection $messages, int $lastId)
static readAllChats(int $userId)
const MANAGE_RIGHTS_OWNER
setDiskFolderId(?int $diskFolderId)
readMessages(?MessageCollection $messages, bool $byEvent=false)
string $lastMessageStatus
getAccessCodesForDiskFolder()
setManageUI(string $manageUI)
const EXTRANET_CAN_SEE_HISTORY
sendPushRead(MessageCollection $messages, int $lastId, int $counter)
removeUsers(array $userIds)
setManageSettings(string $manageSettings)
getDefaultManageSettings()
setAliasName(string $aliasName)
setLastMessageStatus(?string $lastMessageStatus)
getMessage(int $messageId)
static cleanCache(int $id)
setEntityType(?string $entityType)
getStartId(?int $userId=null)
setCallType(?int $callType)
getAvatar(int $size=200, bool $addBlankPicture=false)
setParentMessageId(int $messageId)
setEntityId(?string $entityId)
sendMessageUserDelete(int $userId, bool $skipRecent=false)
deleteMessage(Message $message)
static getInstance(?int $chatId)
getMessageUserDeleteText(int $userId)
setManageUsersAdd(string $manageUsersAdd)
hasPostAccess(?int $userId=null)
sendPushUnreadSelf(int $unreadToId, int $lastId, int $counter, ?array $lastMessageStatuses)
sendPushUsersAdd(array $usersToAdd, RelationCollection $oldRelations)
setDescription(?string $description)
getDefaultManageUsersAdd()
setContext(?Context $context)
sendMessageUpdateAvatar(bool $skipRecent=false)
setCallNumber(?string $callNumber)
setDiskFolder(?Folder $folder)
updateAvatar(string $avatarBase64, bool $withMessage=true, bool $skipRecent=false)
setUserCount(int $userCount)
setDisappearingTime(int $disappearingTime)
static find(array $params, ?Context $context=null)
getSelfRelation(array $options=[])
checkAccessWithoutCaching(int $userId)
getRelations(array $options=[])
createChatIfNotExists(array $params)
getDefaultManageUsersDelete()
const ENTITY_TYPE_FAVORITE
setAuthorId(int $authorId)
deleteUser(int $userId, bool $withMessage=true, bool $skipRecent=false, bool $withNotification=true)
static mirrorDataEntityFields()
updateStateAfterUserDelete(int $deletedUserId)
updateStateAfterUsersAdd(array $usersToAdd)
getLastMessages(int $upperBound, int $lowerBound)
read(MessageCollection $messages, Chat $chat)
readAllInChat(int $chatId)
getLastMessageIdInChat(int $chatId)
unreadTo(Message $message)
getLastIdByChatId(int $chatId)
static find(array $filter, array $order, ?int $limit=null, ?Context $context=null, array $select=[])
filterByChatId(int $chatId)
getParams(bool $disallowLazyLoad=false)
static getStartId(int $userId, int $chatId)
static find(array $filter, array $order=[], ?int $limit=null, ?Context $context=null, array $select=self::COMMON_FIELDS)
static getConnection($name="")
static loadMessages($file)
static getMessage($code, $replace=null, $language=null)
setRegistry(Registry $registry)