22 private static Logger $instance;
24 private bool $isAlreadyPlanned =
false;
25 private array $events = [];
26 private ?array $allowedUsers =
null;
28 private function __construct()
34 self::$instance ??=
new Logger();
36 return self::$instance;
39 public function add(
Event $event, $userId): void
46 $userId ??= $this->getContext()->getUserId();
47 $this->events[] = [
'event' => $event,
'user' => $userId];
49 if (!$this->isAlreadyPlanned)
52 $this->isAlreadyPlanned =
true;
65 (
new static())->clean();
67 return __METHOD__ .
'();';
73 LogTable::deleteByFilter([
'<=DATE_DELETE' => $now]);
76 private function addDeferred(): void
78 if (!Loader::includeModule(
'pull'))
83 $this->runClosureInEvents();
84 $groupedEvents = $this->getGroupedEvents();
86 foreach ($groupedEvents as [
'event' => $event,
'user' => $userId])
88 if (count($userId) === 1)
90 LogTable::merge(...$this->getMergeParam($event, $userId));
94 LogTable::multiplyMerge(...$this->getMultiplyMergeParam($event, $userId));
98 $this->isAlreadyPlanned =
false;
101 private function updateDateDeleteDeferred(EO_Log_Collection $logs, ?DateTime $dateDelete): void
105 if ($dateDelete ===
null)
107 $dateDelete =
new DateTime();
108 $dateDelete->add(self::FAST_EXPIRY_INTERVAL);
111 $newDateDeleteTs = $dateDelete->getTimestamp();
112 foreach ($logs as $log)
114 $oldDateDelete = $log->getDateDelete();
115 if ($oldDateDelete ===
null || $oldDateDelete->getTimestamp() > $newDateDeleteTs)
117 $log->setDateDelete($dateDelete);
124 private function getGroupedEvents(): array
129 foreach ($this->events as [
'event' => $event,
'user' => $userId])
131 $userId = $this->filterUsers($this->getUsersFromEvent([
'user' => $userId]));
138 $key =
"{$event->eventName}|{$event->entityType}|{$event->entityId}";
140 if (isset($result[$key][
'user']))
142 $result[$key][
'user'] = $this->mergeByKey($result[$key][
'user'], $userId);
146 $result[$key] = [
'event' => $event,
'user' =>
$userId];
150 return array_values($result);
153 private function filterUsers(array $users): array
155 if (!isset($this->allowedUsers))
157 $this->fillAllowedUsers();
160 foreach ($users as $key => $userId)
162 if (!isset($this->allowedUsers[$userId]))
171 private function fillAllowedUsers(): void
173 $allUsers = $this->getUsers();
175 foreach ($allUsers as $userId)
178 $isRealUser = !in_array($user->getExternalAuthId(), UserTable::getExternalUserTypes(),
true);
179 if ($isRealUser && $user->isActive())
186 private function getUsers(): array
190 foreach ($this->events as $event)
192 $eventUsers = $this->getUsersFromEvent($event);
194 foreach ($eventUsers as $eventUser)
196 $users[$eventUser] = $eventUser;
203 private function getUsersFromEvent(array $eventItem): array
205 $users = $eventItem[
'user'] ?? [];
212 if (!is_array($users))
220 private function filterWithoutMobile(array $userIds): array
227 return PushTable::query()
228 ->setSelect([
'USER_ID'])
229 ->whereIn(
'USER_ID', $userIds)
235 private function filterInactive(array $userIds): array
242 return UserTable::query()
244 ->whereIn(
'ID', $userIds)
245 ->where(
'ACTIVE',
true)
246 ->where(
'IS_REAL_USER',
true)
252 private function runClosureInEvents(): void
254 foreach ($this->events as $key => [
'event' => $event,
'user' => $userId])
256 if (is_callable($userId))
258 $this->events[$key][
'user'] =
$userId();
263 private function mergeByKey(array ...$arrays): array
266 foreach ($arrays as $array)
268 foreach ($array as $key => $value)
270 $result[$key] = $value;
277 private function getMergeParam(Event $event, array $userId): array
279 $intUserId = array_values($userId)[0];
283 'USER_ID' => $intUserId,
284 'ENTITY_TYPE' => $event->entityType,
285 'ENTITY_ID' => $event->entityId,
286 'EVENT' => $event->eventName,
287 'DATE_CREATE' => $event->getDateCreate(),
288 'DATE_DELETE' => $event->getDateDelete(),
291 'EVENT' => $event->eventName,
292 'DATE_CREATE' => $event->getDateCreate(),
293 'DATE_DELETE' => $event->getDateDelete(),
303 private function getMultiplyMergeParam(Event $event, array $userId): array
307 foreach ($userId as $id)
311 'ENTITY_TYPE' => $event->entityType,
312 'ENTITY_ID' => $event->entityId,
313 'EVENT' => $event->eventName,
314 'DATE_CREATE' => $event->getDateCreate(),
315 'DATE_DELETE' => $event->getDateDelete(),
322 'EVENT' => $event->eventName,
323 'DATE_CREATE' => $event->getDateCreate(),
324 'DATE_DELETE' => $event->getDateDelete(),
331 [
'DEADLOCK_SAFE' =>
true]