Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
Logger.php
1<?php
2
3namespace Bitrix\Im\V2\Sync;
4
5use Bitrix\Im\Model\EO_Log_Collection;
7use Bitrix\Im\V2\Common\ContextCustomer;
14
15class Logger
16{
17 use ContextCustomer;
18
19 public const DEFAULT_EXPIRY_INTERVAL = '+4 weeks';
20 public const FAST_EXPIRY_INTERVAL = '+1 days';
21
22 private static Logger $instance;
23
24 private bool $isAlreadyPlanned = false;
25 private array $events = [];
26 private ?array $allowedUsers = null;
27
28 private function __construct()
29 {
30 }
31
32 public static function getInstance(): self
33 {
34 self::$instance ??= new Logger();
35
36 return self::$instance;
37 }
38
39 public function add(Event $event, $userId): void
40 {
42 {
43 return;
44 }
45
46 $userId ??= $this->getContext()->getUserId();
47 $this->events[] = ['event' => $event, 'user' => $userId];
48
49 if (!$this->isAlreadyPlanned)
50 {
51 Application::getInstance()->addBackgroundJob(fn () => $this->addDeferred());
52 $this->isAlreadyPlanned = true;
53 }
54 }
55
56 public function updateDateDelete(EO_Log_Collection $logs, ?DateTime $dateDelete = null): void
57 {
58 Application::getInstance()->addBackgroundJob(fn () => $this->updateDateDeleteDeferred($logs, $dateDelete));
59 }
60
61 public static function cleanAgent(): string
62 {
63 return '';
64
65 (new static())->clean();
66
67 return __METHOD__ . '();';
68 }
69
70 public function clean(): void
71 {
72 $now = new DateTime();
73 LogTable::deleteByFilter(['<=DATE_DELETE' => $now]);
74 }
75
76 private function addDeferred(): void
77 {
78 if (!Loader::includeModule('pull'))
79 {
80 return;
81 }
82
83 $this->runClosureInEvents();
84 $groupedEvents = $this->getGroupedEvents();
85
86 foreach ($groupedEvents as ['event' => $event, 'user' => $userId])
87 {
88 if (count($userId) === 1)
89 {
90 LogTable::merge(...$this->getMergeParam($event, $userId));
91 }
92 else
93 {
94 LogTable::multiplyMerge(...$this->getMultiplyMergeParam($event, $userId));
95 }
96 }
97 $this->events = [];
98 $this->isAlreadyPlanned = false;
99 }
100
101 private function updateDateDeleteDeferred(EO_Log_Collection $logs, ?DateTime $dateDelete): void
102 {
103 return;
104
105 if ($dateDelete === null)
106 {
107 $dateDelete = new DateTime();
108 $dateDelete->add(self::FAST_EXPIRY_INTERVAL);
109 }
110
111 $newDateDeleteTs = $dateDelete->getTimestamp();
112 foreach ($logs as $log)
113 {
114 $oldDateDelete = $log->getDateDelete();
115 if ($oldDateDelete === null || $oldDateDelete->getTimestamp() > $newDateDeleteTs)
116 {
117 $log->setDateDelete($dateDelete);
118 }
119 }
120
121 $logs->save(true);
122 }
123
124 private function getGroupedEvents(): array
125 {
126 $result = [];
127
129 foreach ($this->events as ['event' => $event, 'user' => $userId])
130 {
131 $userId = $this->filterUsers($this->getUsersFromEvent(['user' => $userId]));
132
133 if (empty($userId))
134 {
135 continue;
136 }
137
138 $key = "{$event->eventName}|{$event->entityType}|{$event->entityId}";
139
140 if (isset($result[$key]['user']))
141 {
142 $result[$key]['user'] = $this->mergeByKey($result[$key]['user'], $userId);
143 }
144 else
145 {
146 $result[$key] = ['event' => $event, 'user' => $userId];
147 }
148 }
149
150 return array_values($result);
151 }
152
153 private function filterUsers(array $users): array
154 {
155 if (!isset($this->allowedUsers))
156 {
157 $this->fillAllowedUsers();
158 }
159
160 foreach ($users as $key => $userId)
161 {
162 if (!isset($this->allowedUsers[$userId]))
163 {
164 unset($users[$key]);
165 }
166 }
167
168 return $users;
169 }
170
171 private function fillAllowedUsers(): void
172 {
173 $allUsers = $this->getUsers();
174
175 foreach ($allUsers as $userId)
176 {
177 $user = User::getInstance($userId);
178 $isRealUser = !in_array($user->getExternalAuthId(), UserTable::getExternalUserTypes(), true);
179 if ($isRealUser && $user->isActive())
180 {
181 $this->allowedUsers[$userId] = $userId;
182 }
183 }
184 }
185
186 private function getUsers(): array
187 {
188 $users = [];
189
190 foreach ($this->events as $event)
191 {
192 $eventUsers = $this->getUsersFromEvent($event);
193
194 foreach ($eventUsers as $eventUser)
195 {
196 $users[$eventUser] = $eventUser;
197 }
198 }
199
200 return $users;
201 }
202
203 private function getUsersFromEvent(array $eventItem): array
204 {
205 $users = $eventItem['user'] ?? [];
206
207 if (is_int($users))
208 {
209 $users = [$users];
210 }
211
212 if (!is_array($users))
213 {
214 return [];
215 }
216
217 return $users;
218 }
219
220 private function filterWithoutMobile(array $userIds): array
221 {
222 if (empty($userIds))
223 {
224 return $userIds;
225 }
226
227 return PushTable::query()
228 ->setSelect(['USER_ID'])
229 ->whereIn('USER_ID', $userIds)
230 ->fetchCollection()
231 ->getUserIdList()
232 ;
233 }
234
235 private function filterInactive(array $userIds): array
236 {
237 if (empty($userIds))
238 {
239 return $userIds;
240 }
241
242 return UserTable::query()
243 ->setSelect(['ID'])
244 ->whereIn('ID', $userIds)
245 ->where('ACTIVE', true)
246 ->where('IS_REAL_USER', true)
247 ->fetchCollection()
248 ->getIdList()
249 ;
250 }
251
252 private function runClosureInEvents(): void
253 {
254 foreach ($this->events as $key => ['event' => $event, 'user' => $userId])
255 {
256 if (is_callable($userId))
257 {
258 $this->events[$key]['user'] = $userId();
259 }
260 }
261 }
262
263 private function mergeByKey(array ...$arrays): array
264 {
265 $result = [];
266 foreach ($arrays as $array)
267 {
268 foreach ($array as $key => $value)
269 {
270 $result[$key] = $value;
271 }
272 }
273
274 return $result;
275 }
276
277 private function getMergeParam(Event $event, array $userId): array
278 {
279 $intUserId = array_values($userId)[0];
280
281 return [
282 [
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(),
289 ],
290 [
291 'EVENT' => $event->eventName,
292 'DATE_CREATE' => $event->getDateCreate(),
293 'DATE_DELETE' => $event->getDateDelete(),
294 ],
295 [
296 'USER_ID',
297 'ENTITY_TYPE',
298 'ENTITY_ID',
299 ]
300 ];
301 }
302
303 private function getMultiplyMergeParam(Event $event, array $userId): array
304 {
305 $insertFields = [];
306
307 foreach ($userId as $id)
308 {
309 $insertFields[] = [
310 'USER_ID' => $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(),
316 ];
317 }
318
319 return [
320 $insertFields,
321 [
322 'EVENT' => $event->eventName,
323 'DATE_CREATE' => $event->getDateCreate(),
324 'DATE_DELETE' => $event->getDateDelete(),
325 ],
326 [
327 'USER_ID',
328 'ENTITY_TYPE',
329 'ENTITY_ID',
330 ],
331 ['DEADLOCK_SAFE' => true]
332 ];
333 }
334}
static getInstance($userId=null)
Definition user.php:44
updateDateDelete(EO_Log_Collection $logs, ?DateTime $dateDelete=null)
Definition Logger.php:56
add(Event $event, $userId)
Definition Logger.php:39