11use Bitrix\Im\V2\Common\ContextCustomer;
33 private static array $lastMessageIdCache = [];
43 $context->setUser($userId);
45 $this->counterService->setContext($context);
46 $this->viewedService->setContext($context);
53 $this->counterService->deleteTo($message);
54 $counter = $this->counterService->getByChat($message->
getChatId());
55 $viewResult = $this->viewedService->addTo($message);
56 $this->updateDateRecent($message->
getChatId());
59 Sync\Logger::getInstance()->add(
60 new Sync\
Event(Sync\Event::ADD_EVENT, Sync\Event::CHAT_ENTITY, $message->
getChatId()),
61 $this->getContext()->getUserId()
66 if ($viewResult->isSuccess())
68 $viewedMessages = $viewResult->getResult()[
'VIEWED_MESSAGES'] ?? [];
71 return (
new Result())->setResult([
'COUNTER' => $counter,
'VIEWED_MESSAGES' => $viewedMessages]);
76 $maxId = max($messages->
getIds());
78 $this->counterService->deleteTo($messages[$maxId]);
79 $counter = $this->counterService->getByChat($chat->getChatId());
80 $messagesToView = $messages
81 ->withContextUser($this->getContext()->getUserId())
85 $this->viewedService->add($messagesToView);
86 $this->updateDateRecent($chat->getChatId());
89 Sync\Logger::getInstance()->add(
90 new Sync\
Event(Sync\Event::ADD_EVENT, Sync\Event::CHAT_ENTITY, $chat->getChatId()),
91 $this->getContext()->getUserId()
95 return (
new Result())->setResult([
'COUNTER' => $counter,
'VIEWED_MESSAGES' => $messagesToView]);
102 foreach ($messages as $message)
104 $chatIds[$message->getChatId()] = 0;
107 $chatIds = array_keys($chatIds);
109 $this->counterService->deleteByMessageIdsForAll($messages->
getIds(), $userByChatId);
110 $counters = $this->counterService->getForNotifyChats($chatIds);
111 $time = microtime(
true);
123 return (
new Result())->setResult([
'COUNTERS' => $counters]);
130 $this->counterService->deleteByChatId($chatId);
133 $this->updateDateRecent($chatId);
136 Sync\Logger::getInstance()->add(
137 new Sync\
Event(Sync\Event::ADD_EVENT, Sync\Event::CHAT_ENTITY, $chatId),
138 $this->getContext()->getUserId()
147 $this->setLastIdForReadAll();
148 $this->counterService->deleteAll();
149 Sync\Logger::getInstance()->add(
150 new Sync\
Event(Sync\Event::READ_ALL_EVENT, Sync\Event::CHAT_ENTITY, 0),
151 $this->getContext()->getUserId()
158 $relation = $message->
getChat()->withContext($this->context)->getSelfRelation();
159 if ($relation ===
null)
163 $this->counterService->addStartingFrom($message->
getMessageId(), $relation);
164 $this->viewedService->deleteStartingFrom($message);
167 Sync\Logger::getInstance()->add(
168 new Sync\
Event(Sync\Event::ADD_EVENT, Sync\Event::CHAT_ENTITY, $message->
getChatId()),
169 $this->getContext()->getUserId()
178 $this->counterService->addCollection($messages, $relation);
179 $counter = $this->counterService->getByChat($relation->
getChatId());
193 $this->counterService->addForEachUser($message, $relations);
206 $this->counterService->addForEachUser($message, $relations);
207 $this->counterService->deleteTo($message);
219 Recent::unread($message->
getChat()->withContext($this->context)->getDialogId(),
false, $this->getContext()->getUserId());
232 return $this->counterService->getByChatForEachUsers($message->
getChatId(), $relations->
getUserIds());
244 if (!$withoutCounters)
250 ->markRecentUnread($message)
251 ->getCountersForUsers($message, $relations)
254 return (
new Result())->setResult([
'COUNTERS' => $counters]);
260 $relationCollection->add($relation);
261 $this->counterService->addForEachUser($message, $relationCollection);
262 $counter = $this->counterService->getByChat($relation->
getChatId());
264 return (
new Result())->setResult([
'COUNTER' => $counter]);
269 $this->counterService->deleteByMessageIdForAll($messageId, $invalidateCacheUsers);
270 $this->viewedService->deleteByMessageIdForAll($messageId);
275 $this->counterService->deleteByChatId($chatId);
276 $this->viewedService->deleteByChatId($chatId);
287 if (empty($messageIds))
293 ->setSelect([
'MESSAGE_ID'])
294 ->whereIn(
'MESSAGE_ID', $messageIds)
295 ->where(
'USER_ID', $this->getContext()->getUserId())
299 $unreadMessages = [];
301 while ($row = $query->fetch())
303 $unreadMessages[(int)$row[
'MESSAGE_ID']] =
false;
308 foreach ($messageIds as $messageId)
310 $readStatuses[$messageId] = $unreadMessages[$messageId] ??
true;
313 return $readStatuses;
318 if (empty($messageIds))
323 $query = MessageViewedTable::query()
324 ->setSelect([
'MESSAGE_ID'])
325 ->whereIn(
'MESSAGE_ID', $messageIds)
326 ->where(
'USER_ID', $this->getContext()->getUserId())
330 $viewedMessages = [];
332 while ($row = $query->fetch())
334 $viewedMessages[(int)$row[
'MESSAGE_ID']] =
true;
339 foreach ($messageIds as $messageId)
341 $viewStatuses[$messageId] = $viewedMessages[$messageId] ??
false;
344 return $viewStatuses;
349 $relation = RelationTable::query()
350 ->setSelect([
'LAST_ID'])
351 ->where(
'USER_ID', $this->getContext()->getUserId())
352 ->where(
'CHAT_ID', $chatId)->setLimit(1)
357 return $relation[
'LAST_ID'] ?? 0;
365 if (isset(static::$lastMessageIdCache[$chatId]))
367 return static::$lastMessageIdCache[$chatId];
370 $result = ChatTable::query()->setSelect([
'LAST_MESSAGE_ID'])->where(
'ID', $chatId)->fetch();
379 $lastMessageId = (int)($result[
'LAST_MESSAGE_ID'] ?? 0);
382 static::$lastMessageIdCache[$chatId] = $lastMessageId;
384 return $lastMessageId;
391 if ($lastMessageId === 0)
393 return \IM_MESSAGE_STATUS_RECEIVED;
396 return $this->viewedService->getMessageStatus($lastMessageId);
414 SET LAST_ID=(CASE WHEN LAST_ID > {$lastId} THEN LAST_ID ELSE {$lastId} END)
415 WHERE CHAT_ID={$chatId} AND USER_ID={$this->getContext()->getUserId()}
423 $this->defaultSetContext($context);
430 private function setLastIdForReadAll(): void
433 $helper = $connection->getSqlHelper();
435 $connection->queryExecute($helper->prepareCorrelatedUpdate(
439 'LAST_ID' =>
'C.LAST_MESSAGE_ID',
442 " C.ID = R.CHAT_ID AND R.MESSAGE_TYPE NOT IN ('" . IM_MESSAGE_OPEN_LINE .
"', '" . IM_MESSAGE_SYSTEM .
"')
443 AND R.USER_ID = {$this->getContext()->getUserId()}"
447 private function updateDateRecent(
int $chatId): void
449 $userId = $this->getContext()->getUserId();
450 \Bitrix\Main\Application::getConnection()->query(
451 "UPDATE b_im_recent SET DATE_UPDATE = NOW() WHERE USER_ID = {$userId} AND ITEM_CID = {$chatId}"
static unread($dialogId, $unread, $userId=null, ?int $markedId=null)
__construct(?int $userId=null)
deleteByChatId(int $chatId)
ViewedService $viewedService
getReadStatusesByMessageIds(array $messageIds)
read(MessageCollection $messages, Chat $chat)
getViewStatusesByMessageIds(array $messageIds)
CounterService $counterService
readNotifications(MessageCollection $messages, array $userByChatId)
unreadNotifications(MessageCollection $messages, Relation $relation)
readAllInChat(int $chatId)
getChatMessageStatus(int $chatId)
onAfterNotificationSend(Message $message, Relation $relation)
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)
deleteByMessageId(int $messageId, ?array $invalidateCacheUsers=null)
unreadTo(Message $message)
getLastIdByChatId(int $chatId)
markNotificationUnread(Message $message, RelationCollection $relations)
static getConnection($name="")