• Модуль: tasks
  • Путь к файлу: ~/bitrix/modules/tasks/lib/internals/counter/countercollector.php
  • Класс: BitrixTasksInternalsCounterCounterCollector
  • Вызов: CounterCollector::recountComments
private function recountComments(string $taskFilter, array $mutedTasks): array
{
	[$userTypeJoin, $userTypeFilter] = $this->getUserTypeSqlParts();

	$sql = "
		SELECT
		    T.ID,
			COUNT(DISTINCT FM.ID) as COUNT,
			T.GROUP_ID,
		   	TM.TYPE
		FROM b_tasks T
			LEFT JOIN b_tasks_viewed TV ON TV.TASK_ID = T.ID AND TV.USER_ID = {$this->userId}
			INNER JOIN b_tasks_member TM ON TM.TASK_ID = T.ID AND TM.USER_ID = {$this->userId}
			INNER JOIN b_forum_message FM ON FM.TOPIC_ID = T.FORUM_TOPIC_ID
			{$userTypeJoin}
		WHERE
			{$taskFilter}
			AND (
				(TV.VIEWED_DATE IS NOT NULL AND FM.POST_DATE > TV.VIEWED_DATE)
				OR (TV.VIEWED_DATE IS NULL AND FM.POST_DATE >= T.CREATED_DATE)
			)
			AND FM.NEW_TOPIC = 'N'
			AND FM.AUTHOR_ID <> {$this->userId}
			{$userTypeFilter}
			{$this->getCounterFilter()}
		GROUP BY T.ID, TM.TYPE
	";

	$res = Application::getConnection()->query($sql);
	$rows = $res->fetchAll();

	$responsibleTasks = [];
	foreach ($rows as $row)
	{
		if ($row['TYPE'] === MemberTable::MEMBER_TYPE_RESPONSIBLE)
		{
			$responsibleTasks[] = $row['ID'];
		}
	}

	$counters = [];

	foreach ($rows as $row)
	{
		$type = $row['TYPE'];
		if (!array_key_exists($type, CounterDictionary::MAP_COMMENTS))
		{
			continue;
		}
		if (
			$type === MemberTable::MEMBER_TYPE_ORIGINATOR
			&& in_array($row['ID'], $responsibleTasks)
		)
		{
			continue;
		}

		$counters[] = [
			'USER_ID'	=> $this->userId,
			'TASK_ID' 	=> (int) $row['ID'],
			'GROUP_ID' 	=> (int) $row['GROUP_ID'],
			'TYPE' 		=> in_array($row['ID'], $mutedTasks)
				? CounterDictionary::MAP_MUTED_COMMENTS[$type]
				: CounterDictionary::MAP_COMMENTS[$type],
			'VALUE' 	=> (int) $row['COUNT']
		];
	}

	return $counters;
}