1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
Notification.php
См. документацию.
1<?php
2
3namespace Bitrix\Im\Configuration;
4
5use Bitrix\Im\Model\OptionStateTable;
6use Bitrix\Im\Model\OptionUserTable;
7use Bitrix\Main\ArgumentException;
8use Bitrix\Main\Db\SqlQueryException;
9use Bitrix\Main\EventManager;
10use Bitrix\Main\ObjectPropertyException;
11use Bitrix\Main\ORM\Fields\Relations\Reference;
12use Bitrix\Main\ORM\Query\Join;
13use Bitrix\Main\SystemException;
14use Bitrix\Main\UserTable;
15use Bitrix\Pull\Model\PushTable;
16
17class Notification extends Base
18{
19 public const SITE = 'site';
20 public const MAIL = 'mail';
21 public const XMPP = 'xmpp';
22 public const PUSH = 'push';
23
24 protected const ENTITY = 'no';
25 protected const MODULE = 1;
26 protected const NAME = 2;
27 protected const TYPE = 3;
28
29 protected static $defaultSettings = [];
30
31 private $module;
32 private $name;
33
34 private static $types = [
35 'SITE' => 1,
36 'MAIL' => 2,
37 'XMPP' => 3,
38 'PUSH' => 4,
39 ];
40
45 public function __construct(string $module, string $name)
46 {
47 $this->module = $module;
48 $this->name = $name;
49 }
50
54 public function setModule(string $module): void
55 {
56 $this->module = $module;
57 }
58
62 public function setName(string $name): void
63 {
64 $this->name = $name;
65 }
66
72 public function isAllowed(int $userId, string $type): bool
73 {
75 {
76 return false;
77 }
78
79 $encodedSetting = self::encodeName($this->module, $this->name, $type);
80
82
84
85 if (!array_key_exists($encodedSetting, $defaultSettings))
86 {
87 $encodedSetting = self::encodeName('im', 'default', $type);
88 }
89
90 $value = $defaultSettings[$encodedSetting] === 'Y' ? 'Y' : 'N';
91
92 $result =
93 OptionUserTable::query()
94 ->addSelect('USER_ID')
95 ->registerRuntimeField(
96 'USER',
97 new Reference(
98 'USER',
99 UserTable::class,
100 Join::on('this.USER_ID', 'ref.ID'),
101 ['join_type' => Join::TYPE_INNER]
102 )
103 )
104 ->registerRuntimeField(
105 'OPTION_STATE',
106 new Reference(
107 'OPTION_STATE',
108 OptionStateTable::class,
109 Join::on('this.NOTIFY_GROUP_ID', 'ref.GROUP_ID')
110 ->where('ref.NAME', $encodedSetting),
111 ['join_type' => Join::TYPE_LEFT]
112 )
113 )
114 ->whereExpr("COALESCE(%s, '$value') = 'Y'", ['OPTION_STATE.VALUE'])
115 ->where('USER_ID', $userId)
116 ->where('USER.ACTIVE', 'Y')
117 ->where('USER.IS_REAL_USER', 'Y')
118 ->fetch()
119 ;
120
121 $result = $result !== false;
122
123 if ($type !== self::PUSH)
124 {
125 return $result;
126 }
127 //checked push
128
129 if ($result)
130 {
131 $query =
132 PushTable::query()
133 ->addSelect('ID')
134 ->where('USER_ID', $userId)
135 ->setLimit(1)
136 ;
137 $pushId = $query->fetch();
138
139 return $pushId !== false;
140 }
141
142 return false;
143 }
144
152 public function filterAllowedUsers(array $userList, string $type): array
153 {
154 if (empty($userList))
155 {
156 return [];
157 }
158
160 if (empty($userList))
161 {
162 return [];
163 }
164
165 $encodedSetting = self::encodeName($this->module, $this->name, $type);
166
168
170
171 if (!array_key_exists($encodedSetting, $defaultSettings))
172 {
173 $encodedSetting = self::encodeName('im', 'default', $type);
174 }
175
176 $value = $defaultSettings[$encodedSetting] === 'Y' ? 'Y' : 'N';
177
178 $filteredUsers = [];
179 if (count($userList) < 1000)
180 {
181 $filteredUsers = $this->filterChunk($userList, $encodedSetting, $value);
182 }
183 else
184 {
185 $chunkList = array_chunk($userList, static::CHUNK_LENGTH);
186 foreach ($chunkList as $chunk)
187 {
188 $filteredUsers = array_merge($filteredUsers, $this->filterChunk($chunk, $encodedSetting, $value));
189 }
190 }
191
192 if ($type !== self::PUSH)
193 {
194 return $filteredUsers;
195 }
196
197 //checked push
198 if (empty($filteredUsers))
199 {
200 return $filteredUsers;
201 }
202
203 $rowFilteredPushUsers =
204 PushTable::query()
205 ->addSelect('USER_ID')
206 ->whereIn('USER_ID', $filteredUsers)
207 ;
208
209 $filteredUsers = [];
210 foreach ($rowFilteredPushUsers->exec() as $user)
211 {
212 $filteredUsers[] = (int)$user['USER_ID'];
213 }
214
215 return array_unique($filteredUsers);
216 }
217
218 private function filterChunk(array $userListChunk, $encodedSettingName, $value): array
219 {
220 $query =
221 OptionUserTable::query()
222 ->addSelect('USER_ID')
223 ->registerRuntimeField(
224 'USER',
225 new Reference(
226 'USER',
227 UserTable::class,
228 Join::on('this.USER_ID', 'ref.ID'),
229 ['join_type' => Join::TYPE_INNER]
230 )
231 )
232 ->registerRuntimeField(
233 'OPTION_STATE',
234 new Reference(
235 'OPTION_STATE',
236 OptionStateTable::class,
237 Join::on('this.NOTIFY_GROUP_ID', 'ref.GROUP_ID')
238 ->where('ref.NAME', $encodedSettingName),
239 ['join_type' => Join::TYPE_LEFT]
240 )
241 )
242 ->whereExpr("COALESCE(%s, '$value') = 'Y'", ['OPTION_STATE.VALUE'])
243 ->whereIn('USER_ID', $userListChunk)
244 ->where('USER.ACTIVE', 'Y')
245 ->where('USER.IS_REAL_USER', 'Y');
246
247 $filteredUsers = [];
248 foreach ($query->exec() as $user)
249 {
250 $filteredUsers[] = (int)$user['USER_ID'];
251 }
252
253 return $filteredUsers;
254 }
255
260 public function checkDisableFeature(string $feature): bool
261 {
263 if (isset($defaultSettings[$this->module]['NOTIFY'][$this->name]['DISABLED'][mb_strtoupper($feature)]))
264 {
265 return (bool)$defaultSettings[$this->module]['NOTIFY'][$this->name]['DISABLED'][mb_strtoupper($feature)];
266 }
267
268 return false;
269 }
270
271 public function getDefaultFeature(string $feature): bool
272 {
273 return (bool)self::getDefaultSettings()[$this->module]['NOTIFY'][$this->name][mb_strtoupper($feature)];
274 }
275
276 public function getLifetime(): int
277 {
278 return (int)self::getDefaultSettings()[$this->module]['NOTIFY'][$this->name]['LIFETIME'];
279 }
280
281 public function getValue(int $userId, string $type): bool
282 {
283 $encodedName = self::encodeName($this->module, $this->name, $type);
284
285 if (!$encodedName)
286 {
287 return false;
288 }
289
290 $defaultSettings = self::encodeSettings(self::getDefaultSettings());
291
293 if (
294 !empty($cachedPreset)
295 && isset($cachedPreset[Configuration::NOTIFY_GROUP])
296 && is_array($cachedPreset[Configuration::NOTIFY_GROUP])
297 )
298 {
299 $notifySettings = $cachedPreset[Configuration::NOTIFY_GROUP]['settings'];
300
301 if (!$notifySettings)
302 {
303 return $defaultSettings[$encodedName];
304 }
305
306 $notifySettings = self::encodeSettings($notifySettings);
307
308 if (is_null($notifySettings[$encodedName]))
309 {
310 return $defaultSettings[$encodedName] === 'Y';
311 }
312
313 return $notifySettings[$encodedName] === 'Y';
314 }
315
316 $query =
317 OptionStateTable::query()
318 ->addSelect('VALUE')
319 ->registerRuntimeField(
320 'OPTION_USER',
321 new Reference(
322 'OPTION_USER',
323 OptionUserTable::class,
324 Join::on('this.GROUP_ID', 'ref.NOTIFY_GROUP_ID'),
325 ['join_type' => Join::TYPE_INNER]
326 )
327 )
328 ->where('OPTION_USER.USER_ID', $userId)
329 ->where('NAME', $encodedName)
330 ;
331
332 $value = $query->fetch()['VALUE'];
333
334 if (!$value)
335 {
336 return $defaultSettings[$encodedName] === 'Y';
337 }
338
339 return $value === 'Y';
340 }
341
347 public static function getDefaultSettings(): array
348 {
349 if (!empty(self::$defaultSettings))
350 {
351 return self::$defaultSettings;
352 }
353
354 foreach (EventManager::getInstance()->findEventHandlers("im", "OnGetNotifySchema") as $events)
355 {
356 $event = ExecuteModuleEventEx($events);
357
358 if (!is_array($event))
359 {
360 continue;
361 }
362
363 foreach ($event as $moduleId => $notifyType)
364 {
365 self::$defaultSettings[$moduleId]['NAME'] =
366 isset($notifyType['NOTIFY'], $notifyType['NAME'])
367 ? $notifyType['NAME']
368 : '';
369
370 $notify = $notifyType['NOTIFY'] ?? $notifyType;
371
372 foreach ($notify as $notifyEvent => $config)
373 {
374 $config['DISABLED'] = $config['DISABLED'] ?? [];
375
376 if (!isset($config['PUSH']) || $config['PUSH'] === 'NONE')
377 {
378 $config['DISABLED'][] = self::PUSH;
379 }
380
381 $disabled['SITE'] = in_array(self::SITE, $config['DISABLED'], true);
382 $disabled['MAIL'] = in_array(self::MAIL, $config['DISABLED'], true);
383 $disabled['XMPP'] = in_array(self::XMPP, $config['DISABLED'], true);
384 $disabled['PUSH'] = in_array(self::PUSH, $config['DISABLED'], true);
385
386 $config['DISABLED'] = $disabled;
387
388 // backward compatibility
389 $config['SITE'] = !isset($config['SITE']) || $config['SITE'] == 'Y';
390 $config['MAIL'] = !isset($config['MAIL']) || $config['MAIL'] == 'Y';
391 $config['XMPP'] = !isset($config['XMPP']) || $config['XMPP'] == 'Y';
392 $config['PUSH'] = isset($config['PUSH']) && $config['PUSH'] == 'Y';
393
394 $config['LIFETIME'] = isset($config['LIFETIME']) ? (int)$config['LIFETIME'] : 0;
395
396 self::$defaultSettings[$moduleId]['NOTIFY'][$notifyEvent] = $config;
397 }
398 }
399 }
400
401 return self::$defaultSettings;
402 }
403
404 public static function getSimpleNotifySettings(array $generalSettings): array
405 {
406 $defaultGeneralSettings = General::getDefaultSettings();
407
408 $send['SITE'] = $generalSettings['notifySchemeSendSite'] ?? $defaultGeneralSettings['notifySchemeSendSite'];
409 $send['MAIL'] = $generalSettings['notifySchemeSendEmail'] ?? $defaultGeneralSettings['notifySchemeSendEmail'];
410 $send['XMPP'] = $generalSettings['notifySchemeSendXmpp'] ?? $defaultGeneralSettings['notifySchemeSendXmpp'];
411 $send['PUSH'] = $generalSettings['notifySchemeSendPush'] ?? $defaultGeneralSettings['notifySchemeSendPush'];
412
413 $notifySettings = Notification::getDefaultSettings();
414
415 foreach ($notifySettings as $moduleId => $moduleSchema)
416 {
417 foreach ($moduleSchema['NOTIFY'] as $eventName => $eventSchema)
418 {
419 foreach (['SITE', 'MAIL', 'XMPP', 'PUSH'] as $type)
420 {
421 if ($eventSchema['DISABLED'][$type])
422 {
423 continue;
424 }
425
426 $notifySettings[$moduleId]['NOTIFY'][$eventName][$type] =
427 !$send[$type]
428 ? false
429 : $eventSchema[$type]
430 ;
431 }
432 }
433 }
434
435 return $notifySettings;
436 }
437
445 public static function getUserSettings(int $userId): array
446 {
448
449 $query =
450 OptionStateTable::query()
451 ->setSelect(['NAME','VALUE'])
452 ->registerRuntimeField(
453 'OPTION_USER_TABLE',
454 new Reference(
455 'OPTION_USER_TABLE',
456 OptionUserTable::class,
457 Join::on('this.GROUP_ID', 'ref.NOTIFY_GROUP_ID'),
458 ['join_type' => Join::TYPE_INNER]
459 )
460 )
461 ->where('OPTION_USER_TABLE.USER_ID', $userId)
462 ->whereLike('NAME', static::ENTITY.'%')
463 ;
464
465 $rowSettings = [];
466 foreach ($query->exec() as $rowSetting)
467 {
468 $rowSettings[] = $rowSetting;
469 }
470
471 if (empty($rowSettings))
472 {
473 return $defaultSettings;
474 }
475
476 $decodedSettings = static::decodeSettings($rowSettings);
477
478 return array_replace_recursive($defaultSettings, $decodedSettings);
479 }
480
488 public static function getGroupSettings(int $groupId): array
489 {
491
492 $query =
493 OptionStateTable::query()
494 ->setSelect(['NAME','VALUE'])
495 ->where('GROUP_ID', $groupId)
496 ->whereLike('NAME', static::ENTITY . '%')
497 ;
498
499 $settings = [];
500 foreach ($query->exec() as $rowSetting)
501 {
502 $settings[] = $rowSetting;
503 }
504
505 if (empty($settings))
506 {
507 return $defaultSettings;
508 }
509
510 $settings = static::decodeSettings($settings);
511
513 }
514
516 {
517 $result = [];
519
520 foreach ($defaultSettings as $moduleId => $defaultModuleSettings)
521 {
522 $moduleSettings = $settings[$moduleId]['NOTIFY'] ?? [];
523
524 foreach ($defaultModuleSettings['NOTIFY'] ?? [] as $notifyKey => $notifyValue)
525 {
526 $defaultModuleSettings['NOTIFY'][$notifyKey] =
527 array_replace_recursive($notifyValue, $moduleSettings[$notifyKey] ?? [])
528 ;
529 }
530
531 $result[$moduleId] = $defaultModuleSettings;
532 }
533
534 return $result;
535 }
536
543 public static function updateGroupSettings(int $groupId, array $settings): void
544 {
545 if (!$settings)
546 {
547 return;
548 }
549 $encodedSettings = self::encodeSettings($settings);
550 $defaultSettings = self::encodeSettings(self::getDefaultSettings());
551
552 $query =
553 OptionStateTable::query()
554 ->setSelect(['NAME', 'VALUE'])
555 ->where('GROUP_ID', $groupId)
556 ->whereLike('NAME', self::ENTITY . '%')
557 ;
558 $addedSettings = [];
559 $enabledSettings = [];
560 $disabledSettings = [];
561 foreach ($query->exec() as $row)
562 {
563 if (array_key_exists($row['NAME'], $encodedSettings))
564 {
565 if ($row['VALUE'] === $encodedSettings[$row['NAME']])
566 {
567 unset($encodedSettings[$row['NAME']]);
568 continue;
569 }
570 if ($encodedSettings[$row['NAME']] === 'Y')
571 {
572 $enabledSettings[] = [
573 'GROUP_ID' => $groupId,
574 'NAME' => $row['NAME']
575 ];
576 unset($encodedSettings[$row['NAME']]);
577 continue;
578 }
579 if ($encodedSettings[$row['NAME']] === 'N')
580 {
581 $disabledSettings[] = [
582 'GROUP_ID' => $groupId,
583 'NAME' => $row['NAME']
584 ];
585 unset($encodedSettings[$row['NAME']]);
586 }
587 }
588 }
589
590 foreach ($encodedSettings as $name => $value)
591 {
592 if (!array_key_exists($name, $defaultSettings))
593 {
594 continue;
595 }
596
597 $addedSettings[] = [
598 'GROUP_ID' => $groupId,
599 'NAME' => $name,
600 'VALUE' => $value
601 ];
602 }
603 if (!empty($addedSettings))
604 {
605 OptionStateTable::addMulti($addedSettings, true);
606 }
607 if (!empty($enabledSettings))
608 {
609 OptionStateTable::updateMulti($enabledSettings, ['VALUE' => 'Y'], true);
610 }
611 if (!empty($disabledSettings))
612 {
613 OptionStateTable::updateMulti($disabledSettings, ['VALUE' => 'N'], true);
614 }
615
616 }
617
624 public static function setSettings(int $groupId, array $settings = [], bool $forInitialize = false): void
625 {
626 if (empty($settings) && !$forInitialize)
627 {
628 return;
629 }
630
631 $selectedSettings = [];
632 $query =
633 OptionStateTable::query()
634 ->setSelect(['NAME', 'VALUE'])
635 ->where('GROUP_ID', $groupId)
636 ->whereLike('NAME', self::ENTITY . '%')
637 ;
638 foreach ($query->exec() as $row)
639 {
640 $selectedSettings[$row['NAME']] = $row['VALUE'];
641 }
642 $defaultSettings = self::encodeSettings(self::getDefaultSettings());
643 $encodedSettings = self::encodeSettings($settings);
644 $encodedSettings = array_merge($defaultSettings, $encodedSettings);
645
646 $rows = [];
647 foreach ($encodedSettings as $name => $value)
648 {
649 if (!array_key_exists($name, $defaultSettings) || isset($selectedSettings[$name]))
650 {
651 continue;
652 }
653
654 $rows[] = [
655 'GROUP_ID' => $groupId,
656 'NAME' => $name,
657 'VALUE' => $value
658 ];
659 }
660
661 OptionStateTable::multiplyInsertWithoutDuplicate($rows);
662 }
663
664 public static function getEventNames(): array
665 {
666 $names = [];
668 foreach ($defaultSettings as $moduleId => $notifyTypes)
669 {
670 $names[$moduleId]['NAME'] = $notifyTypes['NAME'];
671 if ($notifyTypes['NAME'] == '')
672 {
673 $moduleObject = \CModule::CreateModuleObject($moduleId);
674 $names[$moduleId]['NAME'] = $moduleObject->MODULE_NAME;
675 }
676 foreach ($notifyTypes['NOTIFY'] as $eventId => $event)
677 {
678 $names[$moduleId]['NOTIFY'][$eventId] = $event['NAME'];
679 }
680 }
681
682 return $names;
683 }
684
692 public static function decodeSettings(array $rowSettings): array
693 {
694 $decodedSettings = [];
695
696 foreach ($rowSettings as $rowSetting)
697 {
698 if (!$rowSetting['NAME'])
699 {
700 continue;
701 }
702
703 $setting = self::decodeName($rowSetting['NAME']);
704
705 if ($setting === null)
706 {
707 continue;
708 }
709 $module = $setting[self::MODULE];
710 $name = $setting[self::NAME];
711
712 if(!in_array((int)$setting[self::TYPE], [1,2,3,4]))
713 {
714 continue;
715 }
716
717 $type = self::getType((int)$setting[self::TYPE]);
718
719 $decodedSettings[$module]['NOTIFY'][$name][$type] = $rowSetting['VALUE'] === 'Y';
720 }
721
722 return $decodedSettings;
723 }
724
733 public static function encodeSettings(array $settings): array
734 {
735 $encodedSettings = [];
736
737 foreach ($settings as $moduleName => $notifies)
738 {
739 if (!is_array($notifies))
740 {
741 continue;
742 }
743
744 foreach ($notifies as $notify)
745 {
746 if (!is_array($notify))
747 {
748 continue;
749 }
750
751 foreach ($notify as $notifyName => $types)
752 {
753 foreach ($types as $type => $value)
754 {
755 $setting = self::encodeName($moduleName, $notifyName, $type);
756
757 if (!$setting || mb_strlen($setting) > 64)
758 {
759 continue;
760 }
761
762 $encodedSettings[$setting] = $value ? 'Y' : 'N';
763 }
764
765 }
766 }
767 }
768
769 return $encodedSettings;
770 }
771
779 private static function decodeName(string $setting): ?array
780 {
781 $row = explode(static::SEPARATOR, $setting);
782
783 if (!array_key_exists(self::MODULE, $row)
784 || !array_key_exists(self::NAME, $row)
785 || !array_key_exists(self::TYPE, $row)
786 )
787 {
788 return null;
789 }
790
791 return $row;
792 }
793
803 private static function encodeName(string $module, string $name, string $type): ?string
804 {
805 if ($type === '')
806 {
807 return null;
808 }
809
810 $postfix = self::getPostfix($type);
811
812 if ($postfix === null)
813 {
814 return null;
815 }
816
817 return implode(
818 static::SEPARATOR,
819 [
820 static::ENTITY,
821 $module,
822 $name,
823 $postfix,
824 ]
825 );
826 }
827
833 private static function getPostfix(string $type): ?int
834 {
835 return self::$types[mb_strtoupper($type)] ?? null;
836 }
837
843 private static function getType(int $postfix): ?string
844 {
845 $arr = array_flip(self::$types);
846
847 return $arr[$postfix];
848 }
849
850}
$type
Определения options.php:106
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getUserPresetFromCache(int $userId)
Определения Configuration.php:917
static filterAllowedUsersBySimpleNotificationSettings(array $userList, string $notifyType)
Определения General.php:232
static getDefaultSettings()
Определения General.php:95
static allowedUserBySimpleNotificationSettings(int $userId, string $notifyType)
Определения General.php:220
static updateGroupSettings(int $groupId, array $settings)
Определения Notification.php:543
checkDisableFeature(string $feature)
Определения Notification.php:260
isAllowed(int $userId, string $type)
Определения Notification.php:72
static setSettings(int $groupId, array $settings=[], bool $forInitialize=false)
Определения Notification.php:624
static getDefaultSettings()
Определения Notification.php:347
getDefaultFeature(string $feature)
Определения Notification.php:271
filterAllowedUsers(array $userList, string $type)
Определения Notification.php:152
static getGroupSettings(int $groupId)
Определения Notification.php:488
setName(string $name)
Определения Notification.php:62
__construct(string $module, string $name)
Определения Notification.php:45
static getUserSettings(int $userId)
Определения Notification.php:445
static encodeSettings(array $settings)
Определения Notification.php:733
static getSimpleNotifySettings(array $generalSettings)
Определения Notification.php:404
static filterGroupSettingsByDefault(array $settings)
Определения Notification.php:515
getValue(int $userId, string $type)
Определения Notification.php:281
static decodeSettings(array $rowSettings)
Определения Notification.php:692
setModule(string $module)
Определения Notification.php:54
static getInstance()
Определения eventmanager.php:31
$userList
Определения discount_coupon_list.php:276
$arr
Определения file_new.php:624
</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
$query
Определения get_search.php:11
$moduleId
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
$name
Определения menu_edit.php:35
$user
Определения mysql_to_pgsql.php:33
$settings
Определения product_settings.php:43
$event
Определения prolog_after.php:141
return false
Определения prolog_main_admin.php:185
$config
Определения quickway.php:69
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$rows
Определения options.php:264