Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
event.php
1<?php
2
3namespace Bitrix\Pull;
4
9
10class Event
11{
12 const SHARED_CHANNEL = 0;
13
14 private static bool $backgroundContext = false;
15
16 private static array $messages = [];
17 private static array $deferredMessages = [];
18 private static array $push = [];
19 private static $error = false;
20
21 public static function add($recipient, array $parameters, $channelType = \CPullChannel::TYPE_PRIVATE)
22 {
23 if (!isset($parameters['module_id']))
24 {
25 self::$error = new Error(__METHOD__, 'EVENT_PARAMETERS_FORMAT', Loc::getMessage('PULL_EVENT_PARAMETERS_FORMAT_ERROR'), $parameters);
26 return false;
27 }
28
29 $badUnicodeSymbolsPath = Common::findInvalidUnicodeSymbols($parameters);
30 if ($badUnicodeSymbolsPath)
31 {
32 $warning = 'Parameters array contains invalid UTF-8 characters by the path ' . $badUnicodeSymbolsPath;
33 self::$error = new Error(__METHOD__, 'EVENT_BAD_ENCODING', $warning, $parameters);
34 return false;
35 }
36
37 if (isset($parameters['command']) && !empty($parameters['command']))
38 {
39 if (!Config::isJsonRpcUsed() && (isset($parameters['user_params']) || isset($parameters['dictionary'])))
40 {
41 self::generateEventsForUsers($recipient, $parameters, $channelType);
42 }
43 else
44 {
45 $result = self::addEvent($recipient, $parameters, $channelType);
46 }
47 }
48 else if (isset($parameters['push']) || isset($parameters['pushParamsCallback']))
49 {
50 $result = self::addPush($recipient, $parameters);
51 }
52 else
53 {
54 self::$error = new Error(__METHOD__, 'EVENT_PARAMETERS_FORMAT', Loc::getMessage('PULL_EVENT_PARAMETERS_FORMAT_ERROR'), $parameters);
55 return false;
56 }
57
58 return $result;
59 }
60
61 private static function addEvent($recipient, $parameters, $channelType = \CPullChannel::TYPE_PRIVATE)
62 {
63 if (!is_array($recipient))
64 {
65 $recipient = [$recipient];
66 }
67
68 $entities = self::getEntitiesByType($recipient);
69 if ($entities === null)
70 {
71 self::$error = new Error(__METHOD__, 'RECIPIENT_FORMAT', Loc::getMessage('PULL_EVENT_RECIPIENT_FORMAT_ERROR'), [
72 'recipient' => $recipient,
73 'eventParameters' => $parameters,
74 ]);
75
76 return false;
77 }
78
79 $parameters = self::prepareParameters($parameters);
80 if (!$parameters)
81 {
82 return false;
83 }
84 $parameters['channel_type'] = $channelType;
85
86 if (empty($entities['users']) && empty($entities['channels']))
87 {
88 return true;
89 }
90
91 if (isset($parameters['push']))
92 {
93 $pushParameters = $parameters['push'];
94 unset($parameters['push']);
95 }
96 else
97 {
98 $pushParameters = null;
99 }
100
101 if (isset($parameters['pushParamsCallback']))
102 {
103 $pushParametersCallback = $parameters['pushParamsCallback'];
104 unset($parameters['pushParamsCallback']);
105 }
106 else
107 {
108 $pushParametersCallback = null;
109 }
110
111 if (isset($parameters['hasCallback']) && $parameters['hasCallback'])
112 {
113 self::addMessage(self::$deferredMessages, $entities['channels'], $entities['users'], $parameters);
114 }
115 else
116 {
117 self::addMessage(self::$messages, $entities['channels'], $entities['users'], $parameters);
118 }
119
120 if (
121 self::$backgroundContext
122 || defined('BX_CHECK_AGENT_START') && !defined('BX_WITH_ON_AFTER_EPILOG')
123 )
124 {
125 self::send();
126 }
127
128 if ($pushParameters || $pushParametersCallback)
129 {
130 if ($pushParameters)
131 {
132 $parameters['push'] = $pushParameters;
133 }
134 if ($pushParametersCallback)
135 {
136 $parameters['pushParamsCallback'] = $pushParametersCallback;
137 }
138 unset($parameters['channel_type']);
139 self::addPush($entities['users'], $parameters);
140 }
141
142 return true;
143 }
144
145 private static function addMessage(array &$destination, array $channels, array $users, array $parameters)
146 {
147 $eventCode = self::getParamsCode($parameters);
148 unset($parameters['hasCallback']);
149
150 if (isset($destination[$eventCode]))
151 {
152 $waitingToReceiveUserList = $destination[$eventCode]['users'] ?? [];
153 $newUserList = $users ?? [];
154 $destination[$eventCode]['users'] = array_unique(array_merge($waitingToReceiveUserList, $newUserList));
155
156 $waitingToReceiveChannelList = $destination[$eventCode]['channels'] ?? [];
157 $newChannelList = $channels ?? [];
158 $destination[$eventCode]['channels'] = array_unique(array_merge($waitingToReceiveChannelList, $newChannelList));
159 }
160 else
161 {
162 $destination[$eventCode] = [
163 'event' => $parameters,
164 'users' => array_unique($users),
165 'channels' => array_unique($channels),
166 ];
167 }
168 }
169
170 private static function generateEventsForUsers($recipients, $parameters, $channelType = \CPullChannel::TYPE_PRIVATE)
171 {
172 if (!is_array($recipients))
173 {
174 $recipients = [$recipients];
175 }
176 if (is_array($parameters['dictionary']))
177 {
178 $dictionary = $parameters['dictionary'];
179 unset($parameters['dictionary']);
180 $parameters['params'] = array_merge($parameters['params'], $dictionary);
181 }
182
183 $processed = [];
184 if (is_array($parameters['user_params']))
185 {
186 $params = $parameters['params'];
187 $paramsByUser = $parameters['user_params'];
188 unset($parameters['user_params']);
189
190 foreach ($recipients as $recipient)
191 {
192 if (isset($paramsByUser[$recipient]) && is_array($paramsByUser[$recipient]))
193 {
194 $userParams = $parameters;
195 $userParams['params'] = array_merge($params, $paramsByUser[$recipient]);
196 self::addEvent($recipient, $userParams, $channelType);
197
198 $processed[] = $recipient;
199 }
200 }
201 }
202 $left = array_diff($recipients, $processed);
203 if (!empty($left))
204 {
205 self::addEvent($left, $parameters, $channelType);
206 }
207 }
208
209 private static function addPush($users, $parameters)
210 {
211 if (!\CPullOptions::GetPushStatus())
212 {
213 self::$error = new Error(__METHOD__, 'PUSH_DISABLED', Loc::getMessage('PULL_EVENT_PUSH_DISABLED_ERROR'), [
214 'recipient' => $users,
215 'eventParameters' => $parameters,
216 ]);
217
218 return false;
219 }
220 if (!is_array($users))
221 {
222 $users = [$users];
223 }
224
225 foreach ($users as $id => $entity)
226 {
227 $entity = intval($entity);
228 if ($entity <= 0)
229 {
230 unset($users[$id]);
231 }
232 }
233
234 if (empty($users))
235 {
236 self::$error = new Error(__METHOD__, 'RECIPIENT_FORMAT', Loc::getMessage('PULL_EVENT_RECIPIENT_FORMAT_ERROR'), [
237 'recipient' => $users,
238 'eventParameters' => $parameters,
239 ]);
240
241 return false;
242 }
243
244 if (isset($parameters['skip_users']))
245 {
246 if (!isset($parameters['push']['skip_users']))
247 {
248 $parameters['push']['skip_users'] = [];
249 }
250 $parameters['push']['skip_users'] = array_merge($parameters['skip_users'], $parameters['push']['skip_users']);
251 }
252
253 if (!empty($parameters['push']['type']))
254 {
255 foreach ($users as $userId)
256 {
257 if (!\Bitrix\Pull\Push::getConfigTypeStatus($parameters['module_id'], $parameters['push']['type'], $userId))
258 {
259 $parameters['push']['skip_users'][] = $userId;
260 }
261 }
262 }
263
264 $parameters = self::preparePushParameters($parameters);
265 if (!$parameters)
266 {
267 return false;
268 }
269
270 $pushCode = self::getParamsCode($parameters['push']);
271 if (self::$push[$pushCode])
272 {
273 self::$push[$pushCode]['users'] = array_unique(array_merge(self::$push[$pushCode]['users'], array_values($users)));
274 }
275 else
276 {
277 $hasPushCallback = $parameters['hasPushCallback'];
278 unset($parameters['hasPushCallback']);
279
280 self::$push[$pushCode]['push'] = $parameters['push'];
281 self::$push[$pushCode]['extra'] = $parameters['extra'];
282 self::$push[$pushCode]['hasPushCallback'] = $hasPushCallback;
283 self::$push[$pushCode]['users'] = array_unique(array_values($users));
284 }
285
286 if (
287 self::$backgroundContext
288 || defined('BX_CHECK_AGENT_START') && !defined('BX_WITH_ON_AFTER_EPILOG')
289 )
290 {
291 self::send();
292 }
293
294 return true;
295 }
296
297 private static function processDeferredMessages()
298 {
299 foreach (self::$deferredMessages as $eventCode => $message)
300 {
301 $callback = $message['event']['paramsCallback'];
302 if (Main\Loader::includeModule($callback['module_id']) && method_exists($callback['class'], $callback['method']))
303 {
304 $messageParameters = call_user_func_array([$callback['class'], $callback['method']], [$callback['params']]);
305 self::addMessage(self::$messages, $message['users'], $message['channels'], $messageParameters);
306 }
307 }
308 self::$deferredMessages = [];
309 }
310
311 private static function executePushEvent($parameters)
312 {
313 if (!self::$backgroundContext && $parameters['hasPushCallback'])
314 {
315 return null;
316 }
317
318 $data = [];
319 if ($parameters['hasPushCallback'])
320 {
321 $callback = $parameters['push']['pushParamsCallback'];
322 Main\Loader::includeModule($callback['module_id']);
323 if (method_exists($callback['class'], $callback['method']))
324 {
325 $data = call_user_func_array(
326 [
327 $callback['class'],
328 $callback['method'],
329 ],
330 [
331 $callback['params'],
332 ]
333 );
334 }
335 }
336 else
337 {
338 $data = $parameters['push'];
339 }
340
341 $data['message'] = str_replace("\n", " ", trim($data['message']));
342 $data['params'] = $data['params'] ?? [];
343 $data['advanced_params'] = $data['advanced_params'] ?? [];
344 $data['advanced_params']['extra'] = $parameters['extra'] ?? [];
345 $data['badge'] = isset($data['badge']) ? (int)$data['badge'] : '';
346 $data['sound'] = $data['sound'] ?? '';
347 $data['tag'] = $data['tag'] ?? '';
348 $data['sub_tag'] = $data['sub_tag'] ?? '';
349 $data['app_id'] = $data['app_id'] ?? '';
350 $data['send_immediately'] = $data['send_immediately'] == 'Y' ? 'Y' : 'N';
351 $data['important'] = $data['important'] == 'Y' ? 'Y' : 'N';
352
353 $users = [];
354 foreach ($parameters['users'] as $userId)
355 {
356 $users[] = $userId;
357 }
358
359 if (empty($users))
360 {
361 return true;
362 }
363
364 $manager = new \CPushManager();
365 $manager->AddQueue([
366 'USER_ID' => $users,
367 'SKIP_USERS' => is_array($data['skip_users']) ? $data['skip_users'] : [],
368 'MESSAGE' => $data['message'],
369 'EXPIRY' => $data['expiry'],
370 'PARAMS' => $data['params'],
371 'ADVANCED_PARAMS' => $data['advanced_params'],
372 'BADGE' => $data['badge'],
373 'SOUND' => $data['sound'],
374 'TAG' => $data['tag'],
375 'SUB_TAG' => $data['sub_tag'],
376 'APP_ID' => $data['app_id'],
377 'SEND_IMMEDIATELY' => $data['send_immediately'],
378 'IMPORTANT' => $data['important'],
379 ]);
380
381 return true;
382 }
383
384 public static function send()
385 {
386 if (self::$backgroundContext)
387 {
388 self::processDeferredMessages();
389 }
390
391 $executeResult = static::executeEvents();
392 if (!$executeResult->isSuccess())
393 {
394 foreach ($executeResult->getErrors() as $error)
395 {
396 $message = $error->getCode() ? $error->getCode() . ": " . $error->getMessage() : $error->getMessage();
397 trigger_error("Pull send error; {$message}; remote endpoint: {$executeResult->getRemoteAddress()}", E_USER_WARNING);
398 }
399 }
400
401 static::executePushEvents();
402
403 return true;
404 }
405
406 public static function executeEvents(): TransportResult
407 {
408 $result = new TransportResult();
409 if (empty(self::$messages))
410 {
411 return $result;
412 }
413
414 if (!\CPullOptions::GetQueueServerStatus())
415 {
416 self::$messages = [];
417
418 return $result;
419 }
420
421 self::fillChannels(self::$messages);
422
423 if (Config::isJsonRpcUsed())
424 {
425 $messageList = self::convertEventsToMessages(self::$messages);
426 $sendResult = (new JsonRpcTransport())->sendMessages($messageList);
427 if ($sendResult->isSuccess())
428 {
429 self::$messages = [];
430 }
431 else
432 {
433 $result->withRemoteAddress($sendResult->getRemoteAddress());
434 $result->addErrors($sendResult->getErrors());
435 }
436 }
437 else
438 {
439 if (Config::isProtobufUsed())
440 {
441 $sendResult = ProtobufTransport::sendMessages(self::$messages);
442 if (!$sendResult->isSuccess())
443 {
444 $result->withRemoteAddress($sendResult->getRemoteAddress());
445 $result->addErrors($sendResult->getErrors());
446 }
447 }
448 else
449 {
450 self::sendEventsLegacy();
451 }
452
453 self::$messages = [];
454 }
455
456 return $result;
457 }
458
459
460 public static function executePushEvents()
461 {
462 foreach (self::$push as $pushCode => $event)
463 {
464 $result = self::executePushEvent($event);
465 if (!is_null($result))
466 {
467 unset(self::$push[$pushCode]);
468 }
469 }
470 }
471
472 private static function sendEventsLegacy()
473 {
474 foreach (self::$messages as $eventCode => $event)
475 {
476 if (\Bitrix\Pull\Log::isEnabled())
477 {
478 // TODO change code after release - $parameters['hasCallback']
479 $currentHits = ceil(count($event['channels']) / \CPullOptions::GetCommandPerHit());
480 $hitCount += $currentHits;
481
482 $currentChannelCount = count($event['channels']);
483 $channelCount += $currentChannelCount;
484
485 $currentMessagesBytes = self::getBytes($event['event']) + self::getBytes($event['channels']);
486 $messagesBytes += $currentMessagesBytes;
487 $logs[] = 'Command: ' . $event['event']['module_id'] . '/' . $event['event']['command'] . '; Hits: ' . $currentHits . '; Channel: ' . $currentChannelCount . '; Bytes: ' . $currentMessagesBytes . '';
488 }
489
490 if (empty($event['channels']))
491 {
492 continue;
493 }
494
495 $data = [
496 'module_id' => $event['event']['module_id'],
497 'command' => $event['event']['command'],
498 'params' => is_array($event['event']['params']) ? $event['event']['params'] : [],
499 'extra' => $event['event']['extra'],
500 ];
501 $options = ['expiry' => $event['event']['expiry']];
502
503 if (\CPullChannel::Send($event['channels'], \Bitrix\Pull\Common::jsonEncode($data), $options))
504 {
505 unset(self::$messages[$eventCode]);
506 }
507 }
508
509 if ($logs && \Bitrix\Pull\Log::isEnabled())
510 {
511 if (count($logs) > 1)
512 {
513 $logs[] = 'Total - Hits: ' . $hitCount . '; Channel: ' . $channelCount . '; Messages: ' . $messagesCount . '; Bytes: ' . $messagesBytes . '';
514 }
515
516 if (count($logs) > 1 || $hitCount > 1 || $channelCount > 1 || $messagesBytes > 1000)
517 {
518 $logTitle = '!! Pull messages stats - important !!';
519 }
520 else
521 {
522 $logTitle = '-- Pull messages stats --';
523 }
524
525 \Bitrix\Pull\Log::write(implode("\n", $logs), $logTitle);
526 }
527 }
528
529 public static function onAfterEpilog()
530 {
531 Main\Application::getInstance()->addBackgroundJob([__CLASS__, "sendInBackground"]);
532 return true;
533 }
534
535 public static function sendInBackground()
536 {
537 self::$backgroundContext = true;
538 self::send();
539 }
540
541 public static function fillChannels(array &$messages)
542 {
543 foreach ($messages as $key => &$message)
544 {
545 $users = $message['users'] ?? [];
546 if (!empty($messages[$key]['channels']) && is_array($messages[$key]['channels']))
547 {
548 $messages[$key]['channels'] = array_merge($messages[$key]['channels'], self::getChannelIds($users, $message['event']['channel_type']));
549 }
550 else
551 {
552 $messages[$key]['channels'] = self::getChannelIds($users, $message['event']['channel_type']);
553 }
554 unset($message['event']['channel_type']);
555 }
556 }
557
558 public static function getChannelIds(array $users, $type = \CPullChannel::TYPE_PRIVATE)
559 {
560 $result = [];
561 foreach ($users as $userId)
562 {
563 $data = \CPullChannel::Get($userId, true, false, $type);
564 if ($data)
565 {
566 $result[] = $data['CHANNEL_ID'];
567 }
568 }
569
570 return $result;
571 }
572
573 public static function getUserIds(array $channels)
574 {
575 $result = array_fill_keys($channels, null);
576 $orm = \Bitrix\Pull\Model\ChannelTable::getList([
577 'select' => ['USER_ID', 'CHANNEL_ID', 'USER_ACTIVE' => 'USER.ACTIVE'],
578 'filter' => [
579 '=CHANNEL_ID' => $channels,
580 ],
581 ]);
582 while ($row = $orm->fetch())
583 {
584 if ($row['USER_ID'] > 0 && $row['USER_ACTIVE'] !== 'N')
585 {
586 $result[$row['CHANNEL_ID']] = $row['USER_ID'];
587 }
588 else
589 {
590 unset($result[$row['CHANNEL_ID']]);
591 }
592 }
593
594 return $result;
595 }
596
597 private static function prepareParameters(array $parameters)
598 {
599 if (empty($parameters['command']))
600 {
601 self::$error = new Error(__METHOD__, 'EVENT_PARAMETERS_FORMAT', Loc::getMessage('PULL_EVENT_PARAMETERS_FORMAT_ERROR'), $parameters);
602 return false;
603 }
604
605 $parameters['module_id'] = mb_strtolower($parameters['module_id']);
606 $parameters['expiry'] = (int)($parameters['expiry'] ?? 86400);
607
608 if (isset($parameters['paramsCallback']))
609 {
610 if (empty($parameters['paramsCallback']['class']) || empty($parameters['paramsCallback']['method']))
611 {
612 self::$error = new Error(__METHOD__, 'EVENT_CALLBACK_FORMAT', Loc::getMessage('PULL_EVENT_CALLBACK_FORMAT_ERROR'), $parameters);
613 return false;
614 }
615
616 if (empty($parameters['paramsCallback']['module_id']))
617 {
618 $parameters['paramsCallback']['module_id'] = $parameters['module_id'];
619 }
620
621 Main\Loader::includeModule($parameters['paramsCallback']['module_id']);
622
623 if (!method_exists($parameters['paramsCallback']['class'], $parameters['paramsCallback']['method']))
624 {
625 self::$error = new Error(__METHOD__, 'EVENT_CALLBACK_NOT_FOUND', Loc::getMessage('PULL_EVENT_CALLBACK_FORMAT_ERROR'), $parameters);
626 return false;
627 }
628 if (!isset($parameters['paramsCallback']['params']))
629 {
630 $parameters['paramsCallback']['params'] = [];
631 }
632
633 $parameters['params'] = [];
634 $parameters['hasCallback'] = true;
635 }
636 else
637 {
638 if (!isset($parameters['params']) || !is_array($parameters['params']))
639 {
640 $parameters['params'] = [];
641 }
642 }
643
644 $parameters['extra']['server_time'] ??= date('c');
645 $parameters['extra']['server_time_unix'] ??= microtime(true);
646
647 $parameters['extra']['server_name'] = Option::get('main', 'server_name', $_SERVER['SERVER_NAME']);
648 $parameters['extra']['revision_web'] = PULL_REVISION_WEB;
649 $parameters['extra']['revision_mobile'] = PULL_REVISION_MOBILE;
650
651 return $parameters;
652 }
653
654 private static function preparePushParameters(array $parameters)
655 {
656 $parameters['module_id'] = mb_strtolower($parameters['module_id']);
657
658 if (isset($parameters['pushParamsCallback']))
659 {
660 if (
661 empty($parameters['pushParamsCallback']['class'])
662 || empty($parameters['pushParamsCallback']['method'])
663 )
664 {
665 self::$error = new Error(__METHOD__, 'EVENT_PUSH_CALLBACK_FORMAT', Loc::getMessage('PULL_EVENT_PUSH_CALLBACK_FORMAT_ERROR'), $parameters);
666 return false;
667 }
668
669 if (empty($parameters['pushParamsCallback']['module_id']))
670 {
671 $parameters['pushParamsCallback']['module_id'] = $parameters['module_id'];
672 }
673
674 Main\Loader::includeModule($parameters['pushParamsCallback']['module_id']);
675
676 if (!method_exists($parameters['pushParamsCallback']['class'], $parameters['pushParamsCallback']['method']))
677 {
678 self::$error = new Error(__METHOD__, 'EVENT_PUSH_CALLBACK_NOT_FOUND', Loc::getMessage('PULL_EVENT_PUSH_CALLBACK_FORMAT_ERROR'), $parameters);
679 return false;
680 }
681 if (!isset($parameters['pushParamsCallback']['params']))
682 {
683 $parameters['pushParamsCallback']['params'] = [];
684 }
685 $parameters['push']['pushParamsCallback'] = $parameters['pushParamsCallback'];
686 $parameters['hasPushCallback'] = true;
687 }
688 else
689 {
690 $parameters['hasPushCallback'] = false;
691 $parameters['pushParamsCallback'] = [];
692
693 if (isset($parameters['badge']) && $parameters['badge'] == 'Y')
694 {
695 $parameters['send_immediately'] = 'Y';
696 unset($parameters['badge']);
697 }
698
699 if (empty($parameters['push']))
700 {
701 self::$error = new Error(__METHOD__, 'EVENT_PUSH_PARAMETERS_FORMAT', Loc::getMessage('PULL_EVENT_PUSH_PARAMETERS_FORMAT_ERROR'), $parameters);
702 return false;
703 }
704 }
705
706 if (!isset($parameters['extra']['server_time']))
707 {
708 $parameters['extra']['server_time'] = date('c');
709 }
710 if (!$parameters['extra']['server_time_unix'])
711 {
712 $parameters['extra']['server_time_unix'] = microtime(true);
713 }
714
715 return $parameters;
716 }
717
718 public static function getParamsCode($params)
719 {
720 if (isset($params['groupId']) && !empty($params['groupId']))
721 {
722 return md5($params['groupId']);
723 }
724 else
725 {
726 $paramsWithoutTime = $params;
727
728 unset($paramsWithoutTime['extra']['server_time']);
729 unset($paramsWithoutTime['extra']['server_time_unix']);
730 unset($paramsWithoutTime['advanced_params']['filterCallback']);
731
732 return serialize($paramsWithoutTime);
733 }
734 }
735
736 private static function getEntitiesByType(array $recipientList): ?array
737 {
738 $result = [
739 'users' => [],
740 'channels' => [],
741 'count' => 0,
742 ];
743 foreach ($recipientList as $entity)
744 {
745 if ($entity instanceof \Bitrix\Pull\Model\Channel)
746 {
747 $result['channels'][] = $entity->getPrivateId();
748 $result['count']++;
749 }
750 else if (self::isChannelEntity($entity))
751 {
752 $result['channels'][] = $entity;
753 $result['count']++;
754 }
755 else
756 {
757 $result['users'][] = intval($entity);
758 $result['count']++;
759 }
760 }
761
762 return $result['count'] > 0 ? $result : null;
763 }
764
765 private static function getBytes($variable)
766 {
767 $bytes = 0;
768
769 if (is_string($variable))
770 {
771 $bytes += mb_strlen($variable);
772 }
773 else if (is_array($variable))
774 {
775 foreach ($variable as $value)
776 {
777 $bytes += self::getBytes($value);
778 }
779 }
780 else
781 {
782 $bytes += mb_strlen((string)$variable);
783 }
784
785 return $bytes;
786 }
787
788 private static function isChannelEntity($entity)
789 {
790 return is_string($entity) && mb_strlen($entity) == 32;
791 }
792
797 private static function convertEventsToMessages(array $events): array
798 {
799 return array_map(
800 function ($event) {
801 return Message::fromEvent($event);
802 },
803 $events
804 );
805 }
806
807 public static function getLastError()
808 {
809 return self::$error;
810 }
811
812}
send($sender=null)
Definition event.php:139
static includeModule($moduleName)
Definition loader.php:69
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getParamsCode($params)
Definition event.php:718
static send()
Definition event.php:384
static add($recipient, array $parameters, $channelType=\CPullChannel::TYPE_PRIVATE)
Definition event.php:21
static getChannelIds(array $users, $type=\CPullChannel::TYPE_PRIVATE)
Definition event.php:558
static sendInBackground()
Definition event.php:535
static executeEvents()
Definition event.php:406
static getLastError()
Definition event.php:807
static getUserIds(array $channels)
Definition event.php:573
static executePushEvents()
Definition event.php:460
const SHARED_CHANNEL
Definition event.php:12
static fillChannels(array &$messages)
Definition event.php:541
static onAfterEpilog()
Definition event.php:529