1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
im_chat.php
См. документацию.
1<?php
3
4use Bitrix\Im as IM;
9use Bitrix\Imopenlines\Model\SessionTable;
13
15{
16 const CHAT_ALL = 'all';
19
20 private $user_id = 0;
21 private $bHideLink = false;
22 public $lastAvatarId = 0;
23 private static $entityOption = null;
24
25 function __construct($user_id = null, $arParams = Array())
26 {
27 if (is_null($user_id))
28 {
29 global $USER;
30 if (is_object($USER))
31 {
32 $this->user_id = intval($USER->GetID());
33 }
34 }
35 else
36 {
37 $this->user_id = intval($user_id);
38 }
39
40 if (isset($arParams['HIDE_LINK']) && $arParams['HIDE_LINK'] == 'Y')
41 {
42 $this->bHideLink = true;
43 }
44 }
45
46 public function GetMessage($ID)
47 {
48 global $DB;
49
50 $strSql = "
51 SELECT
52 M.*, C.TYPE as CHAT_TYPE, R.USER_ID as RID
53 FROM
54 b_im_message M
55 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID
56 LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$this->user_id."
57 WHERE
58 M.ID = ".intval($ID)."
59 ";
60
61 $dbRes = $DB->Query($strSql);
62 if ($arRes = $dbRes->Fetch())
63 {
64 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
65 if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
66 {
67 if (intval($arRes['RID']) <= 0 && IM\User::getInstance($this->user_id)->isExtranet())
68 {
69 return false;
70 }
71 }
72 else if (intval($arRes['RID']) <= 0)
73 {
74 return false;
75 }
76 unset($arRes['CHAT_TYPE']);
77 unset($arRes['RID']);
78
79 return $arRes;
80 }
81
82 return false;
83 }
84
93 function GetLastMessage($toChatId, $fromUserId = false, $loadExtraData = false, $bTimeZone = true, $limit = true)
94 {
95 global $DB;
96
97 $fromUserId = intval($fromUserId);
98 if ($fromUserId <= 0)
99 $fromUserId = $this->user_id;
100
101 $toChatId = intval($toChatId);
102 if ($toChatId <= 0)
103 {
104 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "ERROR_TO_CHAT_ID");
105 return false;
106 }
107
108 $orm = IM\Model\ChatTable::getById($toChatId);
109 if (!($chatData = $orm->fetch()))
110 {
111 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
112 return false;
113 }
114
115 if ($chatData['TYPE'] == IM_MESSAGE_OPEN && !CIMMessenger::CheckEnableOpenChat())
116 {
117 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
118 return false;
119 }
120
121 $sqlLimit = '';
122 if ($limit)
123 {
124 if ($DB->type == "MSSQL")
125 {
126 $sqlLimit = " AND M.DATE_CREATE > dateadd(day, -30, getdate())";
127 }
128 elseif ($DB->type == "ORACLE")
129 {
130 $sqlLimit = " AND M.DATE_CREATE > SYSDATE-30";
131 }
132 else
133 {
134 //$sqlLimit = " AND M.DATE_CREATE > DATE_SUB(NOW(), INTERVAL 30 DAY)";
136 $helper = $connection->getSqlHelper();
137 $sqlLimit = " AND M.DATE_CREATE > ".$helper->addDaysToDateTime(-30);
138 }
139 }
140
141 $readService = new IM\V2\Message\ReadService($fromUserId);
142 $lastMessageIdInChat = $readService->getLastMessageIdInChat($toChatId);
143 $limitById = '';
144 $limitFetchMessages = 30;
145 $relations = \CIMChat::GetRelationById($toChatId, false, $bTimeZone, false);
146 if (isset($relations[$fromUserId]))
147 {
148 if ($relations[$fromUserId]['START_ID'] > 0)
149 {
150 $limitById = 'AND M.ID >= '.intval($relations[$fromUserId]['START_ID']);
151 }
152
153 //if ($relations[$fromUserId]['STATUS'] != IM_STATUS_READ && $relations[$fromUserId]['COUNTER'] > $limitFetchMessages)
154 $messageCountFilter = \Bitrix\Main\ORM\Query\Query::filter()
155 ->where('ID', '>=', (int)$relations[$fromUserId]['START_ID'])
156 ->where('ID', '>=', (int)$relations[$fromUserId]['LAST_ID'])
157 ->where('ID', '<=', $lastMessageIdInChat)
158 ->where('CHAT_ID', $toChatId)
159 ;
160 $messageCount = \Bitrix\Im\Model\MessageTable::getCount($messageCountFilter);
161 $limitFetchMessages = max($messageCount, 30);
162 }
163
164 if (!$bTimeZone)
165 CTimeZone::Disable();
166
167 $lineId = 0;
168 $crmEntityType = null;
169 $crmEntityId = null;
170 if (
171 $chatData['TYPE'] == IM_MESSAGE_OPEN_LINE
172 && \Bitrix\Main\Loader::includeModule('imopenlines')
173 )
174 {
175 $explodeData = explode('|', $chatData['ENTITY_DATA_1']);
176 $crmEntityType = ($explodeData[0] == 'Y') ? $explodeData[1] : null;
177 $crmEntityId = ($explodeData[0] == 'Y') ? intval($explodeData[2]) : null;
178
179 $lineId = \Bitrix\ImOpenLines\Chat::parseLinesChatEntityId($chatData['ENTITY_ID'])['lineId'];
180 }
181
182 $strSql = "";
183 if ($chatData['TYPE'] == IM_MESSAGE_OPEN)
184 {
185 $strSql = "
186 SELECT
187 M.ID,
188 M.CHAT_ID,
189 M.MESSAGE,
190 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
191 M.AUTHOR_ID,
192 C.TYPE as CHAT_TYPE,
193 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
194 R.USER_ID as RID
195 FROM b_im_message M
196 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN."'
197 LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$fromUserId."
198 WHERE
199 M.CHAT_ID = ".$toChatId."
200 ".$limitById."
201 #LIMIT#
202 ORDER BY M.DATE_CREATE DESC
203 ";
204 }
205 else if (
206 $chatData['TYPE'] == IM_MESSAGE_OPEN_LINE
207 && \Bitrix\Main\Loader::includeModule('imopenlines')
208 && \Bitrix\ImOpenLines\Config::canJoin($lineId, $crmEntityType, $crmEntityId)
209 )
210 {
211 $strSql = "
212 SELECT
213 M.ID,
214 M.CHAT_ID,
215 M.MESSAGE,
216 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
217 M.AUTHOR_ID,
218 C.TYPE as CHAT_TYPE,
219 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
220 R.USER_ID as RID
221 FROM b_im_message M
222 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.TYPE = '".IM_MESSAGE_OPEN_LINE."'
223 LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$fromUserId."
224 WHERE
225 M.CHAT_ID = ".$toChatId."
226 ".$limitById."
227 #LIMIT#
228 ORDER BY M.DATE_CREATE DESC
229 ";
230
231 \Bitrix\Im\Disk\NoRelationPermission::add($toChatId, $fromUserId);
232 }
233 else if (isset($relations[$fromUserId]))
234 {
235 $strSql = "
236 SELECT
237 M.ID,
238 M.CHAT_ID,
239 M.MESSAGE,
240 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
241 M.AUTHOR_ID,
242 C.TYPE as CHAT_TYPE,
243 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
244 '".$fromUserId."' as RID
245 FROM b_im_message M
246 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID
247 WHERE
248 M.CHAT_ID = ".$toChatId."
249 ".$limitById."
250 #LIMIT#
251 ORDER BY M.DATE_CREATE DESC
252 ";
253 }
254 else
255 {
256 if (
257 $chatData['TYPE'] == IM_MESSAGE_OPEN_LINE
258 && \Bitrix\Main\Loader::includeModule('imopenlines')
259 && \Bitrix\ImOpenLines\Model\RecentTable::getCount([
260 '=CHAT_ID' => $toChatId,
261 '=USER_ID' => $fromUserId,
262 ])
263 )
264 {
265 $strSql = "
266 SELECT
267 M.ID,
268 M.CHAT_ID,
269 M.MESSAGE,
270 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
271 M.AUTHOR_ID,
272 C.TYPE as CHAT_TYPE,
273 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
274 '".$fromUserId."' as RID
275 FROM b_im_message M
276 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID
277 WHERE
278 M.CHAT_ID = ".$toChatId."
279 ".$limitById."
280 #LIMIT#
281 ORDER BY M.DATE_CREATE DESC
282 ";
283 }
284 }
285
286 if (!$bTimeZone)
287 CTimeZone::Enable();
288
289 $chatType = $chatData['TYPE'];
290 $chatRelationUserId = 0;
291
292 $arUsers = Array();
293 $arMessages = Array();
294 $arMessageId = Array();
295 $arUsersMessage = Array();
296 $arUnreadMessages = Array();
297 $readedList = Array();
298
299 if ($strSql)
300 {
301 $strSql = $DB->TopSql($strSql, $limitFetchMessages);
302 //LEFT JOIN b_im_message_param MP on MP.MESSAGE_ID = M.ID and MP.PARAM_NAME = 'FOR_USER_ID'
303 //and (MP.PARAM_VALUE is null or MP.PARAM_VALUE = '".$fromUserId."')
304
305 if ($limit)
306 {
307 $dbRes = $DB->Query(str_replace("#LIMIT#", $sqlLimit, $strSql));
308 if (!$dbRes->SelectedRowsCount())
309 $dbRes = $DB->Query(str_replace("#LIMIT#", "", $strSql));
310 }
311 else
312 {
313 $dbRes = $DB->Query(str_replace("#LIMIT#", "", $strSql));
314 }
315
316 $lastReads = $readService
317 ->getViewedService()
318 ->getDateViewedByMessageIdForEachUser($lastMessageIdInChat, array_keys($relations))
319 ;
320 while ($arRes = $dbRes->Fetch())
321 {
322 if ($arRes['CHAT_ENTITY_TYPE'] != 'LIVECHAT' && \Bitrix\Im\User::getInstance($fromUserId)->isConnector())
323 {
324 return false;
325 }
326 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
327
328 $chatType = $arRes['CHAT_TYPE'];
329 $chatRelationUserId = intval($arRes['RID']);
330
331 $arMessages[$arRes['ID']] = Array(
332 'id' => $arRes['ID'],
333 'chatId' => $arRes['CHAT_ID'],
334 'senderId' => $arRes['AUTHOR_ID'],
335 'recipientId' => $arRes['CHAT_ID'],
336 'date' => DateTime::createFromTimestamp($arRes['DATE_CREATE']),
337 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']),
338 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']),
339 );
340
341 $arMessageId[] = $arRes['ID'];
342 if ($arRes['AUTHOR_ID'] > 0)
343 {
344 $arUsers[] = $arRes['AUTHOR_ID'];
345 }
346 if (isset($relations[$fromUserId]) && $relations[$fromUserId]['LAST_ID'] < $arRes['ID'])
347 {
348 $arUnreadMessages['chat'.$arRes['CHAT_ID']][] = $arRes['ID'];
349 }
350 $arUsersMessage[$arRes['CHAT_ID']][] = $arRes['ID'];
351
352 foreach ($relations as $userId => $relation)
353 {
354 $readedList['chat'.$arRes['CHAT_ID']][$relation['USER_ID']] = Array(
355 'messageId' => $relation['LAST_ID'],
356 'date' => $lastReads[$userId] ?? null,
357 );
358 }
359 }
360
361 foreach ($arUsersMessage as $chatId => $messageIds)
362 {
363 $arUsersMessage[$chatId] = array_values(array_unique($messageIds));
364 }
365 }
366
367 if (
368 $chatType == IM_MESSAGE_OPEN && $chatRelationUserId <= 0
369 || $chatType == IM_MESSAGE_OPEN_LINE && $chatRelationUserId <= 0
370 )
371 {
372 if (IM\User::getInstance($fromUserId)->isExtranet())
373 {
374 $arMessages = Array();
375 $arMessageId = Array();
376 $arUsersMessage = Array();
377 $loadExtraData = false;
378 }
379 else if (
380 CModule::IncludeModule('pull')
381 && \Bitrix\Im\V2\Chat::getInstance($toChatId)->checkAccess($fromUserId)->isSuccess()
382 )
383 {
384 CPullWatch::Add($fromUserId, 'IM_PUBLIC_'.$toChatId, true);
385 }
386 }
387
388 $params = CIMMessageParam::Get($arMessageId);
389
390 $arFiles = Array();
391 foreach ($params as $messageId => $param)
392 {
393 $arMessages[$messageId]['params'] = $param;
394
395 if (
396 mb_strlen($arMessages[$messageId]['text']) <= 0
397 && !isset($param['FILE_ID'])
398 && !isset($param['KEYBOARD'])
399 && !isset($param['ATTACH'])
400 )
401 {
402 $arMessages[$messageId]['text'] = GetMessage('IM_MESSAGE_DELETED');
403 $arMessages[$messageId]['params']['IS_DELETED'] = 'Y';
404 }
405
406 if (isset($param['FILE_ID']))
407 {
408 foreach ($param['FILE_ID'] as $fileId)
409 {
410 $arFiles[$fileId] = $fileId;
411 }
412 }
413 }
414
415 $arChatFiles = CIMDisk::GetFiles($toChatId, $arFiles);
416 $arMessages = CIMMessageLink::prepareShow($arMessages, $params);
417
418 $arResult = Array(
419 'chatId' => $toChatId,
420 'message' => $arMessages,
421 'usersMessage' => $arUsersMessage,
422 'unreadMessage' => $arUnreadMessages,
423 'users' => Array(),
424 'userInGroup' => Array(),
425 'readedList' => $readedList,
426 'files' => $arChatFiles
427 );
428
429 if (is_array($loadExtraData) || is_bool($loadExtraData) && $loadExtraData == true)
430 {
431 $bDepartment = true;
432 if (is_array($loadExtraData) && $loadExtraData['DEPARTMENT'] == 'N')
433 $bDepartment = false;
434
435 $arChat = self::GetChatData(array(
436 'ID' => $toChatId,
437 'USE_CACHE' => 'N'
438 ));
439 if (
440 isset($arChat['chat'][$toChatId]) && $arChat['chat'][$toChatId]['message_type'] == IM_MESSAGE_OPEN
441 || isset($arChat['chat'][$toChatId]) && $arChat['chat'][$toChatId]['message_type'] == IM_MESSAGE_OPEN_LINE
442 || isset($arChat['userInChat'][$toChatId]) && in_array($fromUserId, $arChat['userInChat'][$toChatId])
443 )
444 {
445 $arResult['lines'] = $arChat['lines'];
446 $arResult['userInChat'] = $arChat['userInChat'];
447 $arResult['userChatBlockStatus'] = $arChat['userChatBlockStatus'];
448
449 $ar = CIMContactList::GetUserData(array(
450 'ID' => array_values(array_merge($arUsers, $arChat['userInChat'][$toChatId])),
451 'DEPARTMENT' => ($bDepartment? 'Y': 'N'),
452 'USE_CACHE' => 'N'
453 )
454 );
455 $arResult['users'] = $ar['users'];
456 $arResult['userInGroup'] = $ar['userInGroup'];
457
458 if ($arChat['chat'][$toChatId]['extranet'] === "")
459 {
460 $isExtranet = false;
461 foreach ($ar['users'] as $userData)
462 {
463 if ($userData['extranet'])
464 {
465 $isExtranet = true;
466 break;
467 }
468 }
469 IM\Model\ChatTable::update($toChatId, Array('EXTRANET' => $isExtranet? "Y":"N"));
470
471 $arChat['chat'][$toChatId]['extranet'] = $isExtranet;
472 }
473 $arResult['chat'] = $arChat['chat'];
474 }
475 }
476
477 if ($chatData['ENTITY_TYPE'] == 'LINES' && $chatData['ENTITY_ID'] && CModule::IncludeModule('imopenlines'))
478 {
479 [, $lineId] = explode('|', $chatData["ENTITY_ID"]);
480 $configManager = new \Bitrix\ImOpenLines\Config();
481 $arResult['openlines']['canVoteAsHead'][$lineId] = $configManager->canVoteAsHead($lineId);
482 }
483 else if ($chatData['ENTITY_TYPE'] == 'LIVECHAT' && $chatData['ENTITY_ID'] && CModule::IncludeModule('imopenlines'))
484 {
485 [$lineId, $userId] = explode('|', $chatData["ENTITY_ID"]);
486 $userCode = 'livechat|' . $lineId . '|' . $chatData['ID'] . '|' . $userId;
487 unset($lineId, $userId);
488 foreach ($arResult['users'] as $userId => $userData)
489 {
490 $arResult['users'][$userId] = \Bitrix\ImOpenLines\Connector::getOperatorInfo($lineId, $userId, $userCode);
491 }
492 }
493
494 return $arResult;
495 }
496
497 function GetLastMessageLimit($chatId, $messageStartId, $messageEndId = 0, $loadExtraData = false, $bTimeZone = true, $order = 'DESC')
498 {
499 $messageStartId = intval($messageStartId);
500 $messageEndId = intval($messageEndId);
501 $chatId = intval($chatId);
502
503 if ($chatId <= 0)
504 {
505 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "ERROR_TO_CHAT_ID");
506 return false;
507 }
508
509 $orm = IM\Model\ChatTable::getById($chatId);
510 if (!($chatData = $orm->fetch()))
511 {
512 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
513 return false;
514 }
515
516 global $DB;
517 if (!$bTimeZone)
518 CTimeZone::Disable();
519
520 $strSql = "
521 SELECT
522 M.ID,
523 M.CHAT_ID,
524 M.MESSAGE,
525 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
526 M.AUTHOR_ID,
527 C.TYPE as CHAT_TYPE
528 FROM b_im_message M
529 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID
530 WHERE
531 M.CHAT_ID = ".$chatId."
532 AND M.ID >= ".$messageStartId."
533 ".($messageEndId > 0? "AND M.ID <= ".$messageEndId: "")."
534 ORDER BY M.DATE_CREATE ".($order == 'ASC'? 'ASC': 'DESC')."
535 ";
536
537 if (!$bTimeZone)
538 CTimeZone::Enable();
539
540 $dbRes = $DB->Query($strSql);
541
542 $arMessages = Array();
543 $arMessageId = Array();
544 $arUsers = Array();
545 $arUsersMessage = Array();
546 while ($arRes = $dbRes->Fetch())
547 {
548 $arMessages[$arRes['ID']] = Array(
549 'id' => $arRes['ID'],
550 'chatId' => $arRes['CHAT_ID'],
551 'senderId' => $arRes['AUTHOR_ID'],
552 'recipientId' => $arRes['CHAT_ID'],
553 'date' => DateTime::createFromTimestamp($arRes['DATE_CREATE']),
554 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']),
555 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']),
556 );
557
558 $arMessageId[] = $arRes['ID'];
559 $arUsersMessage[$arRes['CHAT_ID']][] = $arRes['ID'];
560 $arUsers[$arRes['CHAT_ID']][] = $arRes['AUTHOR_ID'];
561 }
562
563 if ($chatData['TYPE'] == IM_MESSAGE_OPEN_LINE)
564 {
565 \Bitrix\Im\Disk\NoRelationPermission::add($chatId, $this->user_id);
566 }
567
568 $params = CIMMessageParam::Get($arMessageId);
569
570 $arFiles = Array();
571 foreach ($params as $messageId => $param)
572 {
573 $arMessages[$messageId]['params'] = $param;
574 if (isset($param['FILE_ID']))
575 {
576 foreach ($param['FILE_ID'] as $fileId)
577 {
578 $arFiles[$fileId] = $fileId;
579 }
580 }
581 }
582
583 $arChatFiles = CIMDisk::GetFiles($chatId, $arFiles); // TODO get files for sessions
584 $arMessages = CIMMessageLink::prepareShow($arMessages, $params);
585
586 $arResult = Array(
587 'chatId' => $chatId,
588 'message' => $arMessages,
589 'usersMessage' => $arUsersMessage,
590 'users' => Array(),
591 'userInGroup' => Array(),
592 'files' => $arChatFiles
593 );
594
595 if (is_array($loadExtraData) || is_bool($loadExtraData) && $loadExtraData == true)
596 {
597 $bDepartment = true;
598 if (is_array($loadExtraData) && $loadExtraData['DEPARTMENT'] == 'N')
599 $bDepartment = false;
600
601 $arChat = self::GetChatData(array(
602 'ID' => $chatId,
603 'USE_CACHE' => 'N'
604 ));
605
606 $arResult['lines'] = $arChat['lines'];
607 $arResult['userInChat'] = $arChat['userInChat'];
608 $arResult['userChatBlockStatus'] = $arChat['userChatBlockStatus'];
609
610 $ar = CIMContactList::GetUserData(array(
611 'ID' => $arUsers[$chatId],
612 'DEPARTMENT' => ($bDepartment? 'Y': 'N'),
613 'USE_CACHE' => 'N'
614 )
615 );
616 $arResult['users'] = $ar['users'];
617 $arResult['userInGroup'] = $ar['userInGroup'];
618 $arResult['chat'] = $arChat['chat'];
619 }
620
621 return $arResult;
622 }
623
624 public static function getChatType($chatData)
625 {
626 return \Bitrix\Im\Chat::getType($chatData);
627 }
628
630 {
631 global $DB;
632
633 if (!isset($arParams['ID']))
634 return false;
635
636 $chatId = $arParams['ID'];
637
638 $fromUserId = isset($arParams['FROM_USER_ID']) && intval($arParams['FROM_USER_ID'])>0? intval($arParams['FROM_USER_ID']): $this->user_id;
639 $limit = isset($arParams['LIMIT']) && intval($arParams['LIMIT'])>0? intval($arParams['LIMIT']): false;
640 $bTimeZone = isset($arParams['USE_TIME_ZONE']) && $arParams['USE_TIME_ZONE'] == 'N'? false: true;
641
642 $arChatId = Array();
643 if (is_array($chatId))
644 {
645 foreach ($chatId as $val)
646 $arChatId[] = intval($val);
647 }
648 else
649 {
650 $arChatId[] = intval($chatId);
651 }
652 if (empty($arChatId))
653 return Array();
654
655 $sqlLimit = '';
656 if ($limit)
657 {
658 if ($DB->type == "MSSQL")
659 {
660 $sqlLimit = " AND M.DATE_CREATE > dateadd(day, -".$limit.", getdate())";
661 }
662 elseif ($DB->type == "ORACLE")
663 {
664 $sqlLimit = " AND M.DATE_CREATE > SYSDATE-".$limit;
665 }
666 else
667 {
669 $helper = $connection->getSqlHelper();
670 $sqlLimit = " AND M.DATE_CREATE > ". $helper->addDaysToDateTime(-1 * $limit);
671 }
672 }
673 if (!$bTimeZone)
674 CTimeZone::Disable();
675
676 $strSql = "
677 SELECT
678 M.ID,
679 M.CHAT_ID,
680 M.MESSAGE,
681 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
682 M.AUTHOR_ID,
683 C.TITLE as CHAT_TITLE,
684 C.COLOR as CHAT_COLOR,
685 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
686 C.ENTITY_DATA_1 as CHAT_ENTITY_DATA_1,
687 C.ENTITY_DATA_2 as CHAT_ENTITY_DATA_2,
688 C.ENTITY_DATA_3 as CHAT_ENTITY_DATA_3,
689 ".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." as CHAT_DATE_CREATE,
690 C.TYPE as CHAT_TYPE,
691 R.ID as RID
692 FROM b_im_message M
693 INNER JOIN b_im_chat C ON C.ID = M.CHAT_ID AND C.LAST_MESSAGE_ID = M.ID
694 LEFT JOIN b_im_relation R ON R.CHAT_ID = M.CHAT_ID AND R.USER_ID = ".$fromUserId."
695 WHERE
696 M.ID = C.LAST_MESSAGE_ID
697 AND M.CHAT_ID IN (".implode(",",$arChatId).")
698 ".$sqlLimit."
699 ";
700 if (!$bTimeZone)
701 CTimeZone::Enable();
702
703 $arMessages = Array();
704 $enableOpenChat = CIMMessenger::CheckEnableOpenChat();
705 $dbRes = $DB->Query($strSql);
706 while ($arRes = $dbRes->Fetch())
707 {
708 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
709
710 if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
711 {
712 if (!$enableOpenChat)
713 {
714 continue;
715 }
716 else if (intval($arRes['RID']) <= 0 && IM\User::getInstance($this->user_id)->isExtranet())
717 {
718 continue;
719 }
720 }
721 else if (intval($arRes['RID']) <= 0)
722 {
723 continue;
724 }
725
726 $chatType = \Bitrix\Im\Chat::getType($arRes);
727
728 $arMessages[$arRes['CHAT_ID']] = Array(
729 'id' => $arRes['ID'],
730 'senderId' => $arRes['AUTHOR_ID'],
731 'recipientId' => $arRes['CHAT_ID'],
732 'chatTitle' => \Bitrix\Im\Text::decodeEmoji($arRes['CHAT_TITLE']),
733 'date' => DateTime::createFromTimestamp($arRes['DATE_CREATE']),
734 'color' => $arRes["CHAT_COLOR"] == ""? IM\Color::getColorByNumber($arRes['CHAT_ID']): IM\Color::getColor($arRes['CHAT_COLOR']),
735 'type' => $chatType,
736 'messageType' => $arRes["CHAT_TYPE"],
737 'text' => \Bitrix\Im\Text::parse($arRes['MESSAGE']),
738 'textLegacy' => \Bitrix\Im\Text::parseLegacyFormat($arRes['MESSAGE']),
739 );
740 }
741
742 return $arMessages;
743 }
744
745 public static function GetRelationById($ID, $userId = false, $timezone = true, $withCounter = true, bool $raw = false)
746 {
747 global $DB;
748
749 $ID = intval($ID);
750 $userId = intval($userId);
751 $arResult = Array();
752
753 if (!$timezone)
754 {
755 CTimeZone::Disable();
756 }
757
758 $strSql = "
759 SELECT
760 R.*,
761 U.EXTERNAL_AUTH_ID
762 FROM b_im_relation R
763 LEFT JOIN b_user U ON U.ID = R.USER_ID
764 WHERE R.CHAT_ID = ".$ID." ".($userId>0? "AND R.USER_ID = ".$userId: "");
765
766 if (!$timezone)
767 {
768 CTimeZone::Enable();
769 }
770
771 $dbRes = $DB->Query($strSql);
772 while ($arRes = $dbRes->Fetch())
773 $arResult[$arRes['USER_ID']] = $arRes;
774
775 if (!$raw)
776 {
778 }
779
780 if ($userId > 0)
781 $arResult = isset($arResult[$userId])? $arResult[$userId]: false;
782
783 if ($arResult === false)
784 {
785 return $arResult;
786 }
787
788 // region New counter
789 if ($withCounter)
790 {
791 $readService = new IM\V2\Message\ReadService($userId);
792 if ($userId > 0)
793 {
794 $arResult['COUNTER'] = $readService->getCounterService()->getByChatWithOverflow($ID);
795 $lastRead = $readService->getViewedService()->getDateViewedByMessageId($arResult['LAST_ID']);
796 $arResult['LAST_READ'] = isset($lastRead) ? $lastRead->format('Y-m-d H:i:s') : null;
797 }
798 else
799 {
800 $userIds = array_keys($arResult);
801 $counters = $readService->getCounterService()->getByChatForEachUsers($ID, $userIds);
802 $lastIdInChat = $readService->getLastMessageIdInChat($ID);
803 $lastReads = $readService->getViewedService()->getDateViewedByMessageIdForEachUser($lastIdInChat, $userIds);
804 foreach ($arResult as $id => $user)
805 {
806 $arResult[$id]['COUNTER'] = $counters[$id] ?? 0;
807 $arResult[$id]['LAST_READ'] = isset($lastReads[$id]) ? $lastReads[$id]->format('Y-m-d H:i:s') : null;
808 }
809 }
810 }
811 // endregion
812
813 return $arResult;
814 }
815
816 public function GetPersonalChat(?int $userId = null)
817 {
818 if (!$userId)
819 {
820 $userId = $this->user_id;
821 }
822
823 $favoriteChatResult = \Bitrix\IM\V2\Chat\FavoriteChat::find(['TO_USER_ID' => $userId]);
824 if (!$favoriteChatResult->hasResult())
825 {
826 $favoriteChatResult = IM\V2\Chat\ChatFactory::getInstance()->addChat([
827 'TYPE' => \Bitrix\Im\V2\Chat::IM_TYPE_PRIVATE,
828 'ENTITY_TYPE' => \Bitrix\Im\V2\Chat::ENTITY_TYPE_FAVORITE,
829 'AUTHOR_ID' => $userId,
830 'USERS' => [$userId],
831 'MESSAGE' => GetMessage('IM_PERSONAL_DESCRIPTION')
832 ]);
833
834 return $favoriteChatResult->getResult()['CHAT_ID'];
835 }
836
837 return $favoriteChatResult->getResult()['ID'];
838 }
839
847 public static function GetPrivateRelation($fromUserId, $toUserId)
848 {
849 global $DB;
850
851 $fromUserId = intval($fromUserId);
852 $toUserId = intval($toUserId);
853
854 $arResult = Array();
855 $strSql = "
856 SELECT
857 RF.*
858 FROM
859 b_im_relation RF
860 INNER JOIN b_im_relation RT on RF.CHAT_ID = RT.CHAT_ID
861 WHERE
862 RF.USER_ID = ".$fromUserId."
863 and RT.USER_ID = ".$toUserId."
864 and RF.MESSAGE_TYPE = '".IM_MESSAGE_PRIVATE."'
865 ";
866 $dbRes = $DB->Query($strSql);
867 if ($arRes = $dbRes->Fetch())
869
870 return $arResult;
871 }
872
873 // region General Chat
877 public static function GetGeneralChatId()
878 {
880 }
881
885 public static function InstallGeneralChat($agentMode = false)
886 {
887 (new IM\V2\Chat\GeneralChat())->add([]);
888 }
889
894 {
895 return \Bitrix\Im\V2\Chat\GeneralChat::getAutoMessageStatus((string)$type);
896 }
897
901 public static function CanSendMessageToGeneralChat($userId = null)
902 {
903 $generalChat = IM\V2\Chat\ChatFactory::getInstance()->getGeneralChat();
904 if ($generalChat instanceof Chat\GeneralChat)
905 {
906 return $generalChat->hasManageMessagesAccess($userId);
907 }
908
909 $generalChatId = \COption::GetOptionString('im', 'general_chat_id');
910 $generalChat = IM\V2\Chat::getInstance((int)$generalChatId);
911 if ($generalChat instanceof IM\V2\Chat\GeneralChat)
912 {
913 return $generalChat->hasManageMessagesAccess($userId);
914 }
915
916 return false;
917 }
918
922 public static function SetAccessToGeneralChat($allowAll = true, $allowCodes = Array())
923 {
924 $prevAllow = COption::GetOptionString("im", "allow_send_to_general_chat_all");
925 $prevCodes = COption::GetOptionString("im", "allow_send_to_general_chat_rights");
926
927 if ($allowAll)
928 {
929 $allow = 'Y';
930 $codes = 'AU';
931 }
932 else
933 {
934 $allow = 'N';
935
936 if (is_array($allowCodes) && count($allowCodes) > 0)
937 {
938 $codes = implode(",", $allowCodes);
939 }
940 else
941 {
942 $codes = "";
943 }
944 }
945 COption::SetOptionString("im", "allow_send_to_general_chat_all", $allow);
946 COption::SetOptionString("im", "allow_send_to_general_chat_rights", $codes);
947
948 if ($prevAllow != $allow || $prevCodes != $codes)
949 {
950 if (CModule::IncludeModule('pull'))
951 {
952 CPullStack::AddShared(Array(
953 'module_id' => 'im',
954 'command' => 'generalChatAccess',
955 'params' => Array(
956 "status" => $prevAllow == 'Y' && $allow == 'N'? 'blocked': 'allowed'
957 ),
958 'extra' => \Bitrix\Im\Common::getPullExtra()
959 ));
960 }
961 }
962
963 return true;
964 }
965
969 public static function CanJoinGeneralChatId($userId)
970 {
971 $generalChat = IM\V2\Chat\ChatFactory::getInstance()->getGeneralChat();
972
973 if ($generalChat)
974 {
975 return $generalChat->canJoinGeneralChat((int)$userId);
976 }
977
978 return false;
979 }
980
984 public static function linkGeneralChatId($chatId)
985 {
986 return IM\V2\Chat\GeneralChat::linkGeneralChat((int) $chatId);
987 }
988
992 public static function UnlinkGeneralChatId()
993 {
995 }
996
997 public static function AddGeneralMessage($arFields)
998 {
999 $arFields['MESSAGE_TYPE'] = IM_MESSAGE_OPEN;
1000 $arFields['TO_CHAT_ID'] = self::GetGeneralChatId();
1001
1002 return CIMMessenger::Add($arFields);
1003 }
1004 // endregion
1005
1006 public static function GetChatData($arParams = Array())
1007 {
1008 global $DB;
1009
1010 $arParams['PHOTO_SIZE'] = isset($arParams['PHOTO_SIZE'])? intval($arParams['PHOTO_SIZE']): 200;
1011
1012 $from = "
1013 FROM b_im_chat C
1014 LEFT JOIN b_im_alias A ON A.ENTITY_ID = C.ID AND A.ENTITY_TYPE = C.ENTITY_TYPE
1015 LEFT JOIN b_im_relation R1 ON C.ID = R1.CHAT_ID
1016 ";
1017 $groupTypes = self::implodeTypesForQuery(self::getGroupTypes());
1018
1019 if (isset($arParams['SKIP_PRIVATE']) && $arParams['SKIP_PRIVATE'] == 'Y')
1020 {
1021 $from .= " AND C.TYPE IN ({$groupTypes})";
1022 }
1023
1024 $innerJoin = $whereUser = "";
1025 if (isset($arParams['GET_LIST']) && $arParams['GET_LIST'] == 'Y')
1026 {
1027 if (!isset($arParams['USER_ID']))
1028 return false;
1029
1030 $innerJoin = "INNER JOIN b_im_relation R2 ON R2.CHAT_ID = C.ID";
1031 $whereGeneral = "WHERE R2.USER_ID = ".intval($arParams['USER_ID']);
1032 }
1033 else
1034 {
1035 $arFilter = Array();
1036 if (isset($arParams['ID']) && is_array($arParams['ID']))
1037 {
1038 foreach ($arParams['ID'] as $key => $value)
1039 $arFilter['ID'][$key] = intval($value);
1040 }
1041 else if (isset($arParams['ID']) && intval($arParams['ID']) > 0)
1042 {
1043 $arFilter['ID'][] = intval($arParams['ID']);
1044 }
1045
1046 if (empty($arFilter['ID']))
1047 {
1048 return false;
1049 }
1050
1051 if (isset($arParams['USER_ID']))
1052 {
1053 $innerJoin = "LEFT JOIN b_im_relation R2 ON R2.CHAT_ID = C.ID AND R2.USER_ID = ".intval($arParams['USER_ID']);
1054 }
1055 $whereGeneral = "WHERE C.ID IN (".implode(',', $arFilter['ID']).") ";
1056 }
1057
1059 $helper = $connection->getSqlHelper();
1060 $strSql = "
1061 SELECT
1062 C.ID as CHAT_ID,
1063 C.PARENT_ID as CHAT_PARENT_ID,
1064 C.PARENT_MID as CHAT_PARENT_MID,
1065 C.TITLE as CHAT_TITLE,
1066 C.CALL_TYPE as CHAT_CALL_TYPE,
1067 C.AUTHOR_ID as CHAT_OWNER_ID,
1068 C.CALL_NUMBER as CHAT_CALL_NUMBER,
1069 C.EXTRANET as CHAT_EXTRANET,
1070 C.COLOR as CHAT_COLOR,
1071 C.TYPE as CHAT_TYPE,
1072 C.AVATAR,
1073 C.ENTITY_TYPE,
1074 C.ENTITY_DATA_1 as ENTITY_DATA_1,
1075 C.ENTITY_DATA_2 as ENTITY_DATA_2,
1076 C.ENTITY_DATA_3 as ENTITY_DATA_3,
1077 C.MESSAGE_COUNT as CHAT_MESSAGE_COUNT,
1078 C.MANAGE_USERS_ADD,
1079 C.MANAGE_USERS_DELETE,
1080 C.MANAGE_UI,
1081 C.MANAGE_SETTINGS,
1082 C.CAN_POST,
1083 A.ALIAS ALIAS_NAME,
1084 ".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." as CHAT_DATE_CREATE,
1085 C.ENTITY_ID,
1086 R1.NOTIFY_BLOCK as RELATION_NOTIFY_BLOCK,
1087 R1.USER_ID as RELATION_USER_ID,
1088 R1.CALL_STATUS,
1089 R1.MANAGER as RELATION_MANAGER
1090 ".(isset($arParams['USER_ID'])? ", R2.ID as RID": "")."
1091 ".$from."
1092 ".$innerJoin."
1093 ".$whereGeneral."
1094 ";
1095
1096 $arChat = Array();
1097 $arLines = Array();
1098 $linesChatIds = [];
1099 $multidialogChats = [];
1100 $multidialogs = [];
1101 $arUserInChat = Array();
1102 $arUserCallStatus = Array();
1103 $arUserChatBlockStatus = Array();
1104 $arManagerList = Array();
1105 $enableOpenChat = CIMMessenger::CheckEnableOpenChat();
1106 $generalChatId = CIMChat::GetGeneralChatId();
1107
1108 $dbRes = $DB->Query($strSql);
1109 while ($arRes = $dbRes->GetNext(true, false))
1110 {
1111 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
1112
1113 if (isset($arParams['USER_ID']))
1114 {
1115 if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
1116 {
1117 if (!$enableOpenChat)
1118 {
1119 continue;
1120 }
1121 else if (intval($arRes['RID']) <= 0 && IM\User::getInstance($arParams['USER_ID'])->isExtranet())
1122 {
1123 continue;
1124 }
1125 }
1126 else if (intval($arRes['RID']) <= 0)
1127 {
1128 if ($arRes['CHAT_TYPE'] === IM_MESSAGE_OPEN_LINE && CModule::IncludeModule('imopenlines'))
1129 {
1130 $userCodeParts = \Bitrix\ImOpenLines\Session\Common::parseUserCode($arRes['ENTITY_ID']);
1131 if(!\Bitrix\ImOpenLines\Config::canJoin($userCodeParts['CONFIG_ID']))
1132 {
1133 continue;
1134 }
1135 }
1136 else
1137 {
1138 continue;
1139 }
1140 }
1141 }
1142
1143 if (!isset($arChat[$arRes["CHAT_ID"]]))
1144 {
1145 $avatar = '/bitrix/js/im/images/blank.gif';
1146 if (intval($arRes["AVATAR"]) > 0)
1147 {
1148 $avatar = self::GetAvatarImage($arRes["AVATAR"], $arParams['PHOTO_SIZE']);
1149 }
1150
1151 $chatType = \Bitrix\Im\Chat::getType($arRes);
1152
1153 if ($arRes["ENTITY_TYPE"] == 'LINES')
1154 {
1155 $fieldData = explode("|", $arRes['ENTITY_DATA_1']);
1156 if ($fieldData[5] > 0)
1157 {
1158 $arLines[$arRes["CHAT_ID"]] = $fieldData[5];
1159 }
1160 else
1161 {
1162 $linesChatIds[] = (int)$arRes['CHAT_ID'];
1163 }
1164 }
1166 {
1167 if (in_array($arRes["ENTITY_TYPE"], [\Bitrix\ImBot\Bot\Support24::CHAT_ENTITY_TYPE, \Bitrix\ImBot\Bot\Network::CHAT_ENTITY_TYPE], true))
1168 {
1169 $multidialogChats[$arRes['CHAT_ID']] = [
1170 'type' => $arRes['ENTITY_TYPE'],
1171 'botId' => (int)$arRes['CHAT_OWNER_ID'],
1172 ];
1173 }
1174 }
1175 else if ($generalChatId == $arRes['CHAT_ID'])
1176 {
1177 $arRes["ENTITY_TYPE"] = 'GENERAL';
1178 }
1179
1180 $publicOption = '';
1181 if ($arRes['ALIAS_NAME'])
1182 {
1183 $publicOption = [
1184 'code' => $arRes['ALIAS_NAME'],
1185 'link' => IM\Alias::getPublicLink($arRes['ENTITY_TYPE'], $arRes['ALIAS_NAME'])
1186 ];
1187 }
1188
1189 $dateCreate = $arRes["CHAT_DATE_CREATE"]? DateTime::createFromTimestamp($arRes["CHAT_DATE_CREATE"]): false;
1190
1191 $arChat[$arRes["CHAT_ID"]] = Array(
1192 'id' => $arRes["CHAT_ID"],
1193 'parent_chat_id' => (int)($arRes['CHAT_PARENT_ID'] ?? 0),
1194 'parent_message_id' => (int)($arRes['CHAT_PARENT_MID'] ?? 0),
1195 'name' => \Bitrix\Im\Text::decodeEmoji($arRes["CHAT_TITLE"]),
1196 'owner' => $arRes["CHAT_OWNER_ID"],
1197 'color' => $arRes["CHAT_COLOR"] == ""? IM\Color::getColorByNumber($arRes['CHAT_ID']): IM\Color::getColor($arRes['CHAT_COLOR']),
1198 'extranet' => $arRes["CHAT_EXTRANET"] == ""? "": ($arRes["CHAT_EXTRANET"] == "Y"? true: false),
1199 'avatar' => $avatar,
1200 'call' => trim($arRes["CHAT_CALL_TYPE"]),
1201 'call_number' => trim($arRes["CHAT_CALL_NUMBER"]),
1202 'entity_type' => trim($arRes["ENTITY_TYPE"]),
1203 'entity_id' => trim($arRes["ENTITY_ID"]),
1204 'entity_data_1' => trim($arRes["ENTITY_DATA_1"]),
1205 'entity_data_2' => trim($arRes["ENTITY_DATA_2"]),
1206 'entity_data_3' => trim($arRes["ENTITY_DATA_3"]),
1207 'message_count' => (int)($arRes['CHAT_MESSAGE_COUNT'] ?? 0),
1208 'public' => $publicOption,
1209 'mute_list' => array(),
1210 'manager_list' => array(),
1211 'date_create' => $dateCreate,
1212 'type' => $chatType,
1213 'entity_link' => IM\V2\Chat\EntityLink::getInstance(self::initChatByArray($arRes))->toRestFormat(),
1214 'permissions' => [
1215 'manage_users_add' => mb_strtolower($arRes['MANAGE_USERS_ADD']),
1216 'manage_users_delete' => mb_strtolower($arRes['MANAGE_USERS_DELETE']),
1217 'manage_ui' => mb_strtolower($arRes['MANAGE_UI']),
1218 'manage_settings' => mb_strtolower($arRes['MANAGE_SETTINGS']),
1219 'manage_messages' => mb_strtolower($arRes['CAN_POST']),
1220 'can_post' => mb_strtolower($arRes['CAN_POST']),
1221 ],
1222 'text_field_enabled' => (new TextFieldEnabled((int)$arRes["CHAT_ID"]))->get(),
1223 'background_id' => (new Background((int)$arRes["CHAT_ID"]))->get(),
1224 'message_type' => $arRes["CHAT_TYPE"],
1225 'is_new' => CIMChat::isNewChat($arRes['CHAT_TYPE'], $dateCreate ?: null),
1226 );
1227 $arUserInChat[$arRes["CHAT_ID"]] = [];
1228 $arUserChatBlockStatus[$arRes["CHAT_ID"]] = [];
1229 $arUserCallStatus[$arRes["CHAT_ID"]] = [];
1230 $arManagerList[$arRes["CHAT_ID"]] = [];
1231 }
1232 if (isset($arRes['RELATION_USER_ID']))
1233 {
1234 $arRes["RELATION_USER_ID"] = (int)$arRes["RELATION_USER_ID"];
1235 $arUserInChat[$arRes["CHAT_ID"]][] = $arRes["RELATION_USER_ID"];
1236 $arUserChatBlockStatus[$arRes["CHAT_ID"]][$arRes["RELATION_USER_ID"]] = $arRes["RELATION_NOTIFY_BLOCK"] == 'Y';
1237 $arUserCallStatus[$arRes["CHAT_ID"]][$arRes["RELATION_USER_ID"]] = trim($arRes["CALL_STATUS"]);
1238 $arChat[$arRes["CHAT_ID"]]['mute_list'] = $arUserChatBlockStatus[$arRes["CHAT_ID"]];
1239 if ($arRes["RELATION_MANAGER"] == 'Y')
1240 {
1241 $arManagerList[$arRes["CHAT_ID"]][] = (int)$arRes["RELATION_USER_ID"];
1242 }
1243 $arChat[$arRes["CHAT_ID"]]['manager_list'] = $arManagerList[$arRes["CHAT_ID"]] ?? null;
1244 }
1245 }
1246
1247 foreach ($arUserInChat as $chatId => $userIds)
1248 {
1249 $arUserInChat[$chatId] = array_values(array_unique($userIds));
1250
1251 if (isset($multidialogChats[$chatId]) && count($arUserInChat[$chatId]) == 2)
1252 {
1253 foreach ($arUserInChat[$chatId] as $userId)
1254 {
1255 if ($userId != $multidialogChats[$chatId]['botId'])
1256 {
1257 $multidialog = self::getMultidialog(
1258 $multidialogChats[$chatId]['type'],
1259 $chatId,
1260 $userId,
1261 $multidialogChats[$chatId]['botId']
1262 );
1263
1264 if ($multidialog)
1265 {
1266 $multidialogs[$chatId] = $multidialog;
1267 }
1268
1269 break;
1270 }
1271 }
1272 }
1273 }
1274
1275 $lines = Array();
1276 if (CModule::IncludeModule('imopenlines'))
1277 {
1278 if (!empty($arLines))
1279 {
1280 $orm = SessionTable::getList(Array(
1281 'select' => Array(
1282 'CHAT_ID',
1283 'ID',
1284 'STATUS',
1285 'DATE_CREATE',
1286 'CONFIG_ID',
1287 'PAUSE',
1288 'CLOSED',
1289 'OPERATOR_ID',
1290 ),
1291 'filter' => Array(
1292 '=ID' => array_values($arLines)
1293 )
1294 ));
1295 while($row = $orm->fetch())
1296 {
1297 $statusGroup = null;
1298
1299 if (isset($row['STATUS']))
1300 {
1301 $statusGroup = Bitrix\ImOpenLines\V2\Status\StatusGroup::getFromNumericalCode((int)$row['STATUS']);
1302 }
1303
1304 $lines[$row['CHAT_ID']] = Array(
1305 'id' => (int)$row['ID'],
1306 'status' => (int)$row['STATUS'],
1307 'date_create' => $row['DATE_CREATE'],
1308 'statusGroup' => $statusGroup->name,
1309 'queueId' => $row['CONFIG_ID'],
1310 'pinned' => $row['PAUSE'] === 'Y',
1311 'isClosed' => $row['CLOSED'] === 'Y',
1312 'operatorId' => (int)$row['OPERATOR_ID'],
1313 );
1314 }
1315 }
1316
1317 if (!empty($linesChatIds))
1318 {
1319 $orm = SessionTable::getList([
1320 'select' => [
1321 new ExpressionField('ID', 'MAX(ID)'),
1322 ],
1323 'filter' => [
1324 '=CHAT_ID' => array_values($linesChatIds),
1325 ],
1326 'group' => ['CHAT_ID'],
1327 ]);
1328
1329 $ids = [];
1330
1331 while($row = $orm->fetch())
1332 {
1333 $ids[] = $row['ID'];
1334 }
1335
1336 $orm = SessionTable::getList([
1337 'select' => [
1338 'CHAT_ID',
1339 'ID',
1340 'STATUS',
1341 'DATE_CREATE',
1342 'CONFIG_ID',
1343 'PAUSE',
1344 'CLOSED',
1345 'OPERATOR_ID',
1346 ],
1347 'filter' => [
1348 '=ID' => $ids,
1349 ],
1350 ]);
1351
1352 while($row = $orm->fetch())
1353 {
1354 $statusGroup = null;
1355
1356 if (isset($row['STATUS']))
1357 {
1358 $statusGroup = Bitrix\ImOpenLines\V2\Status\StatusGroup::getFromNumericalCode((int)$row['STATUS']);
1359 }
1360
1361 $lines[$row['CHAT_ID']] = [
1362 'id' => (int)$row['ID'],
1363 'status' => (int)$row['STATUS'],
1364 'date_create' => $row['DATE_CREATE'],
1365 'statusGroup' => $statusGroup->name,
1366 'queueId' => $row['CONFIG_ID'],
1367 'pinned' => $row['PAUSE'] === 'Y',
1368 'isClosed' => $row['CLOSED'] === 'Y',
1369 'operatorId' => (int)$row['OPERATOR_ID'],
1370 ];
1371 }
1372 }
1373 }
1374
1375 $result = [
1376 'chat' => $arChat,
1377 'lines' => $lines,
1378 'multidialogs' => $multidialogs,
1379 'userInChat' => $arUserInChat,
1380 'userCallStatus' => $arUserCallStatus,
1381 'userChatBlockStatus' => $arUserChatBlockStatus
1382 ];
1383
1384 return $result;
1385 }
1386
1387 public static function getMultidialog($type, $chatId, $userId, $botId)
1388 {
1389 if ($type === \Bitrix\ImBot\Bot\Support24::CHAT_ENTITY_TYPE)
1390 {
1392 if (
1393 \Bitrix\Main\Loader::includeModule('bitrix24')
1394 && \Bitrix\ImBot\Bot\Support24::isEnabled()
1395 )
1396 {
1397 $classSupport = \Bitrix\ImBot\Bot\Support24::class;
1398 }
1399 elseif (\Bitrix\ImBot\Bot\SupportBox::isEnabled())
1400 {
1401 $classSupport = \Bitrix\ImBot\Bot\SupportBox::class;
1402 }
1403
1404 $multidialog = $classSupport::getMultidialog((int)$chatId, (int)$botId, $userId);
1405 }
1406 elseif($type === \Bitrix\ImBot\Bot\Network::CHAT_ENTITY_TYPE)
1407 {
1408 $multidialog = \Bitrix\ImBot\Bot\Network::getMultidialog((int)$chatId, (int)$botId, $userId);
1409 }
1410
1411 return $multidialog;
1412 }
1413
1414 public static function GetOpenChatData($arParams = Array())
1415 {
1416 global $DB;
1417
1418 $arParams['PHOTO_SIZE'] = isset($arParams['PHOTO_SIZE'])? intval($arParams['PHOTO_SIZE']): 100;
1419
1420 $strSql = "
1421 SELECT
1422 C.ID as CHAT_ID,
1423 C.TITLE as CHAT_TITLE,
1424 C.CALL_TYPE as CHAT_CALL_TYPE,
1425 C.AUTHOR_ID as CHAT_OWNER_ID,
1426 C.CALL_NUMBER as CHAT_CALL_NUMBER,
1427 C.EXTRANET as CHAT_EXTRANET,
1428 C.COLOR as CHAT_COLOR,
1429 C.TYPE as CHAT_TYPE,
1430 C.AVATAR,
1431 C.ENTITY_TYPE,
1432 C.ENTITY_DATA_1,
1433 C.ENTITY_DATA_2,
1434 C.ENTITY_DATA_3,
1435 ".$DB->DatetimeToTimestampFunction('C.DATE_CREATE')." as CHAT_DATE_CREATE,
1436 C.ENTITY_ID,
1437 R2.NOTIFY_BLOCK as RELATION_NOTIFY_BLOCK,
1438 R2.USER_ID as RELATION_USER_ID,
1439 R2.USER_ID as RELATION_MANAGER,
1440 R2.CALL_STATUS,
1441 R2.ID as RID
1442 FROM
1443 b_im_chat C
1444 LEFT JOIN b_im_relation R2 ON R2.CHAT_ID = C.ID AND R2.USER_ID = ".(int)$arParams['USER_ID']."
1445 WHERE
1446 C.TYPE = '".IM_MESSAGE_OPEN."'
1447 AND EXISTS(SELECT R3.ID FROM b_im_relation R3 WHERE R3.CHAT_ID = C.ID LIMIT 1)
1448 ";
1449
1450 $arChat = Array();
1451 $arUserInChat = Array();
1452 $arUserCallStatus = Array();
1453 $arUserChatBlockStatus = Array();
1454 $arManagerList = Array();
1455
1456 $generalChatId = CIMChat::GetGeneralChatId();
1457
1458 $dbRes = $DB->Query($strSql);
1459 while ($arRes = $dbRes->GetNext(true, false))
1460 {
1461 if (intval($arRes['RID']) <= 0 && IM\User::getInstance($arParams['USER_ID'])->isExtranet())
1462 {
1463 continue;
1464 }
1465
1466 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
1467
1468 if (!isset($arChat[$arRes["CHAT_ID"]]))
1469 {
1470 $avatar = '/bitrix/js/im/images/blank.gif';
1471 if (intval($arRes["AVATAR"]) > 0)
1472 {
1473 $avatar = self::GetAvatarImage($arRes["AVATAR"], $arParams['PHOTO_SIZE']);
1474 }
1475
1476 $chatType = \Bitrix\Im\Chat::getType($arRes);
1477
1478 if ($generalChatId == $arRes['CHAT_ID'])
1479 {
1480 $arRes["ENTITY_TYPE"] = 'GENERAL';
1481 }
1482
1483 $arChat[$arRes["CHAT_ID"]] = Array(
1484 'id' => $arRes["CHAT_ID"],
1485 'name' => \Bitrix\Im\Text::decodeEmoji($arRes["CHAT_TITLE"]),
1486 'owner' => $arRes["CHAT_OWNER_ID"],
1487 'color' => $arRes["CHAT_COLOR"] == ""? IM\Color::getColorByNumber($arRes['CHAT_ID']): IM\Color::getColor($arRes['CHAT_COLOR']),
1488 'extranet' => $arRes["CHAT_EXTRANET"] == ""? "": ($arRes["CHAT_EXTRANET"] == "Y"? true: false),
1489 'avatar' => $avatar,
1490 'call' => trim($arRes["CHAT_CALL_TYPE"]),
1491 'call_number' => trim($arRes["CHAT_CALL_NUMBER"]),
1492 'entity_type' => trim($arRes["ENTITY_TYPE"]),
1493 'entity_data_1' => trim($arRes["ENTITY_DATA_1"]),
1494 'entity_data_2' => trim($arRes["ENTITY_DATA_2"]),
1495 'entity_data_3' => trim($arRes["ENTITY_DATA_3"]),
1496 'mute_list' => array(),
1497 'manager_list' => array(),
1498 'date_create' => $arRes["CHAT_DATE_CREATE"]? DateTime::createFromTimestamp($arRes["CHAT_DATE_CREATE"]): false,
1499 'entity_id' => trim($arRes["ENTITY_ID"]),
1500 'type' => $chatType,
1501 'message_type' => $arRes["CHAT_TYPE"],
1502 );
1503
1504 }
1505 $arUserChatBlockStatus[$arRes["CHAT_ID"]][$arRes["RELATION_USER_ID"]] = $arRes['RELATION_NOTIFY_BLOCK'] == 'Y';
1506 $arUserInChat[$arRes["CHAT_ID"]][] = $arRes["RELATION_USER_ID"];
1507 $arUserCallStatus[$arRes["CHAT_ID"]][$arRes["RELATION_USER_ID"]] = trim($arRes["CALL_STATUS"] ?? '');
1508 $arChat[$arRes["CHAT_ID"]]['mute_list'] = $arUserChatBlockStatus[$arRes["CHAT_ID"]];
1509
1510 if ($arRes["RELATION_MANAGER"] == 'Y')
1511 {
1512 $arManagerList[$arRes["CHAT_ID"]][] = (int)$arRes["RELATION_USER_ID"];
1513 }
1514 $arChat[$arRes["CHAT_ID"]]['manager_list'] = $arManagerList[$arRes["CHAT_ID"]] ?? null;
1515 }
1516
1517 $result = array(
1518 'chat' => $arChat,
1519 'userInChat' => $arUserInChat,
1520 'userCallStatus' => $arUserCallStatus,
1521 'userChatBlockStatus' => $arUserChatBlockStatus
1522 );
1523
1524 return $result;
1525 }
1526
1527 public function SetReadMessage($chatId, $lastId = null, $byEvent = false)
1528 {
1529 global $DB;
1530
1531 $chatId = intval($chatId);
1532 if ($chatId <= 0)
1533 return false;
1534
1535 CIMMessenger::SpeedFileDelete($this->user_id, IM_SPEED_GROUP);
1536
1537 $chat = IM\V2\Chat::getInstance($chatId);
1538
1539 if (
1540 $chat->getType() == IM_MESSAGE_OPEN_LINE
1541 && $chat->getAuthorId() == 0
1542 )
1543 {
1544 return false;
1545 }
1546
1547 $readService = new IM\V2\Message\ReadService($this->user_id);
1548
1549 $startId = $readService->getLastIdByChatId($chatId);
1550 $counter = 0;
1551 $viewedMessages = [];
1552
1553 if (isset($lastId))
1554 {
1555 $message = new \Bitrix\Im\V2\Message();
1556 $message->setMessageId((int)$lastId)->setChatId($chatId);
1557 $readResult = $readService->readTo($message);
1558 $counter = $readResult->getResult()['COUNTER'];
1559 $viewedMessages = $readResult->getResult()['VIEWED_MESSAGES'];
1560 }
1561 else
1562 {
1563 $counter = $readService->readAllInChat($chatId)->getResult()['COUNTER'];
1564 }
1565
1566 $relation = CIMMessage::SetLastId($chatId, $this->user_id, 0);
1567
1568 if (!$relation)
1569 {
1570 return false;
1571 }
1572
1573 $endId = (int)($relation['LAST_ID'] ?? 0);
1574
1575 /*\Bitrix\Main\Application::getConnection()->query(
1576 "UPDATE b_im_recent SET DATE_UPDATE = NOW() WHERE USER_ID = ".$this->user_id." AND ITEM_CID = ".intval($chatId)
1577 );*/
1578
1579 if (CModule::IncludeModule("pull"))
1580 {
1581 CIMNotify::DeleteBySubTag("IM_MESS_".$chatId.'_'.$this->user_id, false, false);
1582 CPushManager::DeleteFromQueueBySubTag($this->user_id, 'IM_MESS');
1583
1584 if (
1585 $chat->getEntityType() == 'LIVECHAT'
1586 || !\Bitrix\Im\User::getInstance($this->user_id)->isConnector()
1587 )
1588 {
1589 \Bitrix\Pull\Event::add($this->user_id, Array(
1590 'module_id' => 'im',
1591 'command' => 'readMessageChat',
1592 'params' => Array(
1593 'dialogId' => 'chat'.$chatId,
1594 'chatId' => (int)$chatId,
1595 'parentChatId' => $chat->getParentChatId(),
1596 'type' => $chat->getExtendedType(),
1597 'lastId' => $endId,
1598 'counter' => $counter,
1599 'muted' => $relation['NOTIFY_BLOCK'] === 'Y',
1600 'unread' => Im\Recent::isUnread($this->user_id, $relation['MESSAGE_TYPE'], 'chat'.$chatId),
1601 'lines' => $relation['MESSAGE_TYPE'] === IM_MESSAGE_OPEN_LINE,
1602 'viewedMessages' => $viewedMessages,
1603 'counterType' => $chat->getCounterType()->value,
1604 'recentConfig' => $chat->getRecentConfig()->toPullFormat(),
1605 ),
1606 'extra' => \Bitrix\Im\Common::getPullExtra()
1607 ));
1608 }
1609
1610 $arRelation = self::GetRelationById($chatId, false, true, false);
1611 unset($arRelation[$this->user_id]);
1612
1613 $pushMessage = Array(
1614 'module_id' => 'im',
1615 'command' => 'readMessageChatOpponent',
1616 'expiry' => 600,
1617 'params' => Array(
1618 'dialogId' => 'chat'.$chatId,
1619 'chatId' => (int)$chatId,
1620 'userId' => (int)$this->user_id,
1621 'userName' => \Bitrix\Im\User::getInstance($this->user_id)->getFullName(false),
1622 'lastId' => $endId,
1623 'date' => date('c', time()),
1624 'viewedMessages' => $viewedMessages,
1625 'chatMessageStatus' => $relation['CHAT_MESSAGE_STATUS'],
1626 ),
1627 'extra' => \Bitrix\Im\Common::getPullExtra()
1628 );
1629 if ($chat->getEntityType() == 'LINES')
1630 {
1631 foreach ($arRelation as $rel)
1632 {
1633 if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
1634 {
1635 unset($arRelation[$rel["USER_ID"]]);
1636 }
1637 }
1638 }
1639 if (count($arRelation) < 200)
1640 {
1641 \Bitrix\Pull\Event::add(array_keys($arRelation), $pushMessage);
1642 if ($chat->needToSendPublicPull())
1643 {
1644 CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pushMessage);
1645 }
1646 }
1647 }
1648
1649 foreach(GetModuleEvents("im", "OnAfterChatRead", true) as $arEvent)
1650 {
1651 ExecuteModuleEventEx($arEvent, array(Array(
1652 'CHAT_ID' => $chat->getChatId(),
1653 'CHAT_ENTITY_TYPE' => $chat->getEntityType(),
1654 'CHAT_ENTITY_ID' => $chat->getEntityId(),
1655 'START_ID' => $startId,
1656 'END_ID' => $endId,
1657 'COUNT' => $relation['COUNTER'],
1658 'USER_ID' => $this->user_id,
1659 'BY_EVENT' => $byEvent
1660 )));
1661 }
1662
1663 return Array(
1664 'DIALOG_ID' => 'chat'.$chatId,
1665 'CHAT_ID' => (int)$chatId,
1666 'LAST_ID' => $endId,
1667 'COUNTER' => (int)$relation['COUNTER']
1668 );
1669 }
1670
1671 public function SetUnReadMessage($chatId, $lastId)
1672 {
1673 $chatId = intval($chatId);
1674 if ($chatId <= 0)
1675 return false;
1676
1677 $lastId = intval($lastId);
1678 if (intval($lastId) <= 0)
1679 return false;
1680
1681 /*$result = Bitrix\Im\V2\Chat::getInstance($chatId)->unreadToMessage(new IM\V2\Message($lastId));
1682
1683 return $result->isSuccess();*/
1684 $readService = new IM\V2\Message\ReadService($this->user_id);
1685 $endId = $readService->getLastMessageIdInChat($chatId);
1686 $relation = CIMMessage::SetLastIdForUnread($chatId, $this->user_id, $lastId);
1687 if ($relation)
1688 {
1689 $chat = Bitrix\Im\V2\Chat::getInstance($chatId);
1691 "UPDATE b_im_recent SET DATE_UPDATE = NOW() WHERE USER_ID = ".$this->user_id." AND ITEM_CID = ".intval($chatId)
1692 );
1693
1694 CIMMessenger::SpeedFileDelete($this->user_id, IM_SPEED_GROUP);
1695
1696 if (CModule::IncludeModule("pull"))
1697 {
1698 \Bitrix\Pull\Event::add($this->user_id, Array(
1699 'module_id' => 'im',
1700 'command' => 'unreadMessageChat',
1701 'params' => Array(
1702 'dialogId' => 'chat'.$chatId,
1703 'chatId' => (int)$chatId,
1704 'lastId' => $endId,
1705 'date' => new DateTime(),
1706 'counter' => (int)$relation['COUNTER'],
1707 'muted' => $relation['NOTIFY_BLOCK'] === 'Y',
1708 'lines' => $relation['MESSAGE_TYPE'] === IM_MESSAGE_OPEN_LINE,
1709 'unreadTo' => $lastId,
1710 'unread' => Im\Recent::isUnread($this->user_id, $relation['MESSAGE_TYPE'], 'chat'.$chatId),
1711 'lastMessageViews' => Im\Common::toJson($chat->getLastMessageViews()),
1712 'counterType' => $chat->getCounterType()->value,
1713 'recentConfig' => $chat->getRecentConfig()->toPullFormat(),
1714 ),
1715 'push' => Array('badge' => 'Y'),
1716 'extra' => \Bitrix\Im\Common::getPullExtra()
1717 ));
1718
1719 $arRelation = self::GetRelationById($chatId, false, true, false);
1720 unset($arRelation[$this->user_id]);
1721
1722 $pushMessage = Array(
1723 'module_id' => 'im',
1724 'command' => 'unreadMessageChatOpponent',
1725 'expiry' => 600,
1726 'params' => Array(
1727 'dialogId' => 'chat'.$chatId,
1728 'chatId' => (int)$chatId,
1729 'userId' => (int)$this->user_id,
1730 'chatMessageStatus' => $relation['CHAT_MESSAGE_STATUS'],
1731 'unreadTo' => $lastId,
1732 'lastMessageStatuses' => $lastMessageStatuses,
1733 ),
1734 'extra' => \Bitrix\Im\Common::getPullExtra()
1735 );
1736 if ($chat->getEntityType() == 'LINES')
1737 {
1738 foreach ($arRelation as $rel)
1739 {
1740 if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
1741 {
1742 unset($arRelation[$rel["USER_ID"]]);
1743 }
1744 }
1745 }
1746 $viewsByGroups = $chat->getLastMessageViewsByGroups();
1747 $usersForPush = array_keys($arRelation);
1748 $viewers = array_intersect($usersForPush, $viewsByGroups['USERS'] ?? []);
1749 $notViewers = array_diff($usersForPush, $viewers);
1750 $pushMessage['params']['lastMessageViews'] = Im\Common::toJson($viewsByGroups['FOR_VIEWERS'] ?? []);
1751 \Bitrix\Pull\Event::add($viewers, $pushMessage);
1752 $pushMessage['params']['lastMessageViews'] = Im\Common::toJson($viewsByGroups['FOR_NOT_VIEWERS'] ?? []);
1753 \Bitrix\Pull\Event::add($notViewers, $pushMessage);
1754 /*\Bitrix\Pull\Event::add(array_keys($arRelation), $pushMessage);
1755 if ($chat->getType() == IM_MESSAGE_OPEN || $chat->getType() == IM_MESSAGE_OPEN_LINE)
1756 {
1757 CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pushMessage);
1758 }*/
1759 }
1760
1762 new Sync\Event(Sync\Event::ADD_EVENT, Sync\Event::CHAT_ENTITY, $chat->getChatId()),
1763 $this->user_id,
1764 $chat
1765 );
1766
1767
1768 return true;
1769 }
1770
1771 return false;
1772 }
1773
1780 public function GetUnreadMessage($arParams = Array())
1781 {
1782 global $DB;
1783
1784 $bSpeedCheck = isset($arParams['SPEED_CHECK']) && $arParams['SPEED_CHECK'] == 'N'? false: true;
1785 $lastId = !isset($arParams['LAST_ID']) || $arParams['LAST_ID'] == null? null: intval($arParams['LAST_ID']);
1786 $loadDepartment = isset($arParams['LOAD_DEPARTMENT']) && $arParams['LOAD_DEPARTMENT'] == 'N'? false: true;
1787 $bTimeZone = isset($arParams['USE_TIME_ZONE']) && $arParams['USE_TIME_ZONE'] == 'N'? false: true;
1788 $bGroupByChat = isset($arParams['GROUP_BY_CHAT']) && $arParams['GROUP_BY_CHAT'] == 'Y'? true: false;
1789 $bUserLoad = isset($arParams['USER_LOAD']) && $arParams['USER_LOAD'] == 'N'? false: true;
1790 $bFileLoad = isset($arParams['FILE_LOAD']) && $arParams['FILE_LOAD'] == 'N'? false: true;
1791 $arExistUserData = isset($arParams['EXIST_USER_DATA']) && is_array($arParams['EXIST_USER_DATA'])? $arParams['EXIST_USER_DATA']: Array();
1792 $messageType = isset($arParams['MESSAGE_TYPE']) && in_array($arParams['MESSAGE_TYPE'], self::getGroupTypes())? $arParams['MESSAGE_TYPE']: 'ALL';
1793
1794 $arMessages = Array();
1795 $arUnreadMessage = Array();
1796 $arUsersMessage = Array();
1797
1798 $arResult = Array(
1799 'message' => Array(),
1800 'unreadMessage' => Array(),
1801 'usersMessage' => Array(),
1802 'users' => Array(),
1803 'userInGroup' => Array(),
1804 'files' => Array(),
1805 'countMessage' => 0,
1806 'chat' => Array(),
1807 'userChatBlockStatus' => Array(),
1808 'userInChat' => Array(),
1809 'result' => false
1810 );
1811 $bLoadMessage = $bSpeedCheck? CIMMessenger::SpeedFileExists($this->user_id, IM_SPEED_GROUP): false;
1812 $count = CIMMessenger::SpeedFileGet($this->user_id, IM_SPEED_GROUP);
1813 if (!$bLoadMessage || ($bLoadMessage && intval($count) > 0))
1814 {
1815 /*$ssqlLastId = "R1.LAST_ID";
1816 $ssqlStatus = " AND R1.STATUS < ".IM_STATUS_READ;
1817 if (!is_null($lastId) && intval($lastId) > 0 && !CIMMessenger::CheckXmppStatusOnline())
1818 {
1819 $ssqlLastId = intval($lastId);
1820 $ssqlStatus = "";
1821 }
1822
1823 $arRelations = Array();
1824 if ($ssqlStatus <> '')
1825 {
1826 $strSql ="
1827 SELECT
1828 R1.USER_ID,
1829 R1.CHAT_ID,
1830 R1.LAST_ID
1831 FROM
1832 b_im_relation R1
1833 WHERE
1834 R1.USER_ID = ".$this->user_id."
1835 ".($messageType == 'ALL'? "AND R1.MESSAGE_TYPE IN ('".IM_MESSAGE_OPEN."','".IM_MESSAGE_CHAT."','".IM_MESSAGE_OPEN_LINE."')": "AND R1.MESSAGE_TYPE = '".$messageType."'")."
1836 ".$ssqlStatus."
1837 ";
1838 $dbSubRes = $DB->Query($strSql);
1839 while ($arRes = $dbSubRes->Fetch())
1840 {
1841 //$ssqlLastId = intval($arRes['LAST_ID']);
1842 $arRelations[] = $arRes;
1843 }
1844 }*/
1845
1846 $arMessageId = Array();
1847 $arMessageChatId = Array();
1848 $arLastMessage = Array();
1849 $arMark = Array();
1850 $arChat = Array();
1851
1852 $arPrepareResult = Array();
1853 $arFilteredResult = Array();
1854
1855 if (!$bTimeZone)
1856 CTimeZone::Disable();
1857 $groupTypes = self::implodeTypesForQuery(self::getGroupTypes());
1858 $strSql = "
1859 SELECT
1860 M.ID,
1861 M.CHAT_ID,
1862 M.MESSAGE,
1863 ".$DB->DatetimeToTimestampFunction('M.DATE_CREATE')." as DATE_CREATE,
1864 M.AUTHOR_ID,
1865 R1.MESSAGE_TYPE as MESSAGE_TYPE
1866 FROM b_im_message M
1867 INNER JOIN b_im_relation R1 ON M.CHAT_ID = R1.CHAT_ID AND R1.USER_ID != M.AUTHOR_ID
1868 INNER JOIN b_im_message_unread MU ON M.ID = MU.MESSAGE_ID AND MU.USER_ID = " . $this->user_id . "
1869 WHERE
1870 R1.USER_ID = ".$this->user_id."
1871 ".($messageType == 'ALL'? "AND R1.MESSAGE_TYPE IN ({$groupTypes})": "AND R1.MESSAGE_TYPE = '".$messageType."'")."
1872 ";
1873 if (!$bTimeZone)
1874 CTimeZone::Enable();
1875
1876 $strSql = $DB->TopSql($strSql, 1000);
1877
1878 $dbRes = $DB->Query($strSql);
1879
1880 while ($arRes = $dbRes->Fetch())
1881 {
1882 $arPrepareResult[$arRes['CHAT_ID']][$arRes['ID']] = $arRes;
1883 }
1884 foreach ($arPrepareResult as $chatId => $arRes)
1885 {
1886 if (count($arPrepareResult[$chatId]) > 100)
1887 {
1888 $arPrepareResult[$chatId] = array_slice($arRes, -100, 100);
1889 }
1890 $arFilteredResult = array_merge($arFilteredResult, $arPrepareResult[$chatId]);
1891 }
1892 unset($arPrepareResult);
1893
1894 foreach ($arFilteredResult as $arRes)
1895 {
1896 $arUsers[] = $arRes['AUTHOR_ID'];
1897
1898 $arMessages[$arRes['ID']] = Array(
1899 'id' => $arRes['ID'],
1900 'chatId' => $arRes['CHAT_ID'],
1901 'senderId' => $arRes['AUTHOR_ID'],
1902 'recipientId' => $arRes['CHAT_ID'],
1903 'date' => DateTime::createFromTimestamp($arRes['DATE_CREATE']),
1904 'text' => $arRes['MESSAGE'],
1905 'messageType' => $arRes['MESSAGE_TYPE'],
1906 );
1907 if ($bGroupByChat)
1908 {
1909 $arMessages[$arRes['ID']]['conversation'] = $arRes['CHAT_ID'];
1910 $arMessages[$arRes['ID']]['unread'] = $this->user_id != $arRes['AUTHOR_ID']? 'Y': 'N';
1911 }
1912 else
1913 {
1914 $arUsersMessage[$arRes['CHAT_ID']][] = $arRes['ID'];
1915 }
1916
1917 /*if ($arRes['R1_STATUS'] == IM_STATUS_UNREAD && (!isset($arMark[$arRes["CHAT_ID"]]) || $arMark[$arRes["CHAT_ID"]] < $arRes["ID"]))
1918 $arMark[$arRes["CHAT_ID"]] = $arRes["ID"];*/
1919
1920 if (!isset($arLastMessage[$arRes["CHAT_ID"]]) || $arLastMessage[$arRes["CHAT_ID"]] < $arRes["ID"])
1921 $arLastMessage[$arRes["CHAT_ID"]] = $arRes["ID"];
1922
1923 $arChat[$arRes["CHAT_ID"]] = $arRes["CHAT_ID"];
1924 $arMessageId[] = $arRes['ID'];
1925 $arMessageChatId[$arRes['CHAT_ID']][$arRes["ID"]] = $arRes["ID"];
1926 }
1927 $params = CIMMessageParam::Get($arMessageId);
1928
1929 if ($bFileLoad)
1930 {
1931 foreach ($arMessageChatId as $chatId => $messages)
1932 {
1933 $files = Array();
1934 foreach ($messages as $messageId)
1935 {
1936 $arMessages[$messageId]['params'] = $params[$messageId];
1937
1938 if (isset($params[$messageId]['FILE_ID']))
1939 {
1940 foreach ($params[$messageId]['FILE_ID'] as $fileId)
1941 {
1942 $files[$fileId] = $fileId;
1943 }
1944 }
1945 }
1946
1947 $arMessageFiles = CIMDisk::GetFiles($chatId, $files);
1948 foreach ($arMessageFiles as $key => $value)
1949 {
1950 $arResult['files'][$chatId][$key] = $value;
1951 }
1952 }
1953 }
1954 else
1955 {
1956 foreach ($params as $messageId => $param)
1957 {
1958 $arMessages[$messageId]['params'] = $param;
1959 }
1960 }
1961
1962 if (!empty($arMessages))
1963 {
1964 foreach ($arMark as $chatId => $lastSendId)
1965 CIMMessage::SetLastSendId($chatId, $this->user_id, $lastSendId);
1966 }
1967
1968 if ($bGroupByChat)
1969 {
1970 foreach ($arMessages as $key => $value)
1971 {
1972 $arMessages[$arLastMessage[$value['conversation']]]['counter']++;
1973 if ($arLastMessage[$value['conversation']] != $value['id'])
1974 {
1975 unset($arMessages[$key]);
1976 }
1977 else
1978 {
1979 $arMessages[$key]['text'] = \Bitrix\Im\Text::parse($value['text']);
1980 $arMessages[$key]['textLegacy'] = \Bitrix\Im\Text::parseLegacyFormat($value['text']);
1981
1982 $arUsersMessage[$value['conversation']][] = $value['id'];
1983
1984 if ($value['params']['NOTIFY'] === 'N' || is_array($value['params']['NOTIFY']) && !in_array($this->user_id, $value['params']['NOTIFY']))
1985 {
1986 // skip unread
1987 }
1988 else if ($value['unread'] == 'Y')
1989 {
1990 $arUnreadMessage[$value['conversation']][] = $value['id'];
1991 }
1992
1993 unset($arMessages[$key]['conversation']);
1994 unset($arMessages[$key]['unread']);
1995 }
1996 }
1997 }
1998 else
1999 {
2000 foreach ($arMessages as $key => $value)
2001 {
2002 $arMessages[$key]['text'] = \Bitrix\Im\Text::parse($value['text']);
2003 $arMessages[$key]['textLegacy'] = \Bitrix\Im\Text::parseLegacyFormat($value['text']);
2004
2005 if ($value['params']['NOTIFY'] === 'N' || is_array($value['params']['NOTIFY']) && !in_array($this->user_id, $value['params']['NOTIFY']))
2006 {
2007 // skip unread
2008 }
2009 else if ($this->user_id != $value['senderId'])
2010 {
2011 $arUnreadMessage[$value['chatId']][] = $value['id'];
2012 }
2013 }
2014 }
2015
2016 $arResult['message'] = $arMessages;
2017 $arResult['unreadMessage'] = $arUnreadMessage;
2018 $arResult['usersMessage'] = $arUsersMessage;
2019
2020 $arChat = self::GetChatData(array(
2021 'ID' => $arChat,
2022 'USE_CACHE' => 'N'
2023 ));
2024 if (!empty($arChat))
2025 {
2026 $arResult['lines'] = $arChat['lines'];
2027 $arResult['chat'] = $arChat['chat'];
2028 $arResult['userChatBlockStatus'] = $arChat['userChatBlockStatus'];
2029 $arResult['userInChat'] = $arChat['userInChat'];
2030
2031 foreach ($arChat['userInChat'] as $value)
2032 $arUsers[] = $value;
2033 }
2034
2035 if ($bUserLoad && !empty($arUsers))
2036 {
2037 $arUserData = CIMContactList::GetUserData(Array('ID' => array_diff(array_unique($arUsers), $arExistUserData), 'DEPARTMENT' => ($loadDepartment? 'Y': 'N')));
2038 $arResult['users'] = $arUserData['users'];
2039 $arResult['userInGroup'] = $arUserData['userInGroup'];
2040 }
2041 else
2042 {
2043 $arResult['users'] = Array();
2044 $arResult['userInGroup'] = Array();
2045 $arResult['userInGroup'] = Array();
2046 }
2047
2048 $arResult['countMessage'] = CIMMessenger::GetMessageCounter($this->user_id, $arResult);
2049 if (!$bGroupByChat)
2050 CIMMessenger::SpeedFileCreate($this->user_id, $arResult['countMessage'], IM_SPEED_GROUP);
2051 $arResult['result'] = true;
2052 }
2053 else
2054 {
2055 $arResult['countMessage'] = CIMMessenger::GetMessageCounter($this->user_id, $arResult);
2056 }
2057
2058 return $arResult;
2059 }
2060
2061 public function SetOwner($chatId, $userId, $checkPermission = true)
2062 {
2063 $chatId = intval($chatId);
2064 $userId = intval($userId);
2065
2066 $chat = IM\Model\ChatTable::getById($chatId)->fetch();
2067 if (!$chat)
2068 {
2069 return false;
2070 }
2071
2072 if ($checkPermission && $chat['AUTHOR_ID'] != $this->user_id)
2073 {
2074 return false;
2075 }
2076
2077 if ($userId == $chat['AUTHOR_ID'])
2078 {
2079 return true;
2080 }
2081
2082 $arRelation = self::GetRelationById($chatId, false, true, false);
2083 if (!isset($arRelation[$userId]))
2084 {
2085 return false;
2086 }
2087
2088 if ($this->user_id !== 0 && !self::canDo($chat, $arRelation, IM\V2\Permission\Action::ChangeOwner))
2089 {
2090 return false;
2091 }
2092
2093 IM\Model\ChatTable::update($chatId, Array('AUTHOR_ID' => $userId));
2094 IM\Model\RelationTable::update($arRelation[$userId]['ID'], Array('MANAGER' => 'Y'));
2095 if (isset($arRelation[$chat['AUTHOR_ID']]))
2096 {
2097 IM\Model\RelationTable::update($arRelation[$chat['AUTHOR_ID']]['ID'], Array('MANAGER' => 'N'));
2098 }
2099
2100 if (CModule::IncludeModule('pull'))
2101 {
2102 \Bitrix\Pull\Event::add(array_keys($arRelation), Array(
2103 'module_id' => 'im',
2104 'command' => 'chatOwner',
2105 'params' => Array(
2106 'dialogId' => 'chat'.$chatId,
2107 'chatId' => (int)$chatId,
2108 'userId' => $userId
2109 ),
2110 'extra' => \Bitrix\Im\Common::getPullExtra()
2111 ));
2112 }
2113
2114 return true;
2115 }
2116
2117 public function SetDescription($chatId, $description)
2118 {
2119 $chatId = intval($chatId);
2120 $chat = Chat\GroupChat::getInstance($chatId);
2121
2122 if (!$chat instanceof Chat\GroupChat)
2123 {
2124 return false;
2125 }
2126
2127 if ($this->user_id !== 0 && !$chat->canDo(IM\V2\Permission\Action::ChangeDescription))
2128 {
2129 return false;
2130 }
2131
2133 (new Chat\Update\UpdateService($chat, $fields))->updateChat();
2134 $arRelation = $chat->getRelations()->getUserIds();
2135
2136 if (CModule::IncludeModule('pull'))
2137 {
2138 \Bitrix\Pull\Event::add(array_keys($arRelation), Array(
2139 'module_id' => 'im',
2140 'command' => 'chatDescription',
2141 'params' => Array(
2142 'chatId' => $chatId,
2143 'description' => \Bitrix\Im\Text::parse($description)
2144 ),
2145 'extra' => \Bitrix\Im\Common::getPullExtra()
2146 ));
2147 }
2148
2149 return true;
2150 }
2151
2152 public static function SetChatParams($chatId, $params)
2153 {
2154 $update = [];
2155 if (isset($params['ENTITY_TYPE']))
2156 $update['ENTITY_TYPE'] = $params['ENTITY_TYPE'];
2157
2158 if (isset($params['ENTITY_ID']))
2159 $update['ENTITY_ID'] = $params['ENTITY_ID'];
2160
2161 if (isset($params['ENTITY_DATA_1']))
2162 $update['ENTITY_DATA_1'] = $params['ENTITY_DATA_1'];
2163
2164 if (isset($params['ENTITY_DATA_2']))
2165 $update['ENTITY_DATA_2'] = $params['ENTITY_DATA_2'];
2166
2167 if (isset($params['ENTITY_DATA_3']))
2168 $update['ENTITY_DATA_3'] = $params['ENTITY_DATA_3'];
2169
2170 \Bitrix\Im\Model\ChatTable::update($chatId, $update);
2171
2172 if (CModule::IncludeModule('pull'))
2173 {
2174 if (isset($update['NAME']))
2175 {
2176 $update['NAME'] = htmlspecialcharsbx($update['NAME']);
2177 }
2178
2179 $arRelation = self::GetRelationById($chatId, false, true, false);
2180 \Bitrix\Pull\Event::add(array_keys($arRelation), Array(
2181 'module_id' => 'im',
2182 'command' => 'chatUpdateParams',
2183 'params' => Array(
2184 'dialogId' => 'chat'.$chatId,
2185 'chatId' => (int)$chatId,
2186 'params' => array_change_key_case($update)
2187 ),
2188 'extra' => \Bitrix\Im\Common::getPullExtra()
2189 ));
2190 }
2191
2192 return true;
2193 }
2194
2195 public function SetManager($chatId, $userId, $isManager = true, $checkPermission = true)
2196 {
2197 return $this->SetManagers($chatId, Array($userId => $isManager), $checkPermission);
2198 }
2199
2200 public function SetManagers($chatId, $users, $checkPermission = true)
2201 {
2202 $chatId = (int)$chatId;
2203 $chat = Chat::getInstance($chatId);
2204
2205 if (!$chat instanceof Chat\GroupChat)
2206 {
2207 return false;
2208 }
2209
2210 if (
2211 $checkPermission
2212 && $this->user_id !== 0
2213 && $chat->getAuthorId() !== $this->user_id
2214 && !$chat->canDo(IM\V2\Permission\Action::ChangeManagers))
2215 {
2216 return false;
2217 }
2218
2219 $chat->changeManagersByMap($users);
2220
2221 return true;
2222 }
2223
2224 public function SetColor($chatId, $color)
2225 {
2226 global $DB;
2227 $chatId = intval($chatId);
2228 $color = mb_strtoupper($color);
2229
2230 if ($chatId <= 0 || !IM\Color::isSafeColor($color))
2231 {
2232 return false;
2233 }
2234
2235 $groupTypes = self::implodeTypesForQuery(self::getGroupTypes());
2236
2237 $strSql = "
2238 SELECT
2239 R.CHAT_ID,
2240 C.COLOR as CHAT_COLOR,
2241 C.AUTHOR_ID as CHAT_AUTHOR_ID,
2242 C.TYPE as CHAT_TYPE,
2243 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
2244 C.ENTITY_ID as CHAT_ENTITY_ID,
2245 C.MANAGE_UI,
2246 C.MANAGE_USERS_ADD,
2247 C.MANAGE_USERS_DELETE,
2248 C.MANAGE_SETTINGS
2249 FROM
2250 b_im_relation R
2251 LEFT JOIN b_im_chat C
2252 ON R.CHAT_ID = C.ID
2253 WHERE
2254 R.USER_ID = ".$this->user_id."
2255 AND R.MESSAGE_TYPE IN ({$groupTypes})
2256 AND R.CHAT_ID = ".$chatId;
2257 $dbRes = $DB->Query($strSql);
2258 if ($arRes = $dbRes->Fetch())
2259 {
2260 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
2261 if ($arRes['CHAT_COLOR'] == $color)
2262 return false;
2263
2264 $ar = CIMChat::GetRelationById($chatId, false, true, false);
2265
2266 if ($this->user_id !== 0 && !self::canDo($arRes, $ar, IM\V2\Permission\Action::ChangeColor))
2267 {
2268 return false;
2269 }
2270
2271 IM\Model\ChatTable::update($chatId, array('COLOR' => $color));
2272
2274 'CHAT_ID' => $chatId,
2275 'USER_ID' => $this->user_id,
2276 'MESSAGE_CODE' => 'IM_CHAT_CHANGE_COLOR_',
2277 'MESSAGE_REPLACE' => Array('#CHAT_COLOR#' => IM\Color::getName($color))
2278 ));
2279
2280 if ($arRes['CHAT_ENTITY_TYPE'] == 'LINES')
2281 {
2282 foreach ($ar as $rel)
2283 {
2284 if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
2285 {
2286 unset($ar[$rel["USER_ID"]]);
2287 }
2288 }
2289 }
2290
2291 if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
2292 {
2293 CIMContactList::CleanAllChatCache();
2294 }
2295 else
2296 {
2297 foreach ($ar as $rel)
2298 {
2299 CIMContactList::CleanChatCache($rel['USER_ID']);
2300 }
2301 }
2302 if (CModule::IncludeModule("pull"))
2303 {
2304 $arPushMessage = Array(
2305 'module_id' => 'im',
2306 'command' => 'chatChangeColor',
2307 'expiry' => 3600,
2308 'params' => Array(
2309 'chatId' => $chatId,
2310 'color' => IM\Color::getColor($color),
2311 ),
2312 'extra' => \Bitrix\Im\Common::getPullExtra()
2313 );
2314 \Bitrix\Pull\Event::add(array_keys($ar), $arPushMessage);
2315 if (CIMMessenger::needToSendPublicPull($arRes['CHAT_TYPE']))
2316 {
2317 CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $arPushMessage);
2318 }
2319 }
2320
2321 return true;
2322 }
2323 return false;
2324 }
2325
2326 public function SetAvatarId($chatId, $fileId)
2327 {
2328 if ($chatId <= 0)
2329 {
2330 return false;
2331 }
2332
2333 $orm = \Bitrix\Im\Model\ChatTable::getById($chatId);
2334 $chat = $orm->fetch();
2335 if (!$chat)
2336 {
2337 return false;
2338 }
2339
2340 $relation = self::GetRelationById($chatId, false, true, false);
2341
2342 if ($this->user_id !== 0 && !self::canDo($chat, $relation, IM\V2\Permission\Action::ChangeAvatar))
2343 {
2344 return false;
2345 }
2346
2347 if ($fileId > 0)
2348 {
2349 $orm = \Bitrix\Main\FileTable::getById($fileId);
2350 $file = $orm->fetch();
2351 if (!$file)
2352 return false;
2353
2354 if ($file['HEIGHT'] <= 0 || $file['WIDTH'] <= 0)
2355 return false;
2356 }
2357
2358 IM\Model\ChatTable::update($chatId, Array('AVATAR' => $fileId));
2359
2360 if (CModule::IncludeModule('pull'))
2361 {
2362 $users = [];
2363 foreach ($relation as $rel)
2364 {
2365 if ($rel["EXTERNAL_AUTH_ID"] != 'imconnector')
2366 {
2367 $users[$rel['USER_ID']] = $rel['USER_ID'];
2368 }
2369 }
2370 \Bitrix\Pull\Event::add($users, Array(
2371 'module_id' => 'im',
2372 'command' => 'chatAvatar',
2373 'params' => Array(
2374 'chatId' => $chatId,
2375 'avatar' => self::GetAvatarImage($fileId),
2376 ),
2377 'extra' => \Bitrix\Im\Common::getPullExtra()
2378 ));
2379 }
2380
2381 return true;
2382 }
2383
2384 public function Rename($chatId, $title, $checkPermission = true, $sendMessage = true)
2385 {
2386 global $DB;
2387 $chatId = intval($chatId);
2388 $title = mb_substr(trim($title), 0, 255);
2389
2390 if ($chatId <= 0 || $title == '')
2391 {
2392 return false;
2393 }
2394
2395 $groupTypes = self::implodeTypesForQuery(self::getGroupTypes());
2396 if ($checkPermission)
2397 {
2398 $strSql = "
2399 SELECT
2400 R.CHAT_ID,
2401 C.TITLE as CHAT_TITLE,
2402 C.AUTHOR_ID as CHAT_AUTHOR_ID,
2403 C.TYPE as CHAT_TYPE,
2404 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
2405 C.ENTITY_ID as CHAT_ENTITY_ID,
2406 R.MANAGER as IS_MANAGER,
2407 C.MANAGE_UI,
2408 C.MANAGE_USERS_ADD,
2409 C.MANAGE_USERS_DELETE,
2410 C.MANAGE_SETTINGS
2411 FROM b_im_relation R LEFT JOIN b_im_chat C ON R.CHAT_ID = C.ID
2412 WHERE
2413 R.USER_ID = ".$this->user_id."
2414 AND R.MESSAGE_TYPE IN ({$groupTypes})
2415 AND R.CHAT_ID = ".$chatId;
2416 }
2417 else
2418 {
2419 $strSql = "
2420 SELECT
2421 C.ID as CHAT_ID,
2422 C.TITLE as CHAT_TITLE,
2423 C.AUTHOR_ID as CHAT_AUTHOR_ID,
2424 C.TYPE as CHAT_TYPE,
2425 C.ENTITY_TYPE as CHAT_ENTITY_TYPE,
2426 C.ENTITY_ID as CHAT_ENTITY_ID,
2427 'Y' as IS_MANAGER,
2428 C.MANAGE_UI,
2429 C.MANAGE_USERS_ADD,
2430 C.MANAGE_USERS_DELETE,
2431 C.MANAGE_SETTINGS
2432 FROM b_im_chat C
2433 WHERE
2434 C.ID = ".$chatId."
2435 AND C.TYPE IN ({$groupTypes})";
2436 }
2437 $dbRes = $DB->Query($strSql);
2438 if ($arRes = $dbRes->Fetch())
2439 {
2440 $ar = CIMChat::GetRelationById($chatId, false, true, false);
2441
2442 if ($this->user_id !== 0 && $checkPermission && !self::canDo($arRes, $ar, IM\V2\Permission\Action::Rename))
2443 {
2444 return false;
2445 }
2446
2447 $arRes['CHAT_TITLE'] = \Bitrix\Im\Text::decodeEmoji($arRes['CHAT_TITLE']);
2448
2449 if ($arRes['CHAT_TITLE'] == $title)
2450 return false;
2451
2452 if ($arRes['CHAT_ENTITY_TYPE'] === 'ANNOUNCEMENT' && $arRes['IS_MANAGER'] !== 'Y')
2453 {
2454 return false;
2455 }
2456
2457 $arRes['CHAT_TYPE'] = trim($arRes['CHAT_TYPE']);
2458
2459 IM\Model\ChatTable::update($chatId, array('TITLE' => $title));
2460
2461 if ($sendMessage)
2462 {
2463 if ($checkPermission)
2464 {
2465 if (
2466 $arRes['CHAT_TYPE'] === Chat::IM_TYPE_CHANNEL
2467 || $arRes['CHAT_TYPE'] === Chat::IM_TYPE_OPEN_CHANNEL
2468 )
2469 {
2470 $type = 'CHANNEL';
2471 $messageCodeVersion = '';
2472 }
2473 else
2474 {
2475 $type = 'CHAT';
2476 $messageCodeVersion = '_MSGVER_1';
2477 }
2478
2480 'CHAT_ID' => $chatId,
2481 'USER_ID' => $this->user_id,
2482 'MESSAGE_CODE' => "IM_{$type}_CHANGE_TITLE_",
2483 'MESSAGE_REPLACE' => Array('#CHAT_TITLE#' => $title),
2484 'MESSAGE_CODE_VERSION' => $messageCodeVersion,
2485 ));
2486 }
2487 else
2488 {
2489 self::AddMessage(Array(
2490 "TO_CHAT_ID" => $chatId,
2491 "MESSAGE" => GetMessage("IM_CHAT_CHANGE_TITLE", Array('#CHAT_TITLE#' => $title)),
2492 "SYSTEM" => 'Y',
2493 "SKIP_USER_CHECK" => 'Y',
2494 ));
2495 }
2496 }
2497
2498 if ($arRes['CHAT_ENTITY_TYPE'] == 'LINES')
2499 {
2500 foreach ($ar as $rel)
2501 {
2502 if ($rel["EXTERNAL_AUTH_ID"] == 'imconnector')
2503 {
2504 unset($ar[$rel["USER_ID"]]);
2505 }
2506 }
2507 }
2508
2509 if ($arRes['CHAT_TYPE'] == IM_MESSAGE_OPEN)
2510 {
2511 CIMContactList::CleanAllChatCache();
2512 }
2513 else
2514 {
2515 foreach ($ar as $rel)
2516 {
2517 CIMContactList::CleanChatCache($rel['USER_ID']);
2518 }
2519 }
2520 if (CModule::IncludeModule("pull"))
2521 {
2522 $pushMessage = Array(
2523 'module_id' => 'im',
2524 'command' => 'chatRename',
2525 'params' => Array(
2526 'chatId' => $chatId,
2527 'name' => \Bitrix\Main\Text\Emoji::decode($title),
2528 ),
2529 'extra' => \Bitrix\Im\Common::getPullExtra()
2530 );
2531 \Bitrix\Pull\Event::add(array_keys($ar), $pushMessage);
2532 if (CIMMessenger::needToSendPublicPull($arRes['CHAT_TYPE']))
2533 {
2534 CPullWatch::AddToStack('IM_PUBLIC_'.$chatId, $pushMessage);
2535 }
2536 if ($arRes['CHAT_TYPE'] === Chat::IM_TYPE_OPEN_CHANNEL)
2537 {
2539 }
2540 }
2541
2542 foreach(GetModuleEvents("im", "OnChatRename", true) as $arEvent)
2543 {
2544 ExecuteModuleEventEx($arEvent, array($chatId, $title, $arRes['CHAT_ENTITY_TYPE'], $arRes['CHAT_ENTITY_ID'], $this->user_id));
2545 }
2546
2547 return true;
2548 }
2549 return false;
2550 }
2551
2560 public function Add($arParams)
2561 {
2562 $type = '';
2563 if (isset($arParams['MESSAGE_TYPE']))
2564 {
2565 $type = $arParams['MESSAGE_TYPE'];
2566 }
2567 elseif (isset($arParams['TYPE']))
2568 {
2569 $type = $arParams['MESSAGE_TYPE'] = $arParams['TYPE'];
2570 }
2571
2572 $arParams['USER_ID'] = $this->user_id;
2573
2574 $authorId = $arParams['USER_ID'];
2575 if (isset($arParams['AUTHOR_ID']))
2576 {
2577 $authorId = intval($arParams['AUTHOR_ID']);
2578 }
2579
2580 if (isset($arParams['OWNER_ID']))
2581 {
2582 $authorId = intval($arParams['OWNER_ID']);
2583 }
2584
2585 if ($authorId)
2586 {
2587 $arParams['AUTHOR_ID'] = $authorId;
2588 }
2589
2590 if (isset($arParams['AVATAR_ID']))
2591 {
2592 $arParams['AVATAR'] = (int) $arParams['AVATAR_ID'];
2593 }
2594
2595 $chatResult = IM\V2\Chat\ChatFactory::getInstance()->addChat($arParams);
2596 if (!$chatResult->isSuccess() || !$chatResult->hasResult())
2597 {
2598 return false;
2599 }
2600
2601 if (isset($arParams['MESSAGE']))
2602 {
2603 $message = trim($arParams['MESSAGE']);
2604 }
2605
2606 if (isset($message) && $message)
2607 {
2608 if ($type === IM\V2\Chat::IM_TYPE_PRIVATE)
2609 {
2611 "FROM_USER_ID" => $this->user_id,
2612 "TO_USER_ID" => $this->user_id,
2613 "MESSAGE" => $message,
2614 ]);
2615 }
2616 else
2617 {
2618 self::AddMessage([
2619 "TO_CHAT_ID" => $chatResult->getResult()['CHAT_ID'],
2620 "FROM_USER_ID" => $this->user_id,
2621 "SYSTEM" => $this->user_id ? 'N' : 'Y',
2622 "MESSAGE" => $message,
2623 ]);
2624 }
2625 }
2626
2627 $chat = $chatResult->getResult()['CHAT'];
2628
2629 CIMContactList::CleanAllChatCache();
2630
2631 return $chat->getChatId();
2632 }
2633
2634 public static function AddMessage($arFields)
2635 {
2636 $arFields['MESSAGE_TYPE'] = IM_MESSAGE_CHAT;
2637
2638 return CIMMessenger::Add($arFields);
2639 }
2640
2641 public function Join($chatId)
2642 {
2643 $chatId = intval($chatId);
2644 if ($chatId <= 0)
2645 {
2646 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "EMPTY_CHAT_ID");
2647 return false;
2648 }
2649
2650 $orm = IM\Model\ChatTable::getById($chatId);
2651 if (!($chatData = $orm->fetch()))
2652 {
2653 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_CHAT_NOT_EXISTS"), "ERROR_CHAT_NOT_EXISTS");
2654 return false;
2655 }
2656
2657 if ($chatData['TYPE'] != IM_MESSAGE_OPEN)
2658 {
2659 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_ACCESS_JOIN"), "ACCESS_JOIN");
2660 return false;
2661 }
2662
2663 if (IM\User::getInstance($this->user_id)->isExtranet())
2664 {
2665 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_ACCESS_JOIN"), "ACCESS_JOIN");
2666 return false;
2667 }
2668
2669 $chat = new CIMChat(0);
2670 $chat->AddUser($chatId, $this->user_id);
2671
2672 return true;
2673 }
2674
2675 public function JoinParent($chatId, $messageId)
2676 {
2677 $chatId = intval($chatId);
2678 if ($chatId <= 0)
2679 {
2680 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "EMPTY_CHAT_ID");
2681 return false;
2682 }
2683
2684 $messageId = intval($messageId);
2685 if ($messageId <= 0)
2686 {
2687 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "EMPTY_CHAT_ID");
2688 return false;
2689 }
2690
2691 $CIMMessage = new CIMMessage($this->user_id);
2692 $message = $CIMMessage->GetMessage($messageId, true);
2693 if (!$message)
2694 {
2695 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_ACCESS_JOIN"), "ACCESS_JOIN");
2696 return false;
2697 }
2698
2699 $relations = IM\Chat::getRelation($chatId, ['WITHOUT_COUNTERS' => 'Y']);
2700 if (!isset($relations[$this->user_id]))
2701 {
2702 $chat = new CIMChat(0);
2703 $chat->AddUser($chatId, $this->user_id);
2704 }
2705
2706 return true;
2707 }
2708
2709 public function AddUser($chatId, $userId, $hideHistory = null, $skipMessage = false, $skipRecent = false, $skipRelation = false)
2710 {
2711 $chatId = intval($chatId);
2712 if ($chatId <= 0)
2713 {
2714 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_CHAT_ID"), "EMPTY_CHAT_ID");
2715 return false;
2716 }
2717
2718 $arUserId = Array();
2719 if (is_array($userId))
2720 {
2721 $arUserId = \CIMContactList::PrepareUserIds($userId);
2722 }
2723 else if (intval($userId) > 0)
2724 {
2725 $arUserId[intval($userId)] = intval($userId);
2726 }
2727 if ($this->user_id > 0)
2728 {
2729 $arUserId[$this->user_id] = $this->user_id;
2730 }
2731
2732 if (count($arUserId) <= 0)
2733 {
2734 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_USER_ID"), "EMPTY_USER_ID");
2735 return false;
2736 }
2737
2738 $chat = Chat::getInstance($chatId)->withContextUser($this->user_id);
2739
2740 if ($this->user_id !== 0 && !$chat->canDo(IM\V2\Permission\Action::Extend))
2741 {
2742 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_CHAT_ACCESS_DENIED_EXTEND_USERS"), "ACCESS_DENIED_EXTEND");
2743 return false;
2744 }
2745
2746 $config = new IM\V2\Relation\AddUsersConfig([], $hideHistory, !$skipMessage, $skipRecent, $skipRelation);
2747 $chat->addUsers($arUserId, $config);
2748
2749 return true;
2750 }
2751
2752 public function MuteNotify($chatId, $mute = true)
2753 {
2754 return \Bitrix\Im\Chat::mute($chatId, $mute, $this->user_id);
2755 }
2756
2757 public function DeleteUser(
2758 $chatId,
2759 $userId,
2760 $checkPermission = true,
2761 $skipMessage = false,
2762 $skipRecent = false,
2763 $withoutRead = false,
2764 $additionalParams = []
2765 )
2766 {
2767 $chatId = (int)$chatId;
2768 $userId = (int)$userId;
2769
2770 if ($chatId <= 0 || $userId <= 0)
2771 {
2772 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_EMPTY_USER_OR_CHAT"), "EMPTY_USER_OR_CHAT");
2773
2774 return false;
2775 }
2776
2777 $chat = Chat::getInstance($chatId)->withContextUser($this->user_id);
2778
2779 if ($this->user_id !== 0 && !$chat->canDo(IM\V2\Permission\Action::Kick, $userId))
2780 {
2781 if ($this->user_id === $userId && $chat->getAuthorId() === $userId)
2782 {
2783 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_LEAVE_OWNER_FORBIDDEN"), "LEAVE_OWNER_FORBIDDEN");
2784 }
2785 else
2786 {
2787 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_CHAT_ACCESS_DENIED_KICK_USERS"), "ACCESS_DENIED_KICK");
2788 }
2789
2790 return false;
2791 }
2792
2793 if ($checkPermission && $this->user_id !== $userId && $chat->getAuthorId() !== $this->user_id)
2794 {
2795 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_KICK"), "IM_ERROR_KICK");
2796
2797 return false;
2798 }
2799
2801 !$skipMessage,
2802 $skipRecent,
2803 true,
2804 false,
2805 $withoutRead
2806 );
2807 $result = $chat->deleteUser($userId, $config);
2808
2809 if ($result->getError() !== null)
2810 {
2811 if ($result->getError()?->getCode() === UserError::NOT_FOUND)
2812 {
2813 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("IM_ERROR_USER_NOT_FOUND"), UserError::NOT_FOUND);
2814
2815 return false;
2816 }
2817
2818 $GLOBALS["APPLICATION"]->ThrowException($result->getError()->getMessage(), $result->getError()->getCode());
2819
2820 return false;
2821 }
2822
2823 return true;
2824 }
2825
2826 public static function GetAvatarImage($id, $size = 200, $addBlankPicture = true)
2827 {
2828 $url = $addBlankPicture? '/bitrix/js/im/images/blank.gif': '';
2829
2830 $id = intval($id);
2831 if ($id > 0 && $size > 0)
2832 {
2833 $arFileTmp = CFile::ResizeImageGet(
2834 $id,
2835 array('width' => $size, 'height' => $size),
2837 false,
2838 false,
2839 true
2840 );
2841 if (!empty($arFileTmp['src']))
2842 {
2843 $url = $arFileTmp['src'];
2844 }
2845 }
2846 return $url;
2847 }
2848
2849 public static function AddSystemMessage($params)
2850 {
2851 $chatId = intval($params['CHAT_ID']);
2852 if ($chatId <= 0)
2853 return false;
2854
2855 $arUser = false;
2856 $userId = intval($params['USER_ID']);
2857 if ($userId > 0)
2858 {
2859 $arSelect = Array("ID", "LAST_NAME", "NAME", "LOGIN", "SECOND_NAME", "PERSONAL_GENDER");
2860 $dbUsers = CUser::GetList('', '', array('ID_EQUAL_EXACT' => $userId), array('FIELDS' => $arSelect));
2861 if ($arUser = $dbUsers->Fetch())
2862 {
2863 $arUser['NAME'] = \Bitrix\Im\User::formatFullNameFromDatabase($arUser);
2864 $arUser['PERSONAL_GENDER'] = $arUser["PERSONAL_GENDER"] == 'F'? 'F': 'M';
2865 }
2866 }
2867
2868 if (isset($params['MESSAGE_CODE']))
2869 {
2870 $messageCodeVersion = $params['MESSAGE_CODE_VERSION'] ?? '';
2871 $messageReplace = is_array($params['MESSAGE_REPLACE'])? $params['MESSAGE_REPLACE']: Array();
2872 if ($arUser)
2873 {
2874 $messageReplace['#USER_NAME#'] = $arUser['NAME'];
2875 $message = GetMessage($params['MESSAGE_CODE'].$arUser['PERSONAL_GENDER'].$messageCodeVersion, $messageReplace);
2876 }
2877 else
2878 {
2879 $message = GetMessage($params['MESSAGE_CODE'], $messageReplace);
2880 }
2881 }
2882 else
2883 {
2884 $messageReplace = is_array($params['MESSAGE_REPLACE'])? $params['MESSAGE_REPLACE']: Array();
2885 $message = trim($params['MESSAGE']);
2886 if ($message <> '' && !empty($messageReplace))
2887 {
2888 $message = str_replace(array_keys($messageReplace), array_values($messageReplace), $message);
2889 }
2890 }
2891 if ($message == '')
2892 return false;
2893
2894 return self::AddMessage(Array(
2895 "TO_CHAT_ID" => $chatId,
2896 "FROM_USER_ID" => $userId,
2897 "MESSAGE" => $message,
2898 "SYSTEM" => 'Y',
2899 "SKIP_USER_CHECK" => 'Y',
2900 ));
2901 }
2902
2903 public static function CheckRestriction($chatId, $action)
2904 {
2905 if (is_int($chatId))
2906 {
2907 if (self::GetGeneralChatId() == $chatId)
2908 {
2909 $chat['ENTITY_TYPE'] = 'GENERAL';
2910 }
2911 else
2912 {
2913 $chat = IM\Model\ChatTable::getById($chatId)->fetch();
2914 if (!$chat)
2915 return true;
2916 }
2917 }
2918 else if(is_array($chatId))
2919 {
2920 $chat = $chatId;
2921 }
2922 else
2923 {
2924 return true;
2925 }
2926
2927 $options = self::GetChatOptions();
2928 if (isset($options[$chat['ENTITY_TYPE']][$action]) && !self::$entityOption[$chat['ENTITY_TYPE']][$action])
2929 {
2930 return true;
2931 }
2932
2933 return false;
2934 }
2935
2936 public static function GetChatOptions()
2937 {
2938 if (!is_null(self::$entityOption))
2939 {
2940 return self::$entityOption;
2941 }
2942
2943 global $USER;
2944
2945 self::$entityOption = [];
2946
2947 $default = [
2948 'AVATAR' => true,
2949 'RENAME' => true,
2950 'EXTEND' => true,
2951 'CALL' => true,
2952 'MUTE' => true,
2953 'LEAVE' => true,
2954 'LEAVE_OWNER' => true,
2955 'SEND' => true,
2956 'USER_LIST' => true,
2957 ];
2958
2959 self::$entityOption['GENERAL'] = [
2960 'AVATAR' => false,
2961 'RENAME' => false,
2962 'EXTEND' => false,
2963 'CALL' => true,
2964 'LEAVE' => false,
2965 'LEAVE_OWNER' => false,
2966 'SEND' => CIMChat::CanSendMessageToGeneralChat(($USER instanceof \CUser) ? (int)$USER->GetID() : null)
2967 ];
2968
2969 if (\Bitrix\Main\Loader::includeModule('imbot'))
2970 {
2971 self::$entityOption[\Bitrix\ImBot\Service\Notifier::CHAT_ENTITY_TYPE] = [
2972 'AVATAR' => false,
2973 'RENAME' => false,
2974 'LEAVE_OWNER' => false,
2975 ];
2976 self::$entityOption[\Bitrix\ImBot\Bot\Support24::CHAT_ENTITY_TYPE] = [
2977 'AVATAR' => false,
2978 'RENAME' => true,
2979 'EXTEND' => false,
2980 'CALL' => false,
2981 'MUTE' => false,
2982 'LEAVE' => false,
2983 'LEAVE_OWNER' => false,
2984 'USER_LIST' => false,
2985 ];
2986 self::$entityOption[\Bitrix\ImBot\Bot\Network::CHAT_ENTITY_TYPE] =
2987 self::$entityOption[\Bitrix\ImBot\Bot\Support24::CHAT_ENTITY_TYPE]
2988 ;
2989 }
2990
2991 if (\Bitrix\Main\ModuleManager::isModuleInstalled('socialnetwork'))
2992 {
2993 $path = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID);
2994 $path = $path.'group/#ID#/';
2995
2996 self::$entityOption['SONET_GROUP'] = [
2997 'AVATAR' => false,
2998 'RENAME' => false,
2999 'EXTEND' => false,
3000 'LEAVE' => false,
3001 'LEAVE_OWNER' => false,
3002 'PATH' => $path,
3003 'PATH_TITLE' => GetMessage('IM_PATH_TITLE_SONET')
3004 ];
3005 }
3006
3007 if (\Bitrix\Main\Loader::includeModule('tasks'))
3008 {
3009 $path = \CTasksTools::GetOptionPathTaskUserEntry(SITE_ID, "/company/personal/user/#user_id#/tasks/task/view/#task_id#/");
3010 $path = str_replace(Array('#user_id#', '#task_id#'), Array(($USER instanceof \CUser) ? (int)$USER->GetId() : 0, '#ID#'), mb_strtolower($path));
3011
3012 self::$entityOption['TASKS'] = Array(
3013 'AVATAR' => true,
3014 'RENAME' => true,
3015 'EXTEND' => true,
3016 'LEAVE' => true,
3017 'LEAVE_OWNER' => true,
3018 'PATH' => $path,
3019 'PATH_TITLE' => GetMessage('IM_PATH_TITLE_TASKS')
3020 );
3021 }
3022
3023 if (\Bitrix\Main\Loader::includeModule('calendar'))
3024 {
3025 $path = \CCalendar::GetPathForCalendarEx(($USER instanceof \CUser) ? (int)$USER->GetId() : 0);
3026 $path = \CHTTP::urlAddParams($path, ['EVENT_ID' => '#ID#']);
3027
3028 self::$entityOption[\CCalendar::CALENDAR_CHAT_ENTITY_TYPE] = Array(
3029 'AVATAR' => true,
3030 'RENAME' => true,
3031 'EXTEND' => true,
3032 'LEAVE' => true,
3033 'LEAVE_OWNER' => true,
3034 'PATH' => $path,
3035 'PATH_TITLE' => GetMessage('IM_PATH_TITLE_CALENDAR_EVENT')
3036 );
3037 }
3038
3039 if (\Bitrix\Main\Loader::includeModule('crm'))
3040 {
3041 self::$entityOption['CRM'] = Array(
3042 'AVATAR' => false,
3043 'RENAME' => false,
3044 'EXTEND' => true,
3045 'LEAVE' => true,
3046 'LEAVE_OWNER' => false,
3047 'PATH' => '',
3048 'PATH_TITLE' => ''
3049 );
3050 }
3051
3052 if (\Bitrix\Main\Loader::includeModule('voximplant'))
3053 {
3054 self::$entityOption['CALL'] = Array(
3055 'AVATAR' => true,
3056 'RENAME' => true,
3057 'EXTEND' => false,
3058 'CALL' => false,
3059 'MUTE' => false,
3060 'LEAVE' => false,
3061 'LEAVE_OWNER' => false,
3062 'SEND' => true,
3063 'USER_LIST' => true,
3064 );
3065 }
3066
3067 foreach (self::$entityOption as $code => $value)
3068 {
3069 self::$entityOption[$code] = array_merge($default, $value);
3070 }
3071
3072 self::$entityOption['DEFAULT'] = $default;
3073
3074 return self::$entityOption;
3075 }
3076
3077 public static function GetSonetGroupChatId($groupId)
3078 {
3079 if (!CModule::IncludeModule('socialnetwork'))
3080 return false;
3081
3083 'group_id' => $groupId,
3084 'skipAvailabilityCheck' => true
3085 ));
3086 if (!empty($chatData[$groupId]) && intval($chatData[$groupId]) > 0)
3087 {
3088 $chatId = $chatData[$groupId];
3089 }
3090 else
3091 {
3093 'group_id' => $groupId
3094 ));
3095 }
3096
3097 return $chatId;
3098 }
3099
3100 public static function GetCrmChatId($code)
3101 {
3102 if (!CModule::IncludeModule('crm'))
3103 return false;
3104
3105 [$entityType, $entityId] = explode('|', $code);
3106
3107 global $USER;
3108
3109 $chatId = \Bitrix\Crm\Integration\Im\Chat::joinChat(Array(
3110 'ENTITY_TYPE' => $entityType,
3111 'ENTITY_ID' => $entityId,
3112 'USER_ID' => $USER->GetId()
3113 ));
3114
3115 return $chatId;
3116 }
3117
3118 public static function GetUserCount($chatId)
3119 {
3120 $result = \Bitrix\Im\Model\ChatTable::getList(
3121 [
3122 'select' => ['USER_COUNT'],
3123 'filter' => ['=ID' => $chatId]
3124 ]
3125 )->fetch();
3126
3127 if (!$result)
3128 {
3129 return false;
3130 }
3131
3132 return (int)$result['USER_COUNT'];
3133 }
3134
3135 public static function GetEntityChat($entityType, $entityId)
3136 {
3137 $entityType = trim($entityType);
3138 $entityId = trim($entityId);
3139
3140 if (empty($entityType) || empty($entityId))
3141 {
3142 return false;
3143 }
3144
3145 $chatData = \Bitrix\Im\Model\ChatTable::getList(Array(
3146 'select' => ['ID'],
3147 'filter' => [
3148 '=ENTITY_TYPE' => $entityType,
3149 '=ENTITY_ID' => $entityId,
3150 ]
3151 ))->fetch();
3152
3153 if (!$chatData)
3154 {
3155 return false;
3156 }
3157
3158 return $chatData['ID'];
3159 }
3160
3161 public static function DeleteEntityChat($entityType, $entityId)
3162 {
3163 $entityType = trim($entityType);
3164 $entityId = trim($entityId);
3165
3166 if (empty($entityType) || empty($entityId))
3167 {
3168 return false;
3169 }
3170
3171 $chatData = \Bitrix\Im\Model\ChatTable::getList(Array(
3172 'select' => ['ID', 'DISK_FOLDER_ID'],
3173 'filter' => [
3174 '=ENTITY_TYPE' => $entityType,
3175 '=ENTITY_ID' => $entityId,
3176 ],
3177 ))->fetch();
3178 if (!$chatData)
3179 {
3180 return false;
3181 }
3182
3183 self::deleteChat($chatData);
3184
3185 return true;
3186 }
3187
3188 public static function deleteChat(array $chatData): void
3189 {
3190 global $DB;
3191
3192 self::hide($chatData['ID']);
3193
3194 $strSQL = "DELETE FROM b_im_chat WHERE ID = ".$chatData['ID'];
3195 $DB->Query($strSQL, true);
3196
3197 $strSQL = "DELETE FROM b_im_relation WHERE CHAT_ID = ".$chatData['ID'];
3198 $DB->Query($strSQL, true);
3199
3200 $strSQL = "DELETE FROM b_im_message WHERE CHAT_ID = ".$chatData['ID'];
3201 $DB->Query($strSQL, true);
3202
3203 IM\V2\Link\Url\UrlCollection::deleteByChatsIds([(int)$chatData['ID']]);
3204 IM\V2\Chat::cleanCache((int)$chatData['ID']);
3205
3206 if ($chatData['DISK_FOLDER_ID'])
3207 {
3208 $folderModel = \Bitrix\Disk\Folder::getById($chatData['DISK_FOLDER_ID']);
3209 if ($folderModel)
3210 {
3211 $folderModel->deleteTree(\Bitrix\Disk\SystemUser::SYSTEM_USER_ID);
3212 }
3213 }
3214 }
3215
3216 public static function hide($chatId)
3217 {
3218 $pushList = [];
3219 $lines = false;
3220 $relations = \CIMChat::GetRelationById($chatId, false, true, false);
3221 foreach($relations as $userId => $relation)
3222 {
3223 if ($relation['MESSAGE_TYPE'] === Chat::IM_TYPE_OPEN_LINE)
3224 {
3225 $lines = true;
3226 }
3227 \CIMContactList::DeleteRecent($chatId, true, $userId);
3228
3229 if (!\Bitrix\Im\User::getInstance($userId)->isConnector())
3230 {
3231 $pushList[] = $userId;
3232 }
3233 }
3234
3235 if (
3236 !empty($pushList)
3238 )
3239 {
3240 \Bitrix\Pull\Event::add($pushList, Array(
3241 'module_id' => 'im',
3242 'command' => 'chatHide',
3243 'expiry' => 3600,
3244 'params' => Array(
3245 'dialogId' => 'chat'.$chatId,
3246 'chatId' => $chatId,
3247 'lines' => $lines
3248 ),
3249 'extra' => \Bitrix\Im\Common::getPullExtra()
3250 ));
3251 }
3252
3253 return true;
3254 }
3255
3256 public static function index($chatId)
3257 {
3258 $index =
3260 ->setChatId((int)$chatId)
3261 ;
3262 static::fillChatIndexWithUserFullNames($index);
3263
3265
3266 return true;
3267 }
3268
3269 public static function addChatIndex(int $chatId, string $chatTitle)
3270 {
3271 $index =
3273 ->setChatId($chatId)
3274 ->setTitle($chatTitle)
3275 ;
3276 static::fillChatIndexWithUserFullNames($index);
3277
3279
3280 return true;
3281 }
3282
3283 public static function updateChatIndex($chatId)
3284 {
3285 $index =
3287 ->setChatId((int)$chatId)
3288 ;
3289 static::fillChatIndexWithUserFullNames($index);
3290
3292
3293 return true;
3294 }
3295
3296 public static function fillChatIndexWithUserFullNames(\Bitrix\Im\Internals\ChatIndex $index)
3297 {
3298 $query =
3299 \Bitrix\Im\Model\RelationTable::query()
3300 ->addSelect('USER_ID')
3301 ->where('CHAT_ID', $index->getChatId())
3302 ->setLimit(100)
3303 ;
3304
3305 $users = [];
3306 foreach ($query->exec() as $relation)
3307 {
3308 $users[] = \Bitrix\Im\User::getInstance($relation['USER_ID'])->getFullName(false);
3309 }
3310
3311 $index->setUserList($users);
3312 }
3313
3314 public static function getNextConferenceDefaultTitle()
3315 {
3316 $counter = CGlobalCounter::GetValue('im_videoconf_count', CGlobalCounter::ALL_SITES) + 1;
3317
3318 return GetMessage('IM_VIDEOCONF_NAME_FORMAT_NEW', [
3319 '#NUMBER#' => $counter
3320 ]);
3321 }
3322
3323 public static function isNewChat(string $type, ?DateTime $dateCreate): bool
3324 {
3325 if ($type !== Chat::IM_TYPE_OPEN_CHANNEL || $dateCreate === null)
3326 {
3327 return false;
3328 }
3329
3330 $lastDay = (new DateTime())->add('-1 day');
3331
3332 return $dateCreate->getTimestamp() > $lastDay->getTimestamp();
3333 }
3334
3335 public static function canDo(array $chatData, array $relations, IM\V2\Permission\Action $action, mixed $target = null): bool
3336 {
3337 $chatData['RELATIONS'] = new IM\V2\RelationCollection($relations);
3338
3339 return self::initChatByArray($chatData)->canDo($action, $target);
3340 }
3341
3342 public static function initChatByArray(array $chatData): Chat
3343 {
3344 $preparedChatData = $chatData;
3345 $preparedChatData['ID'] = $chatData['ID'] ?? $chatData['CHAT_ID'] ?? $chatData['ITEM_CID'] ?? null;
3346 $preparedChatData['TYPE'] = $chatData['TYPE'] ?? $chatData['CHAT_TYPE'] ?? null;
3347 $preparedChatData['ENTITY_TYPE'] = $chatData['ENTITY_TYPE'] ?? $chatData['CHAT_ENTITY_TYPE'] ?? null;
3348 $preparedChatData['ENTITY_ID'] = $chatData['ENTITY_ID'] ?? $chatData['CHAT_ENTITY_ID'] ?? null;
3349 $preparedChatData['ENTITY_DATA_1'] = $chatData['ENTITY_DATA_1'] ?? $chatData['CHAT_ENTITY_DATA_1'] ?? null;
3350 $preparedChatData['ENTITY_DATA_2'] = $chatData['ENTITY_DATA_2'] ?? $chatData['CHAT_ENTITY_DATA_2'] ?? null;
3351 $preparedChatData['ENTITY_DATA_3'] = $chatData['ENTITY_DATA_3'] ?? $chatData['CHAT_ENTITY_DATA_3'] ?? null;
3352 $preparedChatData['DATE_CREATE'] = $chatData['DATE_CREATE'] ?? $chatData['CHAT_DATE_CREATE'] ?? null;
3353
3354 return Chat\ChatFactory::getInstance()->initChat($preparedChatData);
3355 }
3356
3357 public static function getGroupTypes(): array
3358 {
3359 return [
3360 Chat::IM_TYPE_OPEN,
3361 Chat::IM_TYPE_CHAT,
3362 Chat::IM_TYPE_OPEN_LINE,
3363 Chat::IM_TYPE_COPILOT,
3364 Chat::IM_TYPE_CHANNEL,
3365 Chat::IM_TYPE_OPEN_CHANNEL,
3366 Chat::IM_TYPE_COLLAB,
3367 Chat::IM_TYPE_EXTERNAL,
3368 Chat::IM_TYPE_AI_ASSISTANT,
3369 Chat::IM_TYPE_AI_ASSISTANT_ENTITY,
3370 ];
3371 }
3372
3373 public static function getGroupTypesExtra(): array
3374 {
3375 $types = self::getGroupTypes();
3376 $types[] = Chat::IM_TYPE_COMMENT;
3377
3378 return $types;
3379 }
3380
3381 public static function implodeTypesForQuery(array $types): string
3382 {
3383 return "'" . implode("','", $types) . "'";
3384 }
3385}
$arParams
Определения access_dialog.php:21
$path
Определения access_edit.php:21
$connection
Определения actionsdefinitions.php:38
$count
Определения admin_tab.php:4
$type
Определения options.php:106
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
Определения callback_ismscenter.php:26
$arResult
Определения generate_coupon.php:16
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getPublicLink($type, $alias)
Определения alias.php:226
static getType($chatData, bool $camelCase=true)
Определения chat.php:45
static filterRelationsByAccess(int $chatId, array $relations)
Определения chat.php:1392
static getRelation($chatId, $params=[])
Определения chat.php:93
static getColorByNumber($number)
Определения color.php:144
static getName($code)
Определения color.php:135
static isSafeColor($code)
Определения color.php:186
static getColor($code)
Определения color.php:121
static toJson($array, $camelCase=true)
Определения common.php:89
static getPullExtra()
Определения common.php:127
static add($chatId, $userId)
Определения norelationpermission.php:14
static create()
Определения chatindex.php:20
static indexRecord(ChatIndex $chatIndex)
Определения chat.php:301
static updateIndexRecord(ChatIndex $index)
Определения chat.php:341
static addIndexRecord(ChatIndex $index)
Определения chat.php:323
static isUnread(int $userId, string $itemType, string $dialogId)
Определения recent.php:1819
static parse($text, $params=Array())
Определения text.php:28
static parseLegacyFormat($text, $params=Array())
Определения text.php:94
static decodeEmoji($text)
Определения text.php:378
static formatFullNameFromDatabase($fields)
Определения user.php:1243
static getInstance($userId=null)
Определения user.php:45
static getInstance()
Определения ChatFactory.php:37
const GENERAL_MESSAGE_TYPE_JOIN
Определения GeneralChat.php:23
static getGeneralChatId()
Определения GeneralChat.php:123
const GENERAL_MESSAGE_TYPE_LEAVE
Определения GeneralChat.php:24
static linkGeneralChat(?int $chatId=null)
Определения GeneralChat.php:297
static unlinkGeneralChat()
Определения GeneralChat.php:333
static sendSharedPull(array $pull)
Определения OpenChannelChat.php:124
static create(array $fields)
Определения UpdateFields.php:31
const ADD_EVENT
Определения Event.php:12
const CHAT_ENTITY
Определения Event.php:14
static getInstance()
Определения Logger.php:37
static getInstance()
Определения application.php:98
static getConnection($name="")
Определения application.php:638
static includeModule($moduleName)
Определения loader.php:67
static isModuleInstalled($moduleName)
Определения modulemanager.php:125
static cleanCache()
Определения datamanager.php:1983
static filter()
Определения query.php:906
getTimestamp()
Определения date.php:218
static createFromTimestamp($timestamp)
Определения datetime.php:246
static add($recipient, array $parameters, $channelType=\CPullChannel::TYPE_PRIVATE)
Определения event.php:22
static urlAddParams($url, $add_params, $options=[])
Определения http.php:521
Определения im_chat.php:15
SetDescription($chatId, $description)
Определения im_chat.php:2117
static GetAvatarImage($id, $size=200, $addBlankPicture=true)
Определения im_chat.php:2826
JoinParent($chatId, $messageId)
Определения im_chat.php:2675
static CanSendMessageToGeneralChat($userId=null)
Определения im_chat.php:901
Rename($chatId, $title, $checkPermission=true, $sendMessage=true)
Определения im_chat.php:2384
static AddMessage($arFields)
Определения im_chat.php:2634
$lastAvatarId
Определения im_chat.php:22
static CanJoinGeneralChatId($userId)
Определения im_chat.php:969
SetOwner($chatId, $userId, $checkPermission=true)
Определения im_chat.php:2061
GetUnreadMessage($arParams=Array())
Определения im_chat.php:1780
static implodeTypesForQuery(array $types)
Определения im_chat.php:3381
GetLastMessage($toChatId, $fromUserId=false, $loadExtraData=false, $bTimeZone=true, $limit=true)
Определения im_chat.php:93
static GetOpenChatData($arParams=Array())
Определения im_chat.php:1414
SetUnReadMessage($chatId, $lastId)
Определения im_chat.php:1671
static getGroupTypesExtra()
Определения im_chat.php:3373
static getGroupTypes()
Определения im_chat.php:3357
GetLastSendMessage($arParams)
Определения im_chat.php:629
static UnlinkGeneralChatId()
Определения im_chat.php:992
Join($chatId)
Определения im_chat.php:2641
DeleteUser( $chatId, $userId, $checkPermission=true, $skipMessage=false, $skipRecent=false, $withoutRead=false, $additionalParams=[])
Определения im_chat.php:2757
static addChatIndex(int $chatId, string $chatTitle)
Определения im_chat.php:3269
__construct($user_id=null, $arParams=Array())
Определения im_chat.php:25
GetLastMessageLimit($chatId, $messageStartId, $messageEndId=0, $loadExtraData=false, $bTimeZone=true, $order='DESC')
Определения im_chat.php:497
static GetCrmChatId($code)
Определения im_chat.php:3100
static linkGeneralChatId($chatId)
Определения im_chat.php:984
const GENERAL_MESSAGE_TYPE_JOIN
Определения im_chat.php:17
static canDo(array $chatData, array $relations, IM\V2\Permission\Action $action, mixed $target=null)
Определения im_chat.php:3335
static fillChatIndexWithUserFullNames(\Bitrix\Im\Internals\ChatIndex $index)
Определения im_chat.php:3296
static InstallGeneralChat($agentMode=false)
Определения im_chat.php:885
GetMessage($ID)
Определения im_chat.php:46
SetManager($chatId, $userId, $isManager=true, $checkPermission=true)
Определения im_chat.php:2195
static updateChatIndex($chatId)
Определения im_chat.php:3283
Add($arParams)
Определения im_chat.php:2560
static getChatType($chatData)
Определения im_chat.php:624
static GetGeneralChatId()
Определения im_chat.php:877
const CHAT_ALL
Определения im_chat.php:16
static getNextConferenceDefaultTitle()
Определения im_chat.php:3314
static hide($chatId)
Определения im_chat.php:3216
static GetPrivateRelation($fromUserId, $toUserId)
Определения im_chat.php:847
static SetAccessToGeneralChat($allowAll=true, $allowCodes=Array())
Определения im_chat.php:922
AddUser($chatId, $userId, $hideHistory=null, $skipMessage=false, $skipRecent=false, $skipRelation=false)
Определения im_chat.php:2709
SetReadMessage($chatId, $lastId=null, $byEvent=false)
Определения im_chat.php:1527
static GetRelationById($ID, $userId=false, $timezone=true, $withCounter=true, bool $raw=false)
Определения im_chat.php:745
static GetChatOptions()
Определения im_chat.php:2936
static DeleteEntityChat($entityType, $entityId)
Определения im_chat.php:3161
const GENERAL_MESSAGE_TYPE_LEAVE
Определения im_chat.php:18
SetAvatarId($chatId, $fileId)
Определения im_chat.php:2326
static index($chatId)
Определения im_chat.php:3256
static SetChatParams($chatId, $params)
Определения im_chat.php:2152
static isNewChat(string $type, ?DateTime $dateCreate)
Определения im_chat.php:3323
static deleteChat(array $chatData)
Определения im_chat.php:3188
SetManagers($chatId, $users, $checkPermission=true)
Определения im_chat.php:2200
static CheckRestriction($chatId, $action)
Определения im_chat.php:2903
static initChatByArray(array $chatData)
Определения im_chat.php:3342
SetColor($chatId, $color)
Определения im_chat.php:2224
GetPersonalChat(?int $userId=null)
Определения im_chat.php:816
static AddSystemMessage($params)
Определения im_chat.php:2849
static GetGeneralChatAutoMessageStatus($type)
Определения im_chat.php:893
static AddGeneralMessage($arFields)
Определения im_chat.php:997
MuteNotify($chatId, $mute=true)
Определения im_chat.php:2752
static GetSonetGroupChatId($groupId)
Определения im_chat.php:3077
static GetUserCount($chatId)
Определения im_chat.php:3118
static GetEntityChat($entityType, $entityId)
Определения im_chat.php:3135
static GetChatData($arParams=Array())
Определения im_chat.php:1006
static GetFiles($chatId, $fileId=false, $checkPermission=true)
Определения im_disk.php:1601
Определения im_message.php:14
static SetLastSendId($chatId, $userId, $lastSendId)
Определения im_message.php:1199
static SetLastIdForUnread($chatId, $userId, $lastId)
Определения im_message.php:1156
static Add($arFields)
Определения im_message.php:28
static SetLastId($chatId, $userId, $lastId=null)
Определения im_message.php:986
Определения user.php:6037
if(!\Bitrix\Main\Loader::includeModule('clouds')) $lastId
Определения sync.php:68
$options
Определения commerceml2.php:49
$arFields
Определения dblapprove.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
if($ajaxMode) $ID
Определения get_user.php:27
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
const IM_MESSAGE_CHAT
Определения include.php:23
const IM_MESSAGE_OPEN
Определения include.php:24
const IM_SPEED_GROUP
Определения include.php:67
const IM_MESSAGE_PRIVATE
Определения include.php:22
const IM_MESSAGE_OPEN_LINE
Определения include.php:26
global $DB
Определения cron_frame.php:29
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
const BX_RESIZE_IMAGE_EXACT
Определения constants.php:12
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
Определения contextmenu.php:9
Определения chatindex.php:3
Определения alias.php:2
Определения ChatsSync.php:3
Определения ActionUuid.php:3
Определения base32.php:2
$user
Определения mysql_to_pgsql.php:33
$files
Определения mysql_to_pgsql.php:30
$GLOBALS['____1690880296']
Определения license.php:1
$order
Определения payment.php:8
$entityId
Определения payment.php:4
$message
Определения payment.php:8
$arFiles
Определения options.php:60
$counter
Определения options.php:5
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$config
Определения quickway.php:69
if(empty($signedUserToken)) $key
Определения quickway.php:257
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$messages
Определения template.php:8
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$title
Определения pdf.php:123
$val
Определения options.php:1793
$counters
Определения options.php:100
$arRes
Определения options.php:104
const SITE_ID
Определения sonet_set_content_view.php:12
$action
Определения file_dialog.php:21
$arFilter
Определения user_search.php:106
$url
Определения iframe.php:7
$dbRes
Определения yandex_detail.php:168
$fields
Определения yandex_run.php:501