5use Bitrix\Im\Model\EO_MessageUnread;
6use Bitrix\Im\Model\EO_MessageUnread_Collection;
12use Bitrix\Im\V2\Common\ContextCustomer;
61 $this->counters = static::DEFAULT_COUNTERS;
66 $context->setUser($userId);
67 $this->setContext($context);
76 return $totalUnreadMessages + count($unreadUnmutedChats);
84 foreach ($countForEachUsers as $countForUser)
86 $result[(int)$countForUser[
'USER_ID']] = (
int)$countForUser[
'COUNT'];
89 if ($userIds ===
null)
94 foreach ($userIds as $userId)
96 if (!isset($result[$userId]))
110 public function get(): array
112 $userId = $this->getContext()->getUserId();
113 if (isset(self::$staticCounterCache[$userId]))
115 return self::$staticCounterCache[$userId];
119 $cachedCounters = $cache->getVars();
120 if ($cachedCounters !==
false)
122 self::$staticCounterCache[$userId] = $cachedCounters;
124 return $cachedCounters;
127 $this->counters = static::DEFAULT_COUNTERS;
128 $this->countersByChatIds = [];
141 $userId = $this->getContext()->getUserId();
142 if (isset(self::$staticChatsCounterCache[$userId]))
144 return self::$staticChatsCounterCache[$userId];
149 return static::$staticSpecificChatsCounterCache[$userId] ?? [];
153 $cachedCounters = $cache->getVars();
154 if ($cachedCounters !==
false)
156 self::$staticChatsCounterCache[$userId] = $cachedCounters;
158 return $cachedCounters;
161 $this->counters = static::DEFAULT_COUNTERS;
162 $this->countersByChatIds = [];
166 if ($chatIds ===
null)
180 $findResult = NotifyChat::find([
'TO_USER_ID' => $this->getContext()->getUserId()]);
182 if (!$findResult->isSuccess())
187 $chatId = (int)$findResult->getResult()[
'ID'];
200 $countersByChatId = [];
204 $countersByChatId[$counter[
'CHAT_ID']] = $counter[
'COUNT'];
209 foreach ($chatIds as $chatId)
211 $result[$chatId] = $countersByChatId[$chatId] ?? 0;
221 ->where(
'CHAT_ID', $chatId)
222 ->where(
'USER_ID', $this->getContext()->getUserId())
223 ->registerRuntimeField(
'MIN',
new ExpressionField(
'MIN',
'MIN(%s)', [
'MESSAGE_ID']))
227 return isset($result[
'MIN']) ? (int)$result[
'MIN'] :
null;
238 ->setSelect([
'CHAT_ID',
'UNREAD_ID' =>
new ExpressionField(
'UNREAD_ID',
'MIN(%s)', [
'MESSAGE_ID'])])
239 ->whereIn(
'CHAT_ID', $chatIds)
240 ->where(
'USER_ID', $this->getContext()->getUserId())
241 ->setGroup([
'CHAT_ID'])
247 foreach ($result as $row)
249 $firstUnread[(int)$row[
'CHAT_ID']] = (
int)$row[
'UNREAD_ID'];
258 [
'IS_MUTED' => $isMuted],
259 [
'=CHAT_ID' => $chatId,
'=USER_ID' => $this->getContext()->getUserId()]
261 static::clearCache($this->getContext()->getUserId());
266 MessageUnreadTable::deleteByFilter([
'=CHAT_ID' => $chatId,
'=USER_ID' => $this->getContext()->getUserId()]);
267 static::clearCache($this->getContext()->getUserId());
276 public function deleteAll(
bool $withNotify =
false): void
278 $filter = [
'=USER_ID' => $this->getContext()->getUserId()];
282 $filter[
'!=CHAT_TYPE'] = \IM_MESSAGE_SYSTEM;
285 MessageUnreadTable::deleteByFilter($filter);
286 static::clearCache($this->getContext()->getUserId());
294 foreach ($relations as $relation)
296 if ($relation->getMessageType() !== \IM_MESSAGE_SYSTEM && $message->
getAuthorId() === $relation->getUserId())
301 $insertFields[] = $this->prepareInsertFields($message, $relation);
302 $usersIds[] = $relation->getUserId();
305 MessageUnreadTable::multiplyInsertWithoutDuplicate($insertFields);
306 foreach ($usersIds as $userId)
308 static::clearCache($userId);
316 foreach ($messages as $message)
323 $insertFields[] = $this->prepareInsertFields($message, $relation);
326 MessageUnreadTable::multiplyInsertWithoutDuplicate($insertFields);
327 static::clearCache($relation->
getUserId());
332 $query = MessageTable::query()
335 'USER_ID_CONST' =>
new ExpressionField(
'USER_ID_CONST', (
string)$this->getContext()->getUserId()),
337 'MESSAGE_ID' =>
'ID',
339 'CHAT_TYPE' =>
new ExpressionField(
'CHAT_TYPE',
"'{$relation->getMessageType()}'"),
342 ->where(
'CHAT_ID', $relation->
getChatId())
343 ->where(
'MESSAGE_ID',
'>=', $messageId)
347 $query->whereNot(
'AUTHOR_ID', $this->getContext()->getUserId());
350 MessageUnreadTable::insertSelect($query, [
'ID',
'USER_ID',
'CHAT_ID',
'MESSAGE_ID',
'IS_MUTED',
'CHAT_TYPE',
'DATE_CREATE']);
352 static::clearCache($this->getContext()->getUserId());
357 if (empty($messageId))
362 MessageUnreadTable::deleteByFilter([
'=MESSAGE_ID' => $messageId]);
364 if (!isset($invalidateCacheUsers))
366 static::clearCache();
371 foreach ($invalidateCacheUsers as $user)
373 static::clearCache((
int)$user);
379 MessageUnreadTable::deleteByFilter([
'=MESSAGE_ID' => $messageIds]);
381 if (!isset($invalidateCacheUsers))
383 static::clearCache();
388 foreach ($invalidateCacheUsers as $user)
390 static::clearCache((
int)$user);
396 $userId = $this->getContext()->getUserId();
397 MessageUnreadTable::deleteByFilter([
'<=MESSAGE_ID' => $message->
getMessageId(),
'=CHAT_ID' => $message->
getChatId(),
'=USER_ID' => $userId]);
398 static::clearCache($userId);
403 if (!isset($fields[
'ACTIVE']))
408 if ($fields[
'ACTIVE'] ===
'N')
421 if ($user->isExist() && $user->isActive())
426 $counterService =
new self($userId);
427 $counterService->deleteAll(
true);
434 $dateExpired = (
new DateTime())->add(self::EXPIRY_INTERVAL);
435 MessageUnreadTable::deleteByFilter([
'<=DATE_CREATE' => $dateExpired]);
436 static::clearCache();
438 return '\Bitrix\Im\V2\Message\CounterService::deleteExpiredCountersAgent();';
444 "\Bitrix\Im\V2\Message\CounterService::deleteCountersOfFiredUserAgent({$userId});",
447 self::DELAY_DELETION_COUNTERS_OF_FIRED_USER,
450 ConvertTimeStamp(time()+CTimeZone::GetOffset()+self::DELAY_DELETION_COUNTERS_OF_FIRED_USER,
"FULL")
456 \CAgent::RemoveAgent(
457 "\Bitrix\Im\V2\Message\CounterService::deleteCountersOfFiredUserAgent({$userId});",
464 $cache = \Bitrix\Main\Data\Cache::createInstance();
467 unset(self::$staticCounterCache[$userId], self::$staticChatsCounterCache[$userId], self::$staticSpecificChatsCounterCache[$userId]);
468 $cache->clean(static::CACHE_NAME.
'_'.$userId, self::CACHE_PATH);
470 $cache->clean(self::CACHE_CHATS_COUNTERS_NAME.
'_'.$userId, self::CACHE_PATH);
474 self::$staticCounterCache = [];
475 self::$staticChatsCounterCache = [];
476 self::$staticSpecificChatsCounterCache = [];
477 $cache->cleanDir(self::CACHE_PATH);
484 $userId = $this->getContext()->getUserId();
485 $cache = \Bitrix\Main\Data\Cache::createInstance();
486 $cache->initCache(static::CACHE_TTL, static::CACHE_NAME .
'_' . $userId, static::CACHE_PATH);
493 $userId = $this->getContext()->getUserId();
494 $cache = \Bitrix\Main\Data\Cache::createInstance();
495 $cache->initCache(self::CACHE_TTL, self::CACHE_CHATS_COUNTERS_NAME .
'_' . $userId, self::CACHE_PATH);
504 self::$staticCounterCache[$this->getContext()->getUserId()] =
$this->counters;
516 $userId = $this->getContext()->getUserId();
518 foreach ($chatIds as $chatId)
520 self::$staticSpecificChatsCounterCache[$userId][$chatId] = $this->countersByChatIds[$chatId] ?? 0;
528 foreach ($unreadChats as $unreadChat)
530 $this->
setUnreadChat((
int)$unreadChat[
'CHAT_ID'], $unreadChat[
'IS_MUTED'] ===
'Y');
540 $chatId = (int)$counter[
'CHAT_ID'];
541 $count = (int)$counter[
'COUNT'];
542 if ($counter[
'IS_MUTED'] ===
'Y')
546 else if ($counter[
'CHAT_TYPE'] === \IM_MESSAGE_SYSTEM)
550 else if ($counter[
'CHAT_TYPE'] === \IM_MESSAGE_OPEN_LINE)
562 $this->countersByChatIds[$chatId] = $count;
568 if (!$isMuted && !isset($this->counters[
'CHAT'][$id]))
570 $this->counters[
'TYPE'][
'ALL']++;
571 $this->counters[
'TYPE'][
'CHAT']++;
574 $this->counters[
'CHAT_UNREAD'][] = $id;
579 $this->counters[
'CHAT_MUTED'][$id] = $count;
584 $this->counters[
'TYPE'][
'ALL'] += $count;
585 $this->counters[
'TYPE'][
'NOTIFY'] += $count;
590 $this->counters[
'TYPE'][
'ALL'] += $count;
591 $this->counters[
'TYPE'][
'LINES'] += $count;
592 $this->counters[
'LINES'][$id] = $count;
597 $this->counters[
'TYPE'][
'COPILOT'] += $count;
598 $this->counters[
'COPILOT'][$id] = $count;
603 $this->counters[
'TYPE'][
'ALL'] += $count;
604 $this->counters[
'TYPE'][
'CHAT'] += $count;
605 $this->counters[
'CHAT'][$id] = $count;
610 $query = RecentTable::query()
611 ->setSelect([
'CHAT_ID' =>
'ITEM_CID',
'IS_MUTED' =>
'RELATION.NOTIFY_BLOCK'])
612 ->where(
'USER_ID', $this->getContext()->getUserId())
613 ->where(
'UNREAD',
true)
617 $query->where(
'IS_MUTED', $isMuted);
620 return $query->fetchAll();
627 ->setSelect([
'CHAT_ID',
'IS_MUTED',
'CHAT_TYPE',
'COUNT'])
628 ->setGroup([
'CHAT_ID',
'CHAT_TYPE',
'IS_MUTED'])
629 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
631 if (isset($chatIds) && !empty($chatIds))
633 $query->whereIn(
'CHAT_ID', $chatIds);
637 $query->where(
'USER_ID', $this->getContext()->getUserId());
640 return array_merge($additionalCounters, $query->fetchAll());
646 $nonAnsweredLines = [];
648 if ($forCurrentUser && empty($chatIds) && Loader::includeModule(
'imopenlines'))
650 $nonAnsweredLines = \Bitrix\ImOpenLines\Recent::getNonAnsweredLines($this->getContext()->getUserId());
653 foreach ($nonAnsweredLines as $lineId)
656 'CHAT_ID' => $lineId,
669 ->setSelect([
'COUNT'])
670 ->where(
'USER_ID', $this->getContext()->getUserId())
671 ->where(
'IS_MUTED',
false)
673 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
681 ->setSelect([
'USER_ID',
'COUNT'])
682 ->where(
'CHAT_ID', $chatId)
683 ->setGroup([
'USER_ID'])
684 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
686 if (isset($userIds) && !empty($userIds))
688 $query->whereIn(
'USER_ID', $userIds);
691 return $query->fetchAll();
697 ->setSelect([
'COUNT'])
698 ->where(
'CHAT_ID', $chatId)
699 ->where(
'USER_ID', $this->getContext()->getUserId())
700 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
701 ->fetch()[
'COUNT'] ?? 0
707 $userId = $this->getContext()->getUserId();
709 foreach ($chatIds as $chatId)
711 if ($chatId > 0 && !isset(self::$staticSpecificChatsCounterCache[$userId][$chatId]))
720 private function prepareInsertFields(
Message $message,
Relation $relation): array
static updateBatch(array $fields, array $filter)
static getInstance($userId=null)
__construct(?int $userId=null)
deleteByChatId(int $chatId)
setFromCopilot(int $id, int $count)
static onAfterUserUpdate(array $fields)
getIdFirstUnreadMessage(int $chatId)
getIdFirstUnreadMessageForEachChats(array $chatIds)
updateIsMuted(int $chatId, string $isMuted)
static deleteExpiredCountersAgent()
setUnreadChat(int $id, bool $isMuted)
getUnreadChats(?bool $isMuted=null)
getByChatForEachUsers(int $chatId, ?array $userIds=null)
savePreparedCountersInCache(Cache $cache)
setFromNotify(int $count)
getCountUnreadMessagesByChatIdForEachUsers(int $chatId, ?array $userIds=null)
saveSpecificChatsCountersInCache(array $chatIds)
saveChatsCountersInCache(Cache $cache)
const CACHE_CHATS_COUNTERS_NAME
setFromLine(int $id, int $count)
getAdditionalCounters(?array $chatIds=null, bool $forCurrentUser=true)
countUnreadMessages(?array $chatIds=null)
static onHireUser(int $userId)
addCollection(MessageCollection $messages, Relation $relation)
getForNotifyChats(array $chatIds)
setFromMutedChat(int $id, int $count)
getForEachChat(?array $chatIds=null)
static array $staticChatsCounterCache
haveInSpecificChatsCache(array $chatIds)
static array $staticSpecificChatsCounterCache
static deleteCountersOfFiredUserAgent(int $userId)
getCountUnreadMessagesByChatId(int $chatId)
static onFireUser(int $userId)
const DELAY_DELETION_COUNTERS_OF_FIRED_USER
getCountersForEachChat(?array $chatIds=null, bool $forCurrentUser=true)
static clearCache(?int $userId=null)
getCacheForPreparedCounters()
setFromChat(int $id, int $count)
getCacheForChatsCounters()
deleteAll(bool $withNotify=false)
static array $staticCounterCache
getTotalCountUnreadMessages()
deleteByMessageIdsForAll(array $messageIds, ?array $invalidateCacheUsers=null)
addForEachUser(Message $message, RelationCollection $relations)
deleteByMessageIdForAll(int $messageId, ?array $invalidateCacheUsers=null)
deleteTo(Message $message)
addStartingFrom(int $messageId, Relation $relation)
endDataCache($vars=false)
startDataCache($TTL=false, $uniqueString=false, $initDir=false, $vars=array(), $baseDir='cache')