23 private const SUPPORTED_EVENTS = [
24 EventDictionary::EVENT_ATTENDEES_UPDATED,
31 foreach ($events as
$event)
34 $eventType =
$event->getType();
36 if (in_array($eventType, self::SUPPORTED_EVENTS,
true))
38 $eventData =
$event->getData();
39 $affectedUserIds = $eventData[
'user_ids'] ?? [];
40 $affectedEventIds = $eventData[
'event_ids'] ?? [];
41 $affectedGroupIds = $eventData[
'group_ids'] ?? [];
42 if (!$affectedUserIds || (!$affectedEventIds && !$affectedGroupIds))
47 $this->recountGroupEventsInvites($affectedUserIds, $affectedEventIds, $affectedGroupIds);
60 private function recountGroupEventsInvites(
array $userIds,
array $eventIds,
array $groupIds): void
62 $groupsToRecount = [];
64 if (!empty($eventIds))
66 $parentIdsOfAffectedEvents = $this->getParentIdsOfAffectedEvents($eventIds);
67 $groupsToRecount = $this->getAffectedGroupIds($parentIdsOfAffectedEvents);
70 if (!empty($groupIds))
72 $groupsToRecount = array_unique([...$groupsToRecount, ...$groupIds]);
75 if (empty($groupsToRecount))
81 $userAffectedGroups = [];
91 $affectedGroupsForUser = array_intersect($userGroups, $groupsToRecount);
92 if (!$userGroups || !$affectedGroupsForUser)
97 $userAffectedGroups[
$userId] = $affectedGroupsForUser;
101 $groupsToRecountForAffectedUsers = array_unique(array_values(array_merge(...$userAffectedGroups)));
102 if (!$groupsToRecountForAffectedUsers)
107 $groupsToNotify = [];
110 $eventsByGroup = $this->prepareGroupEvents($groupsToRecountForAffectedUsers);
119 foreach ($userAffectedGroups[
$userId] as $groupId)
121 $parentGroupEvents = $eventsByGroup[$groupId] ?? [];
122 if (!$parentGroupEvents)
124 $this->cleanGroupCounter(
$userId, $groupId);
129 $groupsToNotify[$groupId] ??= [];
130 $groupsToNotify[$groupId][] =
$userId;
132 $this->updateGroupCounter(
$userId, $groupId, $parentGroupEvents);
136 if (!empty($groupsToNotify))
138 (
new CollabListener())->notify($groupsToNotify);
152 private function cleanGroupCounter(
int $userId,
int $groupId): void
156 code: $this->getGroupCounterCode($groupId),
162 $this->sendGroupCountersPush(
$userId, $groupId);
175 private function updateGroupCounter(
int $userId,
int $groupId,
array $parentIds): void
177 $actualValue = $this->getActualUserInvitesCount(
$userId, $parentIds);
179 $counterCode = $this->getGroupCounterCode($groupId);
180 $storedValue = \CUserCounter::GetValue(
185 if ((!$actualValue && !$storedValue) || $actualValue === $storedValue)
198 $this->sendGroupCountersPush(
$userId, $groupId);
209 private function getParentIdsOfAffectedEvents(
array $eventIds):
array
213 ->whereIn(
'ID', $eventIds)
214 ->where(
'IS_MEETING', 1)
215 ->setSelect([
'PARENT_ID'])
229 private function getAffectedGroupIds(
array $eventIds):
array
233 ->whereIn(
'ID', $eventIds)
234 ->where(
'CAL_TYPE', Dictionary::CALENDAR_TYPE[
'group'])
235 ->where(
'IS_MEETING', 1)
236 ->setSelect([
'OWNER_ID'])
250 private function prepareGroupEvents(
array $allGroupIds):
array
252 $groupEvents = $this->getGroupsEvents($allGroupIds);
255 foreach ($groupEvents as $eventId => $groupId)
257 $eventsByGroup[(int)$groupId][] = $eventId;
260 return $eventsByGroup;
271 private function getGroupsEvents(
array $groupIds):
array
273 [$fromTimestamp, $toTimestamp] = $this->getPeriod();
276 ->whereIn(
'OWNER_ID', $groupIds)
277 ->where(
'CAL_TYPE', Dictionary::CALENDAR_TYPE[
'group'])
278 ->where(
'DATE_FROM_TS_UTC',
'>=', $fromTimestamp)
279 ->where(
'DATE_TO_TS_UTC',
'<=', $toTimestamp)
280 ->where(
'IS_MEETING', 1)
281 ->where(
'MEETING_STATUS',
'H')
282 ->setSelect([
'ID',
'OWNER_ID'])
285 return array_combine(
$result->getIdList(),
$result->getOwnerIdList());
297 private function getActualUserInvitesCount(
int $userId,
array $parentIds): int
299 [$fromTimestamp, $toTimestamp] = $this->getPeriod();
301 return (
int)EventTable::query()
303 ->whereIn(
'PARENT_ID', $parentIds)
304 ->where(
'CAL_TYPE', Dictionary::CALENDAR_TYPE[
'user'])
305 ->where(
'DATE_FROM_TS_UTC',
'>=', $fromTimestamp)
306 ->where(
'DATE_TO_TS_UTC',
'<=', $toTimestamp)
307 ->where(
'IS_MEETING', 1)
308 ->where(
'MEETING_STATUS',
'Q')
309 ->where(
'DELETED',
'N')
310 ->registerRuntimeField(
'COUNT',
new ExpressionField(
'COUNT',
'COUNT(*)'))
311 ->setSelect([
'COUNT'])
316 private function getPeriod():
array
318 $fromTimestamp = (int)\CCalendar::Timestamp(\CCalendar::Date(time(),
false),
false);
319 $toTimestamp = (int)\CCalendar::Timestamp(\CCalendar::Date(time() + \CCalendar::DAY_LENGTH * 90,
false),
false)
320 + \CCalendar::GetDayLen()
323 return [$fromTimestamp, $toTimestamp];
336 private function sendGroupCountersPush(
int $userId,
int $groupId): void
338 PushService::addEvent(
$userId, [
339 'module_id' => PushService::MODULE_ID,
340 'command' => PushCommand::UpdateGroupCounters->value,
342 'groupId' => $groupId,
355 private function getGroupCounterCode(
int $groupId): string