1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
Logger.php
См. документацию.
1<?php
2
3namespace Bitrix\Im\V2\Sync;
4
5use Bitrix\Im\Model\EO_Log_Collection;
6use Bitrix\Im\Model\LogTable;
7use Bitrix\Im\V2\Chat;
8use Bitrix\Im\V2\Common\ContextCustomer;
9use Bitrix\Im\V2\Entity\User\User;
10use Bitrix\Main\Application;
11use Bitrix\Main\Loader;
12use Bitrix\Main\Type\DateTime;
13use Bitrix\Main\UserTable;
14use Bitrix\Pull\Model\PushTable;
15
16class Logger
17{
18 use ContextCustomer;
19
20 public const DEFAULT_EXPIRY_INTERVAL = '+4 weeks';
21 public const FAST_EXPIRY_INTERVAL = '+1 days';
22 protected const CHAT_TYPE_BLACKLIST = [
23 Chat::IM_TYPE_OPEN_LINE,
24 Chat::IM_TYPE_COMMENT,
25 ];
26
27 private static Logger $instance;
28
29 private bool $isAlreadyPlanned = false;
30 private array $events = [];
31 private ?array $allowedUsers = null;
32
33 private function __construct()
34 {
35 }
36
37 public static function getInstance(): self
38 {
39 self::$instance ??= new Logger();
40
41 return self::$instance;
42 }
43
44 public function add(Event $event, mixed $userId, ?Chat $chat = null): void
45 {
47 {
48 return;
49 }
50
51 if (!$this->needToLog($chat))
52 {
53 return;
54 }
55
56 $userId ??= $this->getContext()->getUserId();
57 $this->events[] = ['event' => $event, 'user' => $userId];
58
59 if (!$this->isAlreadyPlanned)
60 {
61 Application::getInstance()->addBackgroundJob(fn () => $this->addDeferred(), [], Application::JOB_PRIORITY_LOW);
62 $this->isAlreadyPlanned = true;
63 }
64 }
65
66 public function updateDateDelete(EO_Log_Collection $logs, ?DateTime $dateDelete = null): void
67 {
68 Application::getInstance()->addBackgroundJob(fn () => $this->updateDateDeleteDeferred($logs, $dateDelete));
69 }
70
71 public static function cleanAgent(): string
72 {
73 return '';
74
75 (new static())->clean();
76
77 return __METHOD__ . '();';
78 }
79
80 public function clean(): void
81 {
82 $now = new DateTime();
83 LogTable::deleteByFilter(['<=DATE_DELETE' => $now]);
84 }
85
86 protected function needToLog(?Chat $chat): bool
87 {
88 if ($chat === null)
89 {
90 return true;
91 }
92
93 if (
94 $chat instanceof Chat\NullChat
95 || $chat instanceof Chat\NotifyChat
96 )
97 {
98 return false;
99 }
100
101 if (in_array($chat->getType(), self::CHAT_TYPE_BLACKLIST, true))
102 {
103 return false;
104 }
105
106 return !empty($chat->getRecentSections());
107 }
108
109 private function addDeferred(): void
110 {
111 if (!Loader::includeModule('pull'))
112 {
113 return;
114 }
115
116 $this->runClosureInEvents();
117 $groupedEvents = $this->getGroupedEvents();
118
119 foreach ($groupedEvents as ['event' => $event, 'user' => $userId])
120 {
121 LogTable::multiplyMerge(...$this->getMultiplyMergeParam($event, $userId));
122 }
123 $this->events = [];
124 $this->isAlreadyPlanned = false;
125 }
126
127 private function updateDateDeleteDeferred(EO_Log_Collection $logs, ?DateTime $dateDelete): void
128 {
129 return;
130
131 if ($dateDelete === null)
132 {
133 $dateDelete = new DateTime();
134 $dateDelete->add(self::FAST_EXPIRY_INTERVAL);
135 }
136
137 $newDateDeleteTs = $dateDelete->getTimestamp();
138 foreach ($logs as $log)
139 {
140 $oldDateDelete = $log->getDateDelete();
141 if ($oldDateDelete === null || $oldDateDelete->getTimestamp() > $newDateDeleteTs)
142 {
143 $log->setDateDelete($dateDelete);
144 }
145 }
146
147 $logs->save(true);
148 }
149
150 private function getGroupedEvents(): array
151 {
152 $result = [];
153
155 foreach ($this->events as ['event' => $event, 'user' => $userId])
156 {
157 $userId = $this->filterUsers($this->getUsersFromEvent(['user' => $userId]));
158
159 if (empty($userId))
160 {
161 continue;
162 }
163
164 $key = "{$event->eventName}|{$event->entityType}|{$event->entityId}";
165
166 if (isset($result[$key]['user']))
167 {
168 $result[$key]['user'] = $this->mergeByKey($result[$key]['user'], $userId);
169 }
170 else
171 {
172 $result[$key] = ['event' => $event, 'user' => $userId];
173 }
174 }
175
176 return array_values($result);
177 }
178
179 private function filterUsers(array $users): array
180 {
181 if (!isset($this->allowedUsers))
182 {
183 $this->fillAllowedUsers();
184 }
185
186 foreach ($users as $key => $userId)
187 {
188 if (!isset($this->allowedUsers[$userId]))
189 {
190 unset($users[$key]);
191 }
192 }
193
194 return $users;
195 }
196
197 private function fillAllowedUsers(): void
198 {
199 $allUsers = $this->getUsers();
200
201 foreach ($allUsers as $userId)
202 {
203 $user = User::getInstance($userId);
204 $isRealUser = !in_array($user->getExternalAuthId(), UserTable::getExternalUserTypes(), true);
205 if ($isRealUser && $user->isActive())
206 {
207 $this->allowedUsers[$userId] = $userId;
208 }
209 }
210 }
211
212 private function getUsers(): array
213 {
214 $users = [];
215
216 foreach ($this->events as $event)
217 {
218 $eventUsers = $this->getUsersFromEvent($event);
219
220 foreach ($eventUsers as $eventUser)
221 {
222 $users[$eventUser] = $eventUser;
223 }
224 }
225
226 return $users;
227 }
228
229 private function getUsersFromEvent(array $eventItem): array
230 {
231 $users = $eventItem['user'] ?? [];
232
233 if (is_int($users))
234 {
235 return [$users => $users];
236 }
237
238 if (is_array($users))
239 {
240 $result = [];
241
242 foreach ($users as $id)
243 {
244 $result[$id] = $id;
245 }
246
247 return $result;
248 }
249
250 return [];
251 }
252
253 private function filterWithoutMobile(array $userIds): array
254 {
255 if (empty($userIds))
256 {
257 return $userIds;
258 }
259
260 return PushTable::query()
261 ->setSelect(['USER_ID'])
262 ->whereIn('USER_ID', $userIds)
263 ->fetchCollection()
264 ->getUserIdList()
265 ;
266 }
267
268 private function filterInactive(array $userIds): array
269 {
270 if (empty($userIds))
271 {
272 return $userIds;
273 }
274
275 return UserTable::query()
276 ->setSelect(['ID'])
277 ->whereIn('ID', $userIds)
278 ->where('ACTIVE', true)
279 ->where('REAL_USER', 'expr', true)
280 ->fetchCollection()
281 ->getIdList()
282 ;
283 }
284
285 private function runClosureInEvents(): void
286 {
287 foreach ($this->events as $key => ['event' => $event, 'user' => $userId])
288 {
289 if (is_callable($userId))
290 {
291 $this->events[$key]['user'] = $userId();
292 }
293 }
294 }
295
296 private function mergeByKey(array ...$arrays): array
297 {
298 $result = [];
299 foreach ($arrays as $array)
300 {
301 foreach ($array as $key => $value)
302 {
304 }
305 }
306
307 return $result;
308 }
309
310 private function getMergeParam(Event $event, array $userId): array
311 {
312 $intUserId = array_values($userId)[0];
313
314 return [
315 [
316 'USER_ID' => $intUserId,
317 'ENTITY_TYPE' => $event->entityType,
318 'ENTITY_ID' => $event->entityId,
319 'EVENT' => $event->eventName,
320 'DATE_CREATE' => $event->getDateCreate(),
321 'DATE_DELETE' => $event->getDateDelete(),
322 ],
323 [
324 'EVENT' => $event->eventName,
325 'DATE_CREATE' => $event->getDateCreate(),
326 'DATE_DELETE' => $event->getDateDelete(),
327 ],
328 [
329 'USER_ID',
330 'ENTITY_TYPE',
331 'ENTITY_ID',
332 ]
333 ];
334 }
335
336 private function getMultiplyMergeParam(Event $event, array $userId): array
337 {
338 $insertFields = [];
339
340 foreach ($userId as $id)
341 {
342 $insertFields[] = [
343 'USER_ID' => $id,
344 'ENTITY_TYPE' => $event->entityType,
345 'ENTITY_ID' => $event->entityId,
346 'EVENT' => $event->eventName,
347 'DATE_CREATE' => $event->getDateCreate(),
348 'DATE_DELETE' => $event->getDateDelete(),
349 ];
350 }
351
352 return [
353 $insertFields,
354 [
355 'EVENT' => $event->eventName,
356 'DATE_CREATE' => $event->getDateCreate(),
357 'DATE_DELETE' => $event->getDateDelete(),
358 ],
359 [
360 'USER_ID',
361 'ENTITY_TYPE',
362 'ENTITY_ID',
363 ],
364 ['DEADLOCK_SAFE' => true]
365 ];
366 }
367}
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getType($chatData, bool $camelCase=true)
Определения chat.php:45
const FAST_EXPIRY_INTERVAL
Определения Logger.php:21
static cleanAgent()
Определения Logger.php:71
needToLog(?Chat $chat)
Определения Logger.php:86
updateDateDelete(EO_Log_Collection $logs, ?DateTime $dateDelete=null)
Определения Logger.php:66
const CHAT_TYPE_BLACKLIST
Определения Logger.php:22
static getInstance()
Определения Logger.php:37
add(Event $event, mixed $userId, ?Chat $chat=null)
Определения Logger.php:44
clean()
Определения Logger.php:80
const DEFAULT_EXPIRY_INTERVAL
Определения Logger.php:20
static isEnable()
Определения SyncService.php:19
const JOB_PRIORITY_LOW
Определения application.php:32
static getInstance()
Определения application.php:98
static includeModule($moduleName)
Определения loader.php:67
static getExternalUserTypes()
Определения user.php:307
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$value
Определения Param.php:39
$user
Определения mysql_to_pgsql.php:33
$event
Определения prolog_after.php:141
if(empty($signedUserToken)) $key
Определения quickway.php:257