3namespace Bitrix\Im\V2\Message;
5use Bitrix\Im\Model\ChatTable;
6use Bitrix\Im\Model\MessageUnreadTable;
7use Bitrix\Im\Model\MessageViewedTable;
8use Bitrix\Im\Model\RelationTable;
11use Bitrix\Im\V2\Common\ContextCustomer;
12use Bitrix\Im\V2\Message;
13use Bitrix\Im\V2\MessageCollection;
14use Bitrix\Im\V2\Relation;
15use Bitrix\Im\V2\RelationCollection;
16use Bitrix\Im\V2\Result;
17use Bitrix\Im\V2\Service\Context;
19use Bitrix\Main\Application;
20use Bitrix\Main\DB\SqlExpression;
32 private static array $lastMessageIdCache = [];
44 $this->counterService->setContext(
$context);
45 $this->viewedService->setContext(
$context);
52 $this->counterService->deleteTo(
$message);
54 $viewResult = $this->viewedService->addTo(
$message);
55 $this->updateDateRecent(
$message->getChatId());
58 $this->getContext()->getUserId(),
63 if ($viewResult->isSuccess())
65 $viewedMessages = $viewResult->getResult()[
'VIEWED_MESSAGES'] ?? [];
68 return (
new Result())->setResult([
'COUNTER' =>
$counter,
'VIEWED_MESSAGES' => $viewedMessages]);
75 $this->counterService->deleteTo(
$messages[$maxId]);
76 $counter = $this->counterService->getByChat($chat->getChatId());
78 ->withContextUser($this->getContext()->getUserId())
82 $this->viewedService->add($messagesToView);
83 $this->updateDateRecent($chat->getChatId());
85 new Sync\
Event(
Sync\Event::ADD_EVENT,
Sync\Event::CHAT_ENTITY, $chat->getChatId()),
86 $this->getContext()->getUserId(),
90 return (
new Result())->setResult([
'COUNTER' =>
$counter,
'VIEWED_MESSAGES' => $messagesToView]);
102 $chatIds = array_keys($chatIds);
104 $this->counterService->deleteByMessagesForAll(
$messages, $userByChatId);
105 $counters = $this->counterService->getForNotifyChats($chatIds);
106 $time = microtime(
true);
125 $this->counterService->deleteByChatId($chatId);
128 $this->updateDateRecent($chatId);
132 $this->getContext()->getUserId(),
138 $userId = $this->getContext()->getUserId();
147 $childrenToRead = CounterService::getChildrenWithCounters($parentChat, $this->getContext()->getUserId());
149 if (empty($childrenToRead))
151 return $childrenToRead;
154 $this->setLastIdForReadByIds($childrenToRead);
155 $this->counterService->deleteByChatIds($childrenToRead);
157 return $childrenToRead;
162 $this->setLastIdForReadAll();
163 $this->counterService->deleteAll();
166 $this->getContext()->getUserId()
173 $relation =
$message->getChat()->withContext($this->context)->getSelfRelation();
174 if ($relation ===
null)
178 $this->counterService->addStartingFrom(
$message->getMessageId(), $relation);
179 $this->viewedService->deleteStartingFrom(
$message);
182 $this->getContext()->getUserId(),
191 $this->counterService->addCollection(
$messages, $relation);
192 $counter = $this->counterService->getByChatWithOverflow($relation->getChatId());
206 $this->counterService->addForEachUser(
$message, $relations);
219 $this->counterService->addForEachUser(
$message, $relations);
220 $this->counterService->deleteTo(
$message);
232 $chat =
$message->getChat()->withContext($this->context);
233 Recent::unread($chat->getDialogId(),
false, $this->getContext()->getUserId(),
null, $chat->getType());
246 return $this->counterService->getByChatForEachUsers(
$message->getChatId(), $relations->
getUserIds(), 100);
258 if (!$withoutCounters)
265 ->getCountersForUsers(
$message, $relations)
273 $this->counterService->deleteByMessageForAll(
$message, $invalidateCacheUsers);
274 $this->viewedService->deleteByMessageIdForAll(
$message->getMessageId());
279 $this->counterService->deleteByMessagesForAll(
$messages, $invalidateCacheUsers);
280 $this->viewedService->deleteByMessagesIdsForAll(
$messages->getIds());
285 $this->counterService->deleteByChatId($chatId);
286 $this->viewedService->deleteByChatId($chatId);
297 if (empty($messageIds))
302 $query = MessageUnreadTable::query()
303 ->setSelect([
'MESSAGE_ID'])
304 ->whereIn(
'MESSAGE_ID', $messageIds)
305 ->where(
'USER_ID', $this->getContext()->getUserId())
309 $unreadMessages = [];
311 while ($row =
$query->fetch())
313 $unreadMessages[(int)$row[
'MESSAGE_ID']] =
false;
323 return $readStatuses;
328 if (empty($messageIds))
333 $query = MessageViewedTable::query()
334 ->setSelect([
'MESSAGE_ID'])
335 ->whereIn(
'MESSAGE_ID', $messageIds)
336 ->where(
'USER_ID', $this->getContext()->getUserId())
340 $viewedMessages = [];
342 while ($row =
$query->fetch())
344 $viewedMessages[(int)$row[
'MESSAGE_ID']] =
true;
354 return $viewStatuses;
359 $relation = RelationTable::query()
360 ->setSelect([
'LAST_ID'])
361 ->where(
'USER_ID', $this->getContext()->getUserId())
362 ->where(
'CHAT_ID', $chatId)->setLimit(1)
367 return $relation[
'LAST_ID'] ?? 0;
375 if (isset(static::$lastMessageIdCache[$chatId]))
377 return static::$lastMessageIdCache[$chatId];
380 $result = ChatTable::query()->setSelect([
'LAST_MESSAGE_ID'])->where(
'ID', $chatId)->fetch();
389 $lastMessageId = (int)(
$result[
'LAST_MESSAGE_ID'] ?? 0);
392 static::$lastMessageIdCache[$chatId] = $lastMessageId;
394 return $lastMessageId;
401 if ($lastMessageId === 0)
403 return \IM_MESSAGE_STATUS_RECEIVED;
406 return $this->viewedService->getMessageStatus($lastMessageId);
424 SET LAST_ID=(CASE WHEN LAST_ID > {$lastId} THEN LAST_ID ELSE {$lastId} END)
425 WHERE CHAT_ID={$chatId} AND USER_ID={$this->getContext()->getUserId()}
428 Application::getConnection()->queryExecute($sql);
440 private function getChildrenToReadIds(
Chat $parentChat):
array
442 $parentId = $parentChat->getId();
448 $query = ChatTable::query()
450 ->where(
'PARENT_ID', $parentId)
454 $subQuery = MessageUnreadTable::query()
455 ->setSelect([
'CHAT_ID'])
456 ->where(
'USER_ID', $this->getContext()->getUserId())
461 ->whereIn(
'ID', $subQuery)
467 private function setLastIdForReadAll(): void
472 $connection->queryExecute($helper->prepareCorrelatedUpdate(
476 'LAST_ID' =>
'C.LAST_MESSAGE_ID',
480 AND R.USER_ID = {$this->getContext()->getUserId()}"
484 private function setLastIdForReadByIds(
array $chatIds): void
491 $chatIdsString = implode(
',', $chatIds);
495 $connection->queryExecute($helper->prepareCorrelatedUpdate(
499 'LAST_ID' =>
'C.LAST_MESSAGE_ID',
502 " C.ID = R.CHAT_ID AND R.CHAT_ID IN ({$chatIdsString}) AND R.USER_ID = {$this->getContext()->getUserId()}"
506 private function updateDateRecent(
int $chatId): void
509 \Bitrix\Main\Application::getConnection()->query(
510 "UPDATE b_im_recent SET DATE_UPDATE = NOW() WHERE USER_ID = {$userId} AND ITEM_CID = {$chatId}"
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static unread($dialogId, $unread, $userId=null, ?int $markedId=null, ?string $itemTypes=null)
__construct(?int $userId=null)
deleteByChatId(int $chatId)
ViewedService $viewedService
getReadStatusesByMessageIds(array $messageIds)
deleteByMessages(MessageCollection $messages, ?array $invalidateCacheUsers=null)
read(MessageCollection $messages, Chat $chat)
getViewStatusesByMessageIds(array $messageIds)
CounterService $counterService
readChildren(Chat $parentChat)
readNotifications(MessageCollection $messages, array $userByChatId)
unreadNotifications(MessageCollection $messages, Relation $relation)
readAllInChat(int $chatId)
getChatMessageStatus(int $chatId)
setLastIdForRead(int $lastId, int $chatId)
onAfterMessageSend(Message $message, RelationCollection $relations, bool $withoutCounters=false)
getCountersForUsers(Message $message, RelationCollection $relations)
markRecentUnread(Message $message)
getLastMessageIdInChat(int $chatId)
setContext(?Context $context)
markMessageUnread(Message $message, RelationCollection $relations)
deleteByMessage(Message $message, ?array $invalidateCacheUsers=null)
unreadTo(Message $message)
getLastIdByChatId(int $chatId)
markNotificationUnread(Message $message, RelationCollection $relations)
static getConnection($name="")
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
const IM_MESSAGE_OPEN_LINE