3namespace Bitrix\Im\V2\Message;
5use Bitrix\Im\Model\ChatTable;
6use Bitrix\Im\Model\MessageTable;
7use Bitrix\Im\Model\MessageUnreadTable;
8use Bitrix\Im\Model\RecentTable;
9use Bitrix\Im\V2\Application\Features;
11use Bitrix\Im\V2\Chat\NotifyChat;
12use Bitrix\Im\V2\Common\ContextCustomer;
13use Bitrix\Im\V2\Entity\User\User;
14use Bitrix\Im\V2\Message;
15use Bitrix\Im\V2\Message\Counter\CounterOverflowService;
16use Bitrix\Im\V2\MessageCollection;
17use Bitrix\Im\V2\Relation;
18use Bitrix\Im\V2\RelationCollection;
19use Bitrix\Im\V2\Service\Context;
20use Bitrix\Main\ArgumentException;
21use Bitrix\Main\Data\Cache;
22use Bitrix\Main\Loader;
23use Bitrix\Main\ObjectPropertyException;
24use Bitrix\Main\ORM\Fields\ExpressionField;
25use Bitrix\Main\SystemException;
26use Bitrix\Main\Type\DateTime;
55 'COLLAB_UNREAD' => [],
56 'COPILOT_UNREAD' => [],
59 'CHANNEL_COMMENT' => [],
71 $this->counters = static::DEFAULT_COUNTERS;
86 return $totalUnreadMessages +
count($unreadUnmutedChats);
93 $overflowInfo = $overflowService->getOverflowInfo($userIds);
97 foreach ($countForEachUsers as $countForUser)
99 $result[(int)$countForUser[
'USER_ID']] = (
int)$countForUser[
'COUNT'];
102 $overflowService->insertOverflowed(
$result);
106 if ($overflowInfo->hasOverflow(
$userId))
126 $currentUser = $this->getContext()->getUserId();
128 $overflowInfo = $overflowService->getOverflowInfo([$currentUser]);
130 if (!empty($overflowInfo->getUsersWithoutOverflow()))
133 $overflowService->insertOverflowed([$currentUser =>
$count]);
138 return CounterOverflowService::getOverflowValue();
143 $userId = $this->getContext()->getUserId();
144 if (isset(self::$staticCounterCache[
$userId]))
146 return self::$staticCounterCache[
$userId];
150 $cachedCounters = $cache->getVars();
151 if ($cachedCounters !==
false)
153 self::$staticCounterCache[
$userId] = $cachedCounters;
155 return $cachedCounters;
158 $this->counters = static::DEFAULT_COUNTERS;
159 $this->countersByChatIds = [];
172 $userId = $this->getContext()->getUserId();
173 if (isset(self::$staticChatsCounterCache[
$userId]))
175 return self::$staticChatsCounterCache[
$userId];
180 return static::$staticSpecificChatsCounterCache[
$userId] ?? [];
184 $cachedCounters = $cache->getVars();
185 if ($cachedCounters !==
false)
187 self::$staticChatsCounterCache[
$userId] = $cachedCounters;
189 return $cachedCounters;
192 $this->counters = static::DEFAULT_COUNTERS;
193 $this->countersByChatIds = [];
197 if ($chatIds ===
null)
206 return $this->countersByChatIds;
211 $findResult = NotifyChat::find([
'TO_USER_ID' => $this->getContext()->getUserId()]);
213 if (!$findResult->isSuccess())
218 $chatId = (int)$findResult->getResult()[
'ID'];
231 $countersByChatId = [];
240 foreach ($chatIds as $chatId)
242 $result[$chatId] = $countersByChatId[$chatId] ?? 0;
250 $result = MessageUnreadTable::query()
252 ->where(
'CHAT_ID', $chatId)
253 ->where(
'USER_ID', $this->getContext()->getUserId())
254 ->registerRuntimeField(
'MIN',
new ExpressionField(
'MIN',
'MIN(%s)', [
'MESSAGE_ID']))
268 $result = MessageUnreadTable::query()
269 ->setSelect([
'CHAT_ID',
'UNREAD_ID' =>
new ExpressionField(
'UNREAD_ID',
'MIN(%s)', [
'MESSAGE_ID'])])
270 ->whereIn(
'CHAT_ID', $chatIds)
271 ->where(
'USER_ID', $this->getContext()->getUserId())
272 ->setGroup([
'CHAT_ID'])
280 $firstUnread[(int)$row[
'CHAT_ID']] = (
int)$row[
'UNREAD_ID'];
288 MessageUnreadTable::updateBatch(
289 [
'IS_MUTED' => $isMuted],
290 [
'=CHAT_ID' => $chatId,
'=USER_ID' => $this->getContext()->getUserId()]
292 static::clearCache($this->getContext()->getUserId());
297 if ($this->getContext()->getUserId() <= 0)
302 MessageUnreadTable::deleteByFilter([
'=CHAT_ID' => $chatId,
'=USER_ID' => $this->getContext()->getUserId()]);
303 static::clearCache($this->getContext()->getUserId());
309 MessageUnreadTable::deleteByFilter([
'=CHAT_ID' => $chatId]);
310 CounterOverflowService::deleteByChatIdForAll($chatId);
315 MessageUnreadTable::deleteByFilter([
'=CHAT_ID' => $chatIds]);
316 CounterOverflowService::deleteByChatIds($chatIds);
321 if (empty($chatIds) || $this->getContext()->getUserId() <= 0)
326 MessageUnreadTable::deleteByFilter([
'=CHAT_ID' => $chatIds,
'=USER_ID' => $this->getContext()->getUserId()]);
327 static::clearCache($this->getContext()->getUserId());
328 CounterOverflowService::deleteByChatIds($chatIds, $this->getContext()->getUserId());
342 public function deleteAll(
bool $withNotify =
false): void
345 $this->getContext()->getUserId(),
352 $parentId = $parentChat->getId();
358 $query = MessageUnreadTable::query()
359 ->setSelect([
'CHAT_ID'])
360 ->where(
'PARENT_ID', $parentId)
361 ->addGroup(
'CHAT_ID')
370 foreach (
$query->fetchAll() as $row)
372 $parentIds[] = isset($row[
'CHAT_ID']) ? (int)$row[
'CHAT_ID'] : 0;
383 foreach ($relations as $relation)
390 $insertFields[] = $this->prepareInsertFields(
$message, $relation);
391 $usersIds[] = $relation->getUserId();
394 MessageUnreadTable::multiplyInsertWithoutDuplicate($insertFields);
412 $insertFields[] = $this->prepareInsertFields(
$message, $relation);
415 MessageUnreadTable::multiplyInsertWithoutDuplicate($insertFields);
416 static::clearCache($relation->getUserId());
421 $query = MessageTable::query()
424 'USER_ID_CONST' =>
new ExpressionField(
'USER_ID_CONST', (
string)$this->getContext()->getUserId()),
425 'CHAT_ID_CONST' =>
new ExpressionField(
'CHAT_ID', (
string)$relation->getChatId()),
426 'MESSAGE_ID' =>
'ID',
427 'IS_MUTED' =>
new ExpressionField(
'IS_MUTED', $relation->getNotifyBlock() ?
"'Y'" :
"'N'"),
428 'CHAT_TYPE' =>
new ExpressionField(
'CHAT_TYPE',
"'{$relation->getMessageType()}'"),
431 ->where(
'CHAT_ID', $relation->getChatId())
436 $query->whereNot(
'AUTHOR_ID', $this->getContext()->getUserId());
439 MessageUnreadTable::insertSelect(
$query, [
'ID',
'USER_ID',
'CHAT_ID',
'MESSAGE_ID',
'IS_MUTED',
'CHAT_TYPE',
'DATE_CREATE']);
441 static::clearCache($this->getContext()->getUserId());
451 MessageUnreadTable::deleteByFilter([
'=MESSAGE_ID' =>
$message->getId()]);
452 CounterOverflowService::deleteByChatIdForAll(
$message->getChatId());
454 if (!isset($invalidateCacheUsers))
456 static::clearCache();
461 foreach ($invalidateCacheUsers as
$user)
463 static::clearCache((
int)
$user);
471 if (empty($messageIds))
479 $chatIds[$chatId] = $chatId;
482 MessageUnreadTable::deleteByFilter([
'=MESSAGE_ID' => $messageIds]);
483 CounterOverflowService::deleteByChatIds($chatIds);
485 if (!isset($invalidateCacheUsers))
487 static::clearCache();
492 foreach ($invalidateCacheUsers as
$user)
494 static::clearCache((
int)
$user);
500 $userId = $this->getContext()->getUserId();
506 MessageUnreadTable::deleteByFilter([
507 '<=MESSAGE_ID' =>
$message->getMessageId(),
508 '=CHAT_ID' =>
$message->getChatId(),
524 self::onFireUser((
int)
$fields[
'ID']);
528 self::onHireUser((
int)
$fields[
'ID']);
540 $counterService =
new self(
$userId);
541 $counterService->deleteAll(
true);
548 $dateExpired = (
new DateTime())->add(self::EXPIRY_INTERVAL);
549 MessageUnreadTable::deleteByFilter([
'<=DATE_CREATE' => $dateExpired]);
550 static::clearCache();
552 return '\Bitrix\Im\V2\Message\CounterService::deleteExpiredCountersAgent();';
558 "\Bitrix\Im\V2\Message\CounterService::deleteCountersOfFiredUserAgent({$userId});",
561 self::DELAY_DELETION_COUNTERS_OF_FIRED_USER,
564 ConvertTimeStamp(time()+CTimeZone::GetOffset()+self::DELAY_DELETION_COUNTERS_OF_FIRED_USER,
"FULL"),
571 \CAgent::RemoveAgent(
572 "\Bitrix\Im\V2\Message\CounterService::deleteCountersOfFiredUserAgent({$userId});",
579 $cache = \Bitrix\Main\Data\Cache::createInstance();
582 unset(self::$staticCounterCache[
$userId], self::$staticChatsCounterCache[
$userId], self::$staticSpecificChatsCounterCache[
$userId]);
583 $cache->clean(static::CACHE_NAME.
'_'.
$userId, self::CACHE_PATH);
585 $cache->clean(self::CACHE_CHATS_COUNTERS_NAME.
'_'.
$userId, self::CACHE_PATH);
589 self::$staticCounterCache = [];
590 self::$staticChatsCounterCache = [];
591 self::$staticSpecificChatsCounterCache = [];
592 $cache->cleanDir(self::CACHE_PATH);
599 $userId = $this->getContext()->getUserId();
600 $cache = \Bitrix\Main\Data\Cache::createInstance();
601 $cache->initCache(static::CACHE_TTL, static::CACHE_NAME .
'_' .
$userId, static::CACHE_PATH);
608 $userId = $this->getContext()->getUserId();
609 $cache = \Bitrix\Main\Data\Cache::createInstance();
610 $cache->initCache(self::CACHE_TTL, self::CACHE_CHATS_COUNTERS_NAME .
'_' .
$userId, self::CACHE_PATH);
619 self::$staticCounterCache[$this->getContext()->getUserId()] =
$this->counters;
626 self::$staticChatsCounterCache[$this->getContext()->getUserId()] = $this->countersByChatIds;
631 $userId = $this->getContext()->getUserId();
633 foreach ($chatIds as $chatId)
635 self::$staticSpecificChatsCounterCache[
$userId][$chatId] = $this->countersByChatIds[$chatId] ?? 0;
643 foreach ($unreadChats as $unreadChat)
645 $chatId = (int)$unreadChat[
'CHAT_ID'];
646 $isMuted = $unreadChat[
'IS_MUTED'] ===
'Y';
648 match ($unreadChat[
'CHAT_TYPE'])
682 else if (
$counter[
'CHAT_TYPE'] === Chat::IM_TYPE_COPILOT)
686 else if (
$counter[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT)
694 $this->countersByChatIds[$chatId] =
$count;
700 if (!$isMuted && !isset($this->counters[
'CHAT'][$id]))
702 $this->counters[
'TYPE'][
'ALL']++;
703 $this->counters[
'TYPE'][
'CHAT']++;
704 $this->counters[
'TYPE'][
'MESSENGER']++;
707 $this->counters[
'CHAT_UNREAD'][] = $id;
712 if (!$isMuted && !isset($this->counters[
'COLLAB'][$id]))
714 $this->counters[
'TYPE'][
'ALL']++;
715 $this->counters[
'TYPE'][
'CHAT']++;
716 $this->counters[
'TYPE'][
'COLLAB']++;
717 $this->counters[
'TYPE'][
'MESSENGER']++;
720 $this->counters[
'CHAT_UNREAD'][] = $id;
721 $this->counters[
'COLLAB_UNREAD'][] = $id;
726 if (!$isMuted && !isset($this->counters[
'COPILOT'][$id]))
728 $this->counters[
'TYPE'][
'ALL']++;
729 $this->counters[
'TYPE'][
'CHAT']++;
730 $this->counters[
'TYPE'][
'COPILOT']++;
731 $this->counters[
'TYPE'][
'MESSENGER']++;
732 $this->counters[
'CHAT_UNREAD'][] = $id;
735 $this->counters[
'COPILOT_UNREAD'][] = $id;
740 $this->counters[
'CHAT_MUTED'][$id] =
$count;
745 $this->counters[
'TYPE'][
'ALL'] +=
$count;
746 $this->counters[
'TYPE'][
'NOTIFY'] +=
$count;
751 $this->counters[
'TYPE'][
'ALL'] +=
$count;
752 $this->counters[
'TYPE'][
'LINES'] +=
$count;
753 $this->counters[
'TYPE'][
'MESSENGER'] +=
$count;
754 $this->counters[
'LINES'][$id] =
$count;
759 $this->counters[
'TYPE'][
'ALL'] +=
$count;
760 $this->counters[
'TYPE'][
'CHAT'] +=
$count;
761 $this->counters[
'TYPE'][
'MESSENGER'] +=
$count;
762 $this->counters[
'TYPE'][
'COPILOT'] +=
$count;
763 $this->counters[
'COPILOT'][$id] =
$count;
764 $this->counters[
'CHAT'][$id] =
$count;
769 $this->counters[
'TYPE'][
'ALL'] +=
$count;
770 $this->counters[
'TYPE'][
'CHAT'] +=
$count;
771 $this->counters[
'TYPE'][
'MESSENGER'] +=
$count;
772 $this->counters[
'TYPE'][
'COLLAB'] +=
$count;
773 $this->counters[
'CHAT'][$id] =
$count;
774 $this->counters[
'COLLAB'][$id] =
$count;
779 if ($parentId ===
null || $parentId === 0)
784 $this->counters[
'TYPE'][
'ALL'] +=
$count;
785 $this->counters[
'TYPE'][
'MESSENGER'] +=
$count;
786 $this->counters[
'CHANNEL_COMMENT'][$parentId][$id] =
$count;
791 $this->counters[
'TYPE'][
'ALL'] +=
$count;
792 $this->counters[
'TYPE'][
'CHAT'] +=
$count;
793 $this->counters[
'TYPE'][
'MESSENGER'] +=
$count;
794 $this->counters[
'CHAT'][$id] =
$count;
801 if (empty($commentChatIds))
806 $raw = ChatTable::query()
807 ->setSelect([
'ID',
'PARENT_ID'])
808 ->whereIn(
'ID', $commentChatIds)
813 foreach ($raw as $row)
815 $chatId = (int)$row[
'ID'];
816 $parentId = (int)($row[
'PARENT_ID'] ?? 0);
829 if (
$counter[
'CHAT_TYPE'] === Chat::IM_TYPE_COMMENT)
840 $query = RecentTable::query()
842 'CHAT_ID' =>
'ITEM_CID',
843 'CHAT_TYPE' =>
'ITEM_TYPE',
844 'IS_MUTED' =>
'RELATION.NOTIFY_BLOCK',
846 ->where(
'USER_ID', $this->getContext()->getUserId())
847 ->where(
'UNREAD',
true)
851 $query->where(
'IS_MUTED', $isMuted);
854 return $query->fetchAll();
860 $query = MessageUnreadTable::query()
861 ->setSelect([
'CHAT_ID',
'IS_MUTED',
'CHAT_TYPE',
'COUNT'])
862 ->setGroup([
'CHAT_ID',
'CHAT_TYPE',
'IS_MUTED'])
863 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
866 if (isset($chatIds) && !empty($chatIds))
868 $query->whereIn(
'CHAT_ID', $chatIds);
872 $query->where(
'USER_ID', $this->getContext()->getUserId());
875 return array_merge($additionalCounters,
$query->fetchAll());
881 $nonAnsweredLines = [];
883 if ($forCurrentUser && empty($chatIds) && Loader::includeModule(
'imopenlines'))
885 $nonAnsweredLines = \Bitrix\ImOpenLines\Recent::getNonAnsweredLines($this->getContext()->getUserId());
888 foreach ($nonAnsweredLines as $lineId)
891 'CHAT_ID' => $lineId,
893 'CHAT_TYPE' => Chat::IM_TYPE_OPEN_LINE,
903 return (
int)MessageUnreadTable::query()
904 ->setSelect([
'COUNT'])
905 ->where(
'USER_ID', $this->getContext()->getUserId())
906 ->where(
'IS_MUTED',
false)
907 ->whereNot(
'CHAT_TYPE', Chat::IM_TYPE_COPILOT)
908 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
915 $query = MessageUnreadTable::query()
916 ->setSelect([
'USER_ID',
'COUNT'])
917 ->where(
'CHAT_ID', $chatId)
918 ->setGroup([
'USER_ID'])
919 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
921 if (!empty($userIds))
923 $query->whereIn(
'USER_ID', $userIds);
926 return $query->fetchAll();
931 return MessageUnreadTable::query()
932 ->setSelect([
'COUNT'])
933 ->where(
'CHAT_ID', $chatId)
934 ->where(
'USER_ID', $this->getContext()->getUserId())
935 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
936 ->fetch()[
'COUNT'] ?? 0
942 $userId = $this->getContext()->getUserId();
944 foreach ($chatIds as $chatId)
946 if ($chatId > 0 && !isset(self::$staticSpecificChatsCounterCache[
$userId][$chatId]))
958 'MESSAGE_ID' =>
$message->getMessageId(),
959 'CHAT_ID' => $relation->getChatId(),
960 'USER_ID' => $relation->getUserId(),
961 'CHAT_TYPE' => $relation->getMessageType(),
962 'IS_MUTED' => $relation->getNotifyBlock() ?
'Y' :
'N',
963 'PARENT_ID' =>
$message->getChat()->getParentChatId() ?? 0,
if(! $messageFields||!isset($messageFields['message_id'])||!isset($messageFields['status'])||!CModule::IncludeModule("messageservice")) $messageId
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static getInstance($userId=null)
static deleteAllViaAgent(int $userId, bool $withNotify)
__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()
setUnreadCollab(int $id, bool $isMuted)
deleteByMessageForAll(Message $message, ?array $invalidateCacheUsers=null)
setUnreadChat(int $id, bool $isMuted)
getUnreadChats(?bool $isMuted=null)
savePreparedCountersInCache(Cache $cache)
setFromNotify(int $count)
getCountUnreadMessagesByChatIdForEachUsers(int $chatId, ?array $userIds=null)
saveSpecificChatsCountersInCache(array $chatIds)
saveChatsCountersInCache(Cache $cache)
const CACHE_CHATS_COUNTERS_NAME
static getChildrenWithCounters(Chat $parentChat, ?int $userId=null)
getCommentChatIdsOnly(array $counters)
setFromLine(int $id, int $count)
getAdditionalCounters(?array $chatIds=null, bool $forCurrentUser=true)
getByChatWithOverflow(int $chatId)
static deleteByChatIdsForAll(array $chatIds)
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)
setFromComment(int $id, ?int $parentId, int $count)
getCountUnreadMessagesByChatId(int $chatId)
static onFireUser(int $userId)
const DELAY_DELETION_COUNTERS_OF_FIRED_USER
getByChatForEachUsers(int $chatId, array $userIds)
setUnreadCopilot(int $id, bool $isMuted)
getCountersForEachChat(?array $chatIds=null, bool $forCurrentUser=true)
static clearCache(?int $userId=null)
getMapChatIdToParentId(array $counters)
getCacheForPreparedCounters()
setFromChat(int $id, int $count)
deleteByChatIds(array $chatIds)
getCacheForChatsCounters()
deleteAll(bool $withNotify=false)
static array $staticCounterCache
getTotalCountUnreadMessages()
addForEachUser(Message $message, RelationCollection $relations)
deleteByMessagesForAll(MessageCollection $messages, ?array $invalidateCacheUsers=null)
static deleteByChatIdForAll(int $chatId)
deleteTo(Message $message)
setFromCollab(int $id, int $count)
addStartingFrom(int $messageId, Relation $relation)
endDataCache($vars=false)
startDataCache($TTL=false, $uniqueString=false, $initDir=false, $vars=array(), $baseDir='cache')
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
const IM_MESSAGE_OPEN_LINE
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
</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."%"