1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
user_group.php
См. документацию.
1<?php
2
17use Bitrix\Socialnetwork\Integration;
23
24Loc::loadMessages(__FILE__);
25
27{
28 protected static $roleCache = array();
29
30 protected const EVENTS_JOB_PRIORITY = -1;
31
32 protected const LOCK_TIMEOUT = 15;
33
34 /***************************************/
35 /******** DATA MODIFICATION **********/
36 /***************************************/
37 public static function CheckFields($ACTION, &$relationFields, $id = 0): bool
38 {
40
41 if ($ACTION !== "ADD" && (int)$id <= 0)
42 {
43 $APPLICATION->ThrowException("System error 870164", "ERROR");
44 return false;
45 }
46
47 if (
48 (isset($relationFields['USER_ID']) || $ACTION === "ADD")
49 && (int)$relationFields["USER_ID"] <= 0
50 )
51 {
52 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_USER_ID'), 'EMPTY_USER_ID');
53 return false;
54 }
55
56 if (isset($relationFields['USER_ID']))
57 {
58 $res = CUser::getList(
59 'ID',
60 'ASC',
61 ['ID_EQUAL_EXACT' => $relationFields["USER_ID"]],
62 ['FIELDS' => ['ID']],
63 );
64 if (!$res->fetch())
65 {
66 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_USER_ID'), 'ERROR_NO_USER_ID');
67 return false;
68 }
69 }
70
71 if (
72 (isset($relationFields['GROUP_ID']) || $ACTION === "ADD")
73 && (int)$relationFields["GROUP_ID"] <= 0
74 )
75 {
76 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_GROUP_ID'), 'EMPTY_GROUP_ID');
77 return false;
78 }
79
80 if (
81 isset($relationFields["GROUP_ID"])
82 && !CSocNetGroup::getById($relationFields["GROUP_ID"])
83 )
84 {
85 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_GROUP_ID'), 'ERROR_NO_GROUP_ID');
86 return false;
87 }
88
89 if (
90 (isset($relationFields["ROLE"]) || $ACTION === "ADD")
91 && $relationFields["ROLE"] === ''
92 )
93 {
94 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_ROLE'), 'EMPTY_ROLE');
95 return false;
96 }
97
98 if (
99 isset($relationFields["ROLE"])
100 && !in_array($relationFields["ROLE"], $arSocNetAllowedRolesForUserInGroup, true)
101 )
102 {
103 $APPLICATION->ThrowException(str_replace(
104 "#ID#",
105 $relationFields["ROLE"],
106 Loc::getMessage('SONET_UG_ERROR_NO_ROLE')
107 ), 'ERROR_NO_ROLE');
108 return false;
109 }
110
111 if (
112 (isset($relationFields["INITIATED_BY_TYPE"]) || $ACTION === "ADD")
113 && (string)$relationFields["INITIATED_BY_TYPE"] === ''
114 )
115 {
116 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_INITIATED_BY_TYPE'), 'EMPTY_INITIATED_BY_TYPE');
117 return false;
118 }
119
120 if (
121 isset($relationFields["INITIATED_BY_TYPE"])
122 && !in_array($relationFields["INITIATED_BY_TYPE"], $arSocNetAllowedInitiatedByType, true)
123 )
124 {
125 $APPLICATION->ThrowException(str_replace(
126 '#ID#',
127 $relationFields["INITIATED_BY_TYPE"],
128 Loc::getMessage('SONET_UG_ERROR_NO_INITIATED_BY_TYPE')
129 ), 'ERROR_NO_INITIATED_BY_TYPE');
130 return false;
131 }
132
133 if (
134 (isset($relationFields['INITIATED_BY_USER_ID']) || $ACTION === "ADD")
135 && (int)$relationFields['INITIATED_BY_USER_ID'] <= 0
136 )
137 {
138 $APPLICATION->ThrowException(
139 Loc::getMessage('SONET_UG_EMPTY_INITIATED_BY_USER_ID'),
140 'EMPTY_INITIATED_BY_USER_ID'
141 );
142 return false;
143 }
144
145 if (isset($relationFields["INITIATED_BY_USER_ID"]))
146 {
147 $res = CUser::GetByID($relationFields["INITIATED_BY_USER_ID"]);
148 if (!$res->fetch())
149 {
150 $APPLICATION->ThrowException(
151 Loc::getMessage('SONET_UG_ERROR_NO_INITIATED_BY_USER_ID'),
152 'ERROR_NO_INITIATED_BY_USER_ID'
153 );
154 return false;
155 }
156 }
157
158 if (
159 isset($relationFields['DATE_CREATE'])
160 && !$DB->IsDate($relationFields['DATE_CREATE'], false, LANG, 'FULL')
161 )
162 {
163 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_CREATE'), 'EMPTY_DATE_CREATE');
164 return false;
165 }
166
167 if (
168 isset($relationFields['DATE_UPDATE'])
169 && !$DB->IsDate($relationFields['DATE_UPDATE'], false, LANG, 'FULL')
170 )
171 {
172 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_UPDATE'), 'EMPTY_DATE_UPDATE');
173 return false;
174 }
175
176 if (
177 isset($relationFields['DATE_LAST_VIEW'])
178 && !$DB->IsDate($relationFields['DATE_LAST_VIEW'], false, LANG, 'FULL')
179 )
180 {
181 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_EMPTY_DATE_LAST_VIEW'), 'EMPTY_DATE_LAST_VIEW');
182 return false;
183 }
184
185 if (
186 (
187 isset($relationFields["SEND_MAIL"])
188 && $relationFields["SEND_MAIL"] !== "N"
189 )
190 || !isset($relationFields['SEND_MAIL'])
191 )
192 {
193 $relationFields["SEND_MAIL"] = "Y";
194 }
195
196 return true;
197 }
198
199 public static function Delete(
200 $id,
201 $sendExclude = false,
202 bool $skipChatMessage = false,
203 bool $skipStatistics = false,
204 bool $delayEvents = false
205 )
206 {
208
209 if (!CSocNetGroup::__ValidateID($id))
210 {
211 return false;
212 }
213
214 $id = (int)$id;
215
216 $relationFields = CSocNetUserToGroup::GetByID($id);
217 if (!$relationFields)
218 {
219 $APPLICATION->ThrowException(Loc::getMessage('SONET_NO_USER2GROUP'), 'ERROR_NO_USER2GROUP');
220 return false;
221 }
222
223 $res = GetModuleEvents("socialnetwork", "OnBeforeSocNetUserToGroupDelete");
224 while ($eventFields = $res->Fetch())
225 {
226 if (ExecuteModuleEventEx($eventFields, array($id)) === false)
227 {
228 return false;
229 }
230 }
231
232 $events = GetModuleEvents("socialnetwork", "OnSocNetUserToGroupDelete");
233 while ($eventFields = $events->Fetch())
234 {
235 if ($delayEvents)
236 {
237 static::delayJob(static fn () => ExecuteModuleEventEx($eventFields, [ $id, $relationFields ]));
238 }
239 else
240 {
241 ExecuteModuleEventEx($eventFields, [ $id, $relationFields ]);
242 }
243 }
244
246 'GROUP_ID' => $relationFields['GROUP_ID'],
247 'USER_ID' => $relationFields['USER_ID'],
248 'ROLE' => $relationFields['ROLE'] ?? null,
249 'INITIATED_BY_TYPE' => $relationFields['INITIATED_BY_TYPE'] ?? null,
250 ]);
251
253 'GROUP_ID' => $relationFields['GROUP_ID'],
254 'USER_ID' => $relationFields['USER_ID'],
255 ]);
256
257 if (Loader::includeModule('im'))
258 {
259 CIMNotify::DeleteByTag("SOCNET|INVITE_GROUP|" . (int)$relationFields['USER_ID'] . "|" . (int)$id);
260 }
261
262 $bSuccess = $DB->Query("DELETE FROM b_sonet_user2group WHERE ID = ".$id."", true);
263
264 if (!$skipStatistics)
265 {
266 CSocNetGroup::SetStat($relationFields["GROUP_ID"]);
267 }
268
269 CSocNetSearch::OnUserRelationsChange($relationFields["USER_ID"]);
270
271 $event = new Event('socialnetwork', 'OnAfterSocNetUserToGroupDelete', $relationFields);
272
273 if ($delayEvents)
274 {
275 static::delayJob(static fn () => $event->send());
276 }
277 else
278 {
279 $event->send();
280 }
281
282 $roleCacheKey = $relationFields['USER_ID'] . '_' . $relationFields['GROUP_ID'];
283 if (isset(self::$roleCache[$roleCacheKey]))
284 {
285 unset(self::$roleCache[$roleCacheKey]);
286 }
287
288 if ($bSuccess && defined("BX_COMP_MANAGED_CACHE"))
289 {
290 $CACHE_MANAGER->ClearByTag("sonet_user2group_G".$relationFields["GROUP_ID"]);
291 $CACHE_MANAGER->ClearByTag("sonet_user2group_U".$relationFields["USER_ID"]);
292 $CACHE_MANAGER->ClearByTag("sonet_user2group");
293 }
294
295 if (
296 $bSuccess
297 && in_array($relationFields['ROLE'], [
300 ], true)
301 )
302 {
303 $chatNotificationResult = false;
304
305 if (!$skipChatMessage && Loader::includeModule('im'))
306 {
307 $chatNotificationResult = UserToGroup::addInfoToChat([
308 'group_id' => $relationFields["GROUP_ID"],
309 'user_id' => $relationFields["USER_ID"],
311 'sendMessage' => $sendExclude,
312 ]);
313
314 if ($sendExclude)
315 {
316 $arMessageFields = [
317 "TO_USER_ID" => $relationFields["USER_ID"],
318 "FROM_USER_ID" => 0,
319 "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
320 "NOTIFY_MODULE" => "socialnetwork",
321 "NOTIFY_EVENT" => "invite_group",
322 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$relationFields["USER_ID"] . "|" . (int)$relationFields["ID"],
323 "NOTIFY_MESSAGE" => fn (?string $languageId = null) => Loc::getMessage(
324 'SONET_UG_EXCLUDE_MESSAGE',
325 ["#NAME#" => $relationFields["GROUP_NAME"]],
326 $languageId
327 ),
328 ];
329
330 CIMNotify::Add($arMessageFields);
331 }
332 }
333
334 if (
335 $sendExclude
336 && !$chatNotificationResult
337 )
338 {
339 CSocNetUserToGroup::notifyImToModerators([
340 "TYPE" => "exclude",
341 "RELATION_ID" => $relationFields["ID"],
342 "USER_ID" => $relationFields["USER_ID"],
343 "GROUP_ID" => $relationFields["GROUP_ID"],
344 "GROUP_NAME" => $relationFields["GROUP_NAME"],
345 "EXCLUDE_USERS" => array($USER->getId()),
346 ]);
347 }
348 }
349
351 'GROUP_ID' => (int)$relationFields['GROUP_ID'],
352 'USER_ID' => (int)$relationFields['USER_ID'],
353 'ROLE' => $relationFields['ROLE'],
354 'INITIATED_BY_TYPE' => ($relationFields['INITIATED_BY_TYPE']),
355 'RELATION_ID' => (int)$relationFields['ID'],
356 ]);
357
358 return $bSuccess;
359 }
360
361 public static function DeleteNoDemand($userId): bool
362 {
363 global $DB;
364
365 if (!CSocNetGroup::__ValidateID($userId))
366 {
367 return false;
368 }
369
370 $userId = (int)$userId;
371 $bSuccess = True;
372
373 $groupIdList = [];
374
375 $res = CSocNetUserToGroup::GetList(array(), array("USER_ID" => $userId), false, false, array("GROUP_ID"));
376 while ($relationFields = $res->fetch())
377 {
378 $groupIdList[] = (int)$relationFields["GROUP_ID"];
379 }
380
381 $DB->Query("DELETE FROM b_sonet_user2group WHERE USER_ID = ".$userId."", true);
382
383 foreach ($groupIdList as $groupId)
384 {
385 CSocNetGroup::SetStat($groupId);
386 }
387
388 self::$roleCache = array();
389
392
393 return $bSuccess;
394 }
395
396 /***************************************/
397 /********** DATA SELECTION ***********/
398 /***************************************/
399 public static function GetById($id)
400 {
401 if (!CSocNetGroup::__ValidateID($id))
402 {
403 return false;
404 }
405
406 $id = (int)$id;
407
408 $res = CSocNetUserToGroup::GetList(
409 [],
410 [ 'ID' => $id ],
411 false,
412 false,
413 [
414 'ID',
415 'ROLE', 'DATE_CREATE', 'DATE_UPDATE', 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID', 'MESSAGE',
416 'USER_ID',
417 'GROUP_ID', 'GROUP_VISIBLE', 'GROUP_NAME',
418 ]
419 );
420 if ($relationFields = $res->fetch())
421 {
422 if (!empty($relationFields['GROUP_NAME']))
423 {
424 $relationFields['GROUP_NAME'] = Emoji::decode(htmlspecialcharsEx($relationFields['GROUP_NAME']));
425 }
426
427 return $relationFields;
428 }
429
430 return false;
431 }
432
433 public static function GetGroupUsers(int $groupId): array
434 {
435 return UserToGroupTable::query()
436 ->setSelect([ 'USER_ID', 'GROUP_ID', 'ROLE', 'AUTO_MEMBER' ])
437 ->where('GROUP_ID', $groupId)
438 ->fetchAll()
439 ;
440 }
441
442 public static function AddUsersToGroup(int $groupId, array $userIds): Main\Result
443 {
444 if (empty($userIds))
445 {
446 return (new Main\Result())->addError(new Main\Error('$userIds is empty'));
447 }
448
449 $users = [];
450 foreach($userIds as $userId)
451 {
452 $users[] = [
453 'USER_ID' => $userId,
454 'GROUP_ID' => $groupId,
456 'DATE_CREATE' => new Main\Type\DateTime(),
457 'DATE_UPDATE' => new Main\Type\DateTime(),
458 'INITIATED_BY_USER_ID' => $userId,
459 ];
460 }
461
462 return UserToGroupTable::addMulti($users, true);
463 }
464
465 public static function addUniqueUsersToGroup(int $groupId, array $userIds): void
466 {
468 $lockName = 'socnet_update_group_users_lock_' . $groupId;
469
470 if (!$connection->lock($lockName, static::LOCK_TIMEOUT))
471 {
472 return;
473 }
474
475 try
476 {
477 $oldUsers = self::GetGroupUsers($groupId);
478 $oldUserIds = array_map('intval', array_column($oldUsers, 'USER_ID'));
479
480 $newUserIds = array_map('intval', $userIds);
481 $usersToAdd = array_diff($newUserIds, $oldUserIds);
483
484 self::AddUsersToGroup($groupId, $usersToAdd);
485 }
486 catch (Throwable)
487 {
488 }
489 finally
490 {
491 $connection->unlock($lockName);
492 }
493 }
494
495 /***************************************/
496 /********** COMMON METHODS ***********/
497 /***************************************/
498 public static function GetUserRole($userId, $groupId, $extendedReturn = false)
499 {
500 $userId = (int)$userId;
501 if ($userId <= 0)
502 {
503 return false;
504 }
505
506 // compatibility?
507 if (isset($_REQUEST['arSocNetUserInRoleCache']))
508 {
509 self::$roleCache = [];
510 }
511
512 if (is_array($groupId))
513 {
514 $result = false;
515
516 $groupIdListToGet = [];
517 foreach ($groupId as $TmpGroupID)
518 {
519 $cacheKey = $userId . '_' . $TmpGroupID;
520 if (!isset(self::$roleCache[$cacheKey]))
521 {
522 $groupIdListToGet[] = $TmpGroupID;
523 }
524 }
525
526 if (count($groupIdListToGet) > 0)
527 {
528 $res = CSocNetUserToGroup::getList(
529 [],
530 [
531 'USER_ID' => $userId,
532 'GROUP_ID' => $groupIdListToGet,
533 ],
534 false,
535 false,
536 [ 'GROUP_ID', 'ROLE', 'AUTO_MEMBER' ]
537 );
538 $arRolesFromDB = [];
539 while ($relationFields = $res->fetch())
540 {
541 $arRolesFromDB[$relationFields["GROUP_ID"]] = [
542 "ROLE" => $relationFields["ROLE"],
543 "AUTO_MEMBER" => $relationFields["AUTO_MEMBER"],
544 ];
545 }
546
547 foreach ($groupIdListToGet as $TmpGroupID)
548 {
549 self::$roleCache[$userId."_".$TmpGroupID] = (
550 array_key_exists($TmpGroupID, $arRolesFromDB)
551 ? [
552 "ROLE" => $arRolesFromDB[$TmpGroupID]["ROLE"],
553 "AUTO_MEMBER" => $arRolesFromDB[$TmpGroupID]["AUTO_MEMBER"],
554 ]
555 : array(
556 "ROLE" => false,
557 "AUTO_MEMBER" => "N"
558 )
559 );
560 }
561 }
562
563 foreach ($groupId as $currentGroupId)
564 {
565 if ($result === false)
566 {
567 $result = [];
568 }
569 $result[$currentGroupId] = (
570 $extendedReturn
571 ? self::$roleCache[$userId . '_' . $currentGroupId]
572 : self::$roleCache[$userId . '_' . $currentGroupId]['ROLE']
573 );
574 }
575
576 return $result;
577 }
578
579 $groupId = (int)$groupId;
580 if ($groupId <= 0)
581 {
582 return false;
583 }
584
585 if (!array_key_exists($userId."_".$groupId, self::$roleCache))
586 {
587 $res = CSocNetUserToGroup::GetList(
588 array(),
589 array("USER_ID" => $userId, "GROUP_ID" => $groupId),
590 false,
591 false,
592 array("ROLE", "AUTO_MEMBER")
593 );
594 if ($relationFields = $res->Fetch())
595 {
596 self::$roleCache[$userId."_".$groupId] = array(
597 "ROLE" => $relationFields["ROLE"],
598 "AUTO_MEMBER" => $relationFields["AUTO_MEMBER"]
599 );
600 }
601 else
602 {
603 self::$roleCache[$userId."_".$groupId] = array(
604 "ROLE" => false,
605 "AUTO_MEMBER" => false
606 );
607 }
608 }
609
610 return (
611 $extendedReturn
612 ? self::$roleCache[$userId."_".$groupId]
613 : self::$roleCache[$userId."_".$groupId]["ROLE"]
614 );
615 }
616
617 /***************************************/
618 /********** SEND EVENTS **************/
619 /***************************************/
620 public static function SendEvent($userGroupID, $mailTemplate = "SONET_INVITE_GROUP"): bool
621 {
622 $userGroupID = (int)$userGroupID;
623 if ($userGroupID <= 0)
624 {
625 return false;
626 }
627
628 $dbRelation = CSocNetUserToGroup::GetList(
629 [],
630 [ 'ID' => $userGroupID ],
631 false,
632 false,
633 [
634 'ID',
635 'ROLE', 'DATE_CREATE', 'MESSAGE', 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID',
636 'USER_ID', 'USER_NAME', 'USER_LAST_NAME', 'USER_EMAIL', 'USER_LID',
637 'GROUP_ID', 'GROUP_NAME',
638 ]
639 );
640 $arRelation = $dbRelation->Fetch();
641 if (!$arRelation)
642 {
643 return false;
644 }
645
646 $arUserGroup = array();
647
648 if (Loader::includeModule('extranet'))
649 {
650 $arUserGroup = CUser::GetUserGroup($arRelation["USER_ID"]);
651 }
652
653 $bExtranetInstalled = ModuleManager::isModuleInstalled('extranet');
654 $siteId = false;
655
656 $rsGroupSite = CSocNetGroup::GetSite($arRelation["GROUP_ID"]);
657 while ($arGroupSite = $rsGroupSite->Fetch())
658 {
659 if ($bExtranetInstalled)
660 {
661 if (
662 (
663 CExtranet::IsExtranetSite($arGroupSite["LID"])
664 && in_array(CExtranet::GetExtranetUserGroupID(), $arUserGroup)
665 )
666 ||
667 (
668 !CExtranet::IsExtranetSite($arGroupSite["LID"])
669 && !in_array(CExtranet::GetExtranetUserGroupID(), $arUserGroup)
670 )
671 )
672 {
673 $siteId = $arGroupSite["LID"];
674 break;
675 }
676 }
677 else
678 {
679 $siteId = $arGroupSite["LID"];
680 break;
681 }
682 }
683
684 if (empty($siteId))
685 {
686 return false;
687 }
688
689 $requestsPagePath = str_replace(
690 "#USER_ID#",
691 $arRelation["USER_ID"],
692 Option::get(
693 "socialnetwork",
694 "user_request_page",
695 (
697 ? "/company/personal/user/#USER_ID#/requests/"
698 : "/club/user/#USER_ID#/requests/"
699 ),
700 $siteId
701 )
702 );
703
704 $arUserInitiatedForEmail = array("NAME"=>"", "LAST_NAME"=>"");
705
706 if ((int)$arRelation["INITIATED_BY_USER_ID"] > 0):
707
708 $dbUserInitiated = CUser::GetList(
709 "id",
710 "desc",
711 array("ID" => $arRelation["INITIATED_BY_USER_ID"])
712 );
713
714 if ($arUserInitiated = $dbUserInitiated->Fetch())
715 {
716 $arUserInitiatedForEmail = [
717 'NAME' => $arUserInitiated['NAME'],
718 'LAST_NAME' => $arUserInitiated['LAST_NAME'],
719 ];
720 }
721
722 endif;
723
725 "RELATION_ID" => $userGroupID,
726 "URL" => $requestsPagePath,
727 "GROUP_ID" => $arRelation["GROUP_ID"],
728 "USER_ID" => $arRelation["USER_ID"],
729 "GROUP_NAME" => Emoji::decode($arRelation["GROUP_NAME"]),
730 "USER_NAME" => $arRelation["USER_NAME"],
731 "USER_LAST_NAME" => $arRelation["USER_LAST_NAME"],
732 "USER_EMAIL" => $arRelation["USER_EMAIL"],
733 "INITIATED_USER_NAME" => $arUserInitiatedForEmail["NAME"],
734 "INITIATED_USER_LAST_NAME" => $arUserInitiatedForEmail["LAST_NAME"],
735 "MESSAGE" => $arRelation["MESSAGE"]
736 );
737
738 CEvent::Send($mailTemplate, $siteId, $arFields, "N");
739
740 return true;
741 }
742
743 /***************************************/
744 /************ ACTIONS ****************/
745 /***************************************/
746 public static function SendRequestToBeMember($userId, $groupId, $message, $requestConfirmUrl = "", $autoSubscribe = true): bool
747 {
748 global $APPLICATION;
749
750 $userId = (int)$userId;
751 if ($userId <= 0)
752 {
753 $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), 'ERROR_USERID');
754 return false;
755 }
756
757 $groupId = (int)$groupId;
758 if ($groupId <= 0)
759 {
760 $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_GROUPID'), 'ERROR_GROUPID');
761 return false;
762 }
763
764 $groupFields = WorkgroupTable::getList([
765 'select' => [
766 'ACTIVE',
767 'OPENED',
768 'NAME',
769 'INITIATE_PERMS',
770 'SITE_ID',
771 ],
772 'filter' => ['ID' => $groupId],
773 ])->fetch();
774 if (
775 !$groupFields
776 || !is_array($groupFields)
777 || $groupFields["ACTIVE"] !== "Y"
778 /* || $arGroup["VISIBLE"] != "Y"*/)
779 {
780 $APPLICATION->ThrowException(Loc::getMessage('SONET_UG_ERROR_NO_GROUP_ID'), 'ERROR_NO_GROUP');
781 return false;
782 }
783
784 $relationFields = [
785 "USER_ID" => $userId,
786 "GROUP_ID" => $groupId,
788 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
789 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
790 "MESSAGE" => $message,
791 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER,
792 "INITIATED_BY_USER_ID" => $userId
793 ];
794 if ($groupFields["OPENED"] === "Y")
795 {
796 $relationFields["ROLE"] = UserToGroupTable::ROLE_USER;
797 }
798
799 $ID = CSocNetUserToGroup::Add($relationFields);
800 if (!$ID)
801 {
802 $errorMessage = "";
803 if ($e = $APPLICATION->GetException())
804 {
805 $errorMessage = $e->GetString();
806 }
807 if ($errorMessage === '')
808 {
809 $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP");
810 }
811
812 $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_USER2GROUP");
813 return false;
814 }
815
817 'groupId' => $groupId,
818 'userId' => $userId,
819 ]);
820
821 if ($groupFields["OPENED"] === "Y")
822 {
823 if ($autoSubscribe)
824 {
826 }
827
829 {
830 $chatNotificationResult = UserToGroup::addInfoToChat([
831 'group_id' => $groupId,
832 'user_id' => $userId,
833 'action' => UserToGroup::CHAT_ACTION_IN,
834 'role' => $relationFields['ROLE'],
835 ]);
836
837 if (!$chatNotificationResult)
838 {
839 CSocNetUserToGroup::notifyImToModerators([
840 "TYPE" => "join",
841 "RELATION_ID" => $ID,
842 "USER_ID" => $userId,
843 "GROUP_ID" => $groupId,
844 "GROUP_NAME" => $groupFields["NAME"],
845 ]);
846 }
847 }
848 }
849 elseif (
850 trim($requestConfirmUrl) !== ''
851 && Loader::includeModule('im')
852 )
853 {
854 static $serverName;
855 if (!$serverName)
856 {
857 $dbSite = CSite::GetByID(SITE_ID);
858 $arSite = $dbSite->Fetch();
859 $serverName = htmlspecialcharsEx($arSite["SERVER_NAME"]);
860 if ($serverName === '')
861 {
862 if (defined("SITE_SERVER_NAME") && SITE_SERVER_NAME !== '')
863 {
864 $serverName = SITE_SERVER_NAME;
865 }
866 else
867 {
868 $serverName = Option::get("main", "server_name");
869 }
870
871 if ($serverName === '')
872 {
873 $serverName = $_SERVER["SERVER_NAME"];
874 }
875 }
876 $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".$serverName;
877 }
878
879 // send sonet system messages to owner and (may be) moderators to accept or refuse request
880 $FilterRole = (
881 $groupFields['INITIATE_PERMS'] === UserToGroupTable::ROLE_OWNER
884 );
885
886 $res = CSocNetUserToGroup::GetList(
887 array("USER_ID" => "ASC"),
888 array(
889 "GROUP_ID" => $groupId,
890 "<=ROLE" => $FilterRole,
891 "USER_ACTIVE" => "Y"
892 ),
893 false,
894 false,
895 array("ID", "USER_ID", "USER_NAME", "USER_LAST_NAME", "USER_EMAIL")
896 );
897 if ($res)
898 {
899 $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false);
900 $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID);
901 $groupUrlTemplate = Path::get('group_path_template');
902 $groupUrlTemplate = "#GROUPS_PATH#" . mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
903 $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate);
904
905 while ($recipientRelationFields = $res->fetch())
906 {
908 [
909 "GROUP_URL" => $groupUrl,
910 ],
911 $recipientRelationFields["USER_ID"],
912 $groupSiteId
913 );
914 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
915 $domainName = (
916 mb_strpos($groupUrl, "http://") === 0
917 || mb_strpos($groupUrl, "https://") === 0
918 ? ""
919 : (
920 isset($arTmp["DOMAIN"])
921 && !empty($arTmp["DOMAIN"])
922 ? "//".$arTmp["DOMAIN"]
923 : ""
924 )
925 );
926
928 "TO_USER_ID" => $recipientRelationFields["USER_ID"],
929 "FROM_USER_ID" => $userId,
930 "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM,
931 "NOTIFY_MODULE" => "socialnetwork",
932 "NOTIFY_EVENT" => "invite_group_btn",
933 "NOTIFY_TAG" => "SOCNET|REQUEST_GROUP|" . $userId . "|" . $groupId . "|" . $ID . "|" . $recipientRelationFields["USER_ID"],
934 "NOTIFY_SUB_TAG" => "SOCNET|REQUEST_GROUP|" . $userId."|" . $groupId . "|" . $ID,
935 "NOTIFY_TITLE" => str_replace(
936 "#GROUP_NAME#",
937 truncateText($groupFields["NAME"], 150),
938 Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY')
939 ),
940 "NOTIFY_MESSAGE" => fn (?string $languageId = null) => str_replace(
941 [
942 "#TEXT#",
943 "#GROUP_NAME#",
944 ],
945 [
946 $message,
947 "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"
948 ],
949 (empty($message)
950 ? Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY', null, $languageId)
951 : Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT', null, $languageId)
952 )
953 ),
954 "NOTIFY_BUTTONS" => [
955 [
956 "TITLE" => Loc::getMessage('SONET_UG_REQUEST_CONFIRM'),
957 "VALUE" => "Y",
958 "TYPE" => "accept",
959 ],
960 [
961 "TITLE" => Loc::getMessage('SONET_UG_REQUEST_REJECT'),
962 "VALUE" => "N",
963 "TYPE" => "cancel",
964 ],
965 ],
966 );
967
968 $groupUrl = $serverName.str_replace("#group_id#", $groupId, Path::get('group_path_template'));
969
970 $messageFields["NOTIFY_MESSAGE_OUT"] = fn (?string $languageId = null) => str_replace(
971 [
972 "#TEXT#",
973 "#GROUP_NAME#",
974 ],
975 [
976 $message,
977 "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"
978 ],
979 (empty($message)
980 ? Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT_EMPTY', null, $languageId)
981 : Loc::getMessage('SONET_UG_REQUEST_CONFIRM_TEXT', null, $languageId)
982 )
983 )
984 . "\n\n".Loc::getMessage("SONET_UG_GROUP_LINK", null, $languageId).$groupUrl
985 . "\n\n".Loc::getMessage("SONET_UG_REQUEST_CONFIRM_REJECT", null, $languageId).": ".$requestConfirmUrl
986 ;
987
988 CIMNotify::Add($messageFields);
989 }
990 }
991 }
992
993 return true;
994 }
995
996 public static function SendRequestToJoinGroup($senderUserId, $userId, $groupId, $message, $sendMail = true): bool
997 {
998 global $APPLICATION, $USER;
999
1000 $senderUserId = (int)$senderUserId;
1001 if ($senderUserId <= 0)
1002 {
1003 $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), "ERROR_SENDERID");
1004 return false;
1005 }
1006
1007 $userId = (int)$userId;
1008 if ($userId <= 0)
1009 {
1010 $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
1011 return false;
1012 }
1013
1014 $groupId = (int)$groupId;
1015 if ($groupId <= 0)
1016 {
1017 $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
1018 return false;
1019 }
1020
1021 $groupFields = WorkgroupTable::getList([
1022 'select' => [
1023 'NAME',
1024 'INITIATE_PERMS',
1025 'OWNER_ID',
1026 ],
1027 'filter' => ['ID' => $groupId],
1028 ])->fetch();
1029 if (!$groupFields || !is_array($groupFields))
1030 {
1031 $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
1032 return false;
1033 }
1034
1035 $arGroupSites = array();
1036 $rsGroupSite = CSocNetGroup::GetSite($groupId);
1037 while ($arGroupSite = $rsGroupSite->Fetch())
1038 {
1039 $arGroupSites[] = $arGroupSite["LID"];
1040 }
1041
1042 $userRole = CSocNetUserToGroup::GetUserRole($senderUserId, $groupId);
1043 $userIsMember = ($userRole && in_array($userRole, UserToGroupTable::getRolesMember(), true));
1044 $canInitiate = (
1045 $USER->IsAdmin()
1046 || CSocNetUser::IsCurrentUserModuleAdmin($arGroupSites)
1047 || (
1048 $userRole
1049 && (
1050 (
1051 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER
1052 && $senderUserId === (int)$groupFields["OWNER_ID"]
1053 )
1054 || (
1055 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR
1056 && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true)
1057 )
1058 || (
1059 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER
1060 && $userIsMember
1061 )
1062 )
1063 )
1064 );
1065
1066 if (!$canInitiate)
1067 {
1068 $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS");
1069 return false;
1070 }
1071
1072 $relationFields = array(
1073 "USER_ID" => $userId,
1074 "GROUP_ID" => $groupId,
1076 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
1077 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
1078 "MESSAGE" => str_replace(
1079 [ "#TEXT#", "#GROUP_NAME#" ],
1080 [ $message, $groupFields["NAME"] ],
1081 (
1082 empty($message)
1083 ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY")
1084 : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT")
1085 )
1086 ),
1087 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP,
1088 "INITIATED_BY_USER_ID" => $senderUserId,
1089 "SEND_MAIL" => ($sendMail ? "Y" : "N")
1090 );
1091 $relationId = CSocNetUserToGroup::Add($relationFields);
1092 if (!$relationId)
1093 {
1094 $errorMessage = "";
1095 if ($e = $APPLICATION->GetException())
1096 {
1097 $errorMessage = $e->GetString();
1098 }
1099
1100 if ($errorMessage === '')
1101 {
1102 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
1103 }
1104
1105 $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_USER2GROUP");
1106 return false;
1107 }
1108
1109 $userIsConfirmed = true;
1110
1111 $rsInvitedUser = CUser::getList(
1112 'ID',
1113 'ASC',
1114 ['ID' => $userId],
1115 [
1116 'FIELDS' => [
1117 'ID',
1118 'LAST_LOGIN',
1119 'LAST_ACTIVITY_DATE',
1120 'UF_DEPARTMENT',
1121 ],
1122 'SELECT' => ['UF_DEPARTMENT'],
1123 ]
1124 );
1125 $arInvitedUser = $rsInvitedUser->Fetch();
1126
1127 if (
1128 (
1129 !is_array($arInvitedUser["UF_DEPARTMENT"])
1130 || (int) ($arInvitedUser["UF_DEPARTMENT"][0] ?? null) <= 0
1131 ) // extranet
1132 && ($arInvitedUser["LAST_LOGIN"] <= 0)
1133 && $arInvitedUser["LAST_ACTIVITY_DATE"] == ''
1134 )
1135 {
1136 $userIsConfirmed = false;
1137 }
1138
1139 if (
1140 $userIsConfirmed
1141 && Loader::includeModule('im')
1142 )
1143 {
1144 $messageFields = [
1145 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
1146 "TO_USER_ID" => (int)$relationFields['USER_ID'],
1147 "FROM_USER_ID" => (int)$relationFields['INITIATED_BY_USER_ID'],
1148 "NOTIFY_TYPE" => IM_NOTIFY_CONFIRM,
1149 "NOTIFY_MODULE" => "socialnetwork",
1150 "NOTIFY_EVENT" => "invite_group_btn",
1151 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . $userId . "|" . $relationId,
1152 "NOTIFY_TITLE" => fn (?string $languageId = null) => str_replace(
1153 "#GROUP_NAME#",
1154 truncateText($groupFields["NAME"], 150),
1155 Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId)
1156 ),
1157 "NOTIFY_MESSAGE" => fn (?string $languageId = null) => str_replace(
1158 [ "#TEXT#", "#GROUP_NAME#" ],
1159 [ $message, $groupFields["NAME"] ],
1160 (
1161 empty($message)
1162 ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId)
1163 : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT", null, $languageId)
1164 )
1165 ),
1166 "NOTIFY_BUTTONS" => [
1167 [
1168 'TITLE' => Loc::getMessage('SONET_UG_INVITE_CONFIRM'),
1169 'VALUE' => 'Y',
1170 'TYPE' => 'accept',
1171 ],
1172 [
1173 'TITLE' => Loc::getMessage('SONET_UG_INVITE_REJECT'),
1174 'VALUE' => 'N',
1175 'TYPE' => 'cancel',
1176 ],
1177 ],
1178 ];
1179
1180 $siteId = (
1181 (
1182 !is_array($arInvitedUser["UF_DEPARTMENT"])
1183 || (int)$arInvitedUser["UF_DEPARTMENT"][0] <= 0
1184 )
1185 && Loader::includeModule('extranet')
1186 ? CExtranet::GetExtranetSiteID()
1187 : SITE_ID
1188 );
1189
1190 $dbSite = CSite::GetByID($siteId);
1191 $arSite = $dbSite->Fetch();
1192 $serverName = htmlspecialcharsEx($arSite["SERVER_NAME"]);
1193
1194 if (!$serverName)
1195 {
1196 $serverName = (
1197 defined("SITE_SERVER_NAME")
1198 && SITE_SERVER_NAME !== ''
1199 ? SITE_SERVER_NAME
1200 : Option::get('main', 'server_name')
1201 );
1202 }
1203
1204 if (!$serverName)
1205 {
1206 $serverName = $_SERVER["SERVER_NAME"];
1207 }
1208
1209 $serverName = (CMain::IsHTTPS() ? "https" : "http")."://".$serverName;
1210
1211 $requestUrl = Option::get(
1212 "socialnetwork",
1213 "user_request_page",
1214 (
1216 ? "/company/personal/user/#USER_ID#/requests/"
1217 : "/club/user/#USER_ID#/requests/"
1218 ),
1219 $siteId
1220 );
1221
1222 $requestUrl = $serverName.str_replace(array("#USER_ID#", "#user_id#"), $userId, $requestUrl);
1223 $groupUrl = $serverName.str_replace("#group_id#", $groupId, Path::get('group_path_template', $siteId));
1224
1225 $messageFields['NOTIFY_MESSAGE_OUT'] = fn (?string $languageId = null) =>
1226 str_replace(
1227 [ "#TEXT#", "#GROUP_NAME#" ],
1228 [ $message, $groupFields["NAME"] ],
1229 (
1230 empty($message)
1231 ? Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT_EMPTY", null, $languageId)
1232 : Loc::getMessage("SONET_UG_INVITE_CONFIRM_TEXT", null, $languageId)
1233 )
1234 )
1235 . "\n\n" . Loc::getMessage('SONET_UG_GROUP_LINK', null, $languageId) . $groupUrl
1236 . "\n\n" . Loc::getMessage('SONET_UG_INVITE_CONFIRM', null, $languageId) . ": " . $requestUrl . '?INVITE_GROUP=' . $relationId . '&CONFIRM=Y'
1237 . "\n\n" . Loc::getMessage('SONET_UG_INVITE_REJECT', null, $languageId) . ": " . $requestUrl . '?INVITE_GROUP=' . $relationId . '&CONFIRM=N'
1238 ;
1239
1240 CIMNotify::Add($messageFields);
1241 }
1242
1243 $events = GetModuleEvents("socialnetwork", "OnSocNetSendRequestToJoinGroup");
1244 while ($arEvent = $events->Fetch())
1245 {
1246 ExecuteModuleEventEx($arEvent, [ $relationId, $relationFields ]);
1247 }
1248
1250
1251 return true;
1252 }
1253
1254 public static function ConfirmRequestToBeMember($userId, $groupId, $relationIdList, $autoSubscribe = true): bool // request from a user confirmed by a moderator
1255 {
1256 global $APPLICATION, $USER;
1257
1258 $userId = (int)$userId;
1259 if ($userId <= 0)
1260 {
1261 $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
1262 return false;
1263 }
1264
1265 $groupId = (int)$groupId;
1266 if ($groupId <= 0)
1267 {
1268 $APPLICATION->ThrowException(Loc::getMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
1269 return false;
1270 }
1271
1272 if (!is_array($relationIdList))
1273 {
1274 return true;
1275 }
1276
1277 $arGroup = CSocNetGroup::getById($groupId);
1278 if (!$arGroup || !is_array($arGroup))
1279 {
1280 $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
1281 return false;
1282 }
1283
1284 $groupSiteIdList = array();
1285 $res = CSocNetGroup::GetSite($groupId);
1286 while ($groupSiteFields = $res->fetch())
1287 {
1288 $groupSiteIdList[] = $groupSiteFields["LID"];
1289 }
1290
1291 $userRole = CSocNetUserToGroup::GetUserRole($userId, $groupId);
1292 $userIsMember = (
1293 $userRole
1294 && in_array($userRole, UserToGroupTable::getRolesMember(), true)
1295 );
1296 $canInitiate = (
1297 $USER->IsAdmin()
1298 || CSocNetUser::IsCurrentUserModuleAdmin($groupSiteIdList)
1299 || (
1300 $userRole
1301 && (
1302 (
1303 $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER
1304 && $userId === (int)$arGroup["OWNER_ID"]
1305 )
1306 || (
1307 $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR
1308 && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true)
1309 )
1310 || (
1311 $arGroup["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER
1312 && $userIsMember
1313 )
1314 )
1315 )
1316 );
1317
1318 if (!$canInitiate)
1319 {
1320 $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS");
1321 return false;
1322 }
1323
1324 $bSuccess = true;
1325 $arSuccessRelations = array();
1326 $chatNotificationResult = false;
1327
1328 foreach ($relationIdList as $relationId)
1329 {
1330 $relationId = (int)$relationId;
1331 if ($relationId <= 0)
1332 {
1333 continue;
1334 }
1335
1336 $relationFields = CSocNetUserToGroup::GetByID($relationId);
1337 if (!$relationFields)
1338 {
1339 continue;
1340 }
1341
1342 if (
1343 (int)$relationFields["GROUP_ID"] !== $groupId
1344 || $relationFields["INITIATED_BY_TYPE"] !== SONET_INITIATED_BY_USER
1345 || $relationFields["ROLE"] !== UserToGroupTable::ROLE_REQUEST
1346 )
1347 {
1348 continue;
1349 }
1350
1351 $arFields = array(
1353 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
1354 );
1355 if (CSocNetUserToGroup::Update($relationFields["ID"], $arFields))
1356 {
1357 $arSuccessRelations[] = $relationFields;
1358
1359 if ($autoSubscribe)
1360 {
1361 CSocNetLogEvents::AutoSubscribe($relationFields["USER_ID"], SONET_ENTITY_GROUP, $groupId);
1362 }
1363
1364 $chatNotificationResult = UserToGroup::addInfoToChat([
1365 'group_id' => $groupId,
1366 'user_id' => $relationFields["USER_ID"],
1367 'action' => UserToGroup::CHAT_ACTION_IN,
1368 'role' => $arFields['ROLE'],
1369 ]);
1370
1371 if (
1372 !$chatNotificationResult
1373 && Loader::includeModule('im')
1374 )
1375 {
1376 $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $arGroup["SITE_ID"]);
1377 $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID);
1378 $groupUrlTemplate = Path::get('group_path_template');
1379 $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
1381 array(
1382 "GROUP_URL" => str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate)
1383 ),
1384 $relationFields["USER_ID"],
1385 $groupSiteId
1386 );
1387 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
1388
1389 $serverName = (
1390 mb_strpos($groupUrl, "http://") === 0
1391 || mb_strpos($groupUrl, "https://") === 0
1392 ? ""
1393 : $arTmp["SERVER_NAME"]
1394 );
1395 $domainName = (
1396 mb_strpos($groupUrl, "http://") === 0
1397 || mb_strpos($groupUrl, "https://") === 0
1398 ? ""
1399 : (
1400 isset($arTmp["DOMAIN"])
1401 && !empty($arTmp["DOMAIN"])
1402 ? "//".$arTmp["DOMAIN"]
1403 : ""
1404 )
1405 );
1406
1407 $arMessageFields = array(
1408 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
1409 "TO_USER_ID" => $relationFields["USER_ID"],
1410 "FROM_USER_ID" => $userId,
1411 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
1412 "NOTIFY_MODULE" => "socialnetwork",
1413 "NOTIFY_EVENT" => "invite_group",
1414 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$relationFields["USER_ID"] . "|" . (int)$relationFields["ID"],
1415 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
1416 Loc::getMessage(
1417 "SONET_UG_CONFIRM_MEMBER_MESSAGE_G",
1418 ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$arGroup["NAME"]."</a>"],
1419 $languageId
1420 )
1421 ,
1422 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
1423 Loc::getMessage(
1424 "SONET_UG_CONFIRM_MEMBER_MESSAGE_G",
1425 ['#NAME#' => $arGroup['NAME']],
1426 $languageId
1427 )
1428 . " (".$serverName.$groupUrl.")"
1429 );
1430
1431 CIMNotify::DeleteBySubTag("SOCNET|REQUEST_GROUP|".$relationFields["USER_ID"]."|".$relationFields["GROUP_ID"]."|".$relationFields["ID"]);
1432 CIMNotify::Add($arMessageFields);
1433 }
1434
1435 if (Loader::includeModule('pull'))
1436 {
1437 \Bitrix\Pull\Event::add((int)$relationFields['USER_ID'], [
1438 'module_id' => 'socialnetwork',
1439 'command' => 'workgroup_request_accepted',
1440 'params' => [
1441 'initiatedByType' => $relationFields['INITIATED_BY_TYPE'],
1442 ],
1443 ]);
1444 }
1445
1447 'groupId' => (int)$relationFields['GROUP_ID'],
1448 'userId' => (int)$relationFields['USER_ID'],
1449 ]);
1450 }
1451 else
1452 {
1453 $errorMessage = "";
1454 if ($e = $APPLICATION->GetException())
1455 {
1456 $errorMessage = $e->GetString();
1457 }
1458
1459 if ($errorMessage === '')
1460 {
1461 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
1462 }
1463
1464 $APPLICATION->ThrowException($errorMessage, "ERROR_CONFIRM_MEMBER");
1465 $bSuccess = false;
1466 }
1467 }
1468
1469 if (
1470 !empty($arSuccessRelations)
1471 && !$chatNotificationResult
1472 )
1473 {
1474 foreach ($arSuccessRelations as $arRel)
1475 {
1476 CSocNetUserToGroup::notifyImToModerators(array(
1477 "TYPE" => "join",
1478 "RELATION_ID" => $arRel["ID"],
1479 "USER_ID" => $arRel["USER_ID"],
1480 "GROUP_ID" => $arRel["GROUP_ID"],
1481 "GROUP_NAME" => $arRel["GROUP_NAME"],
1482 "EXCLUDE_USERS" => array($USER->GetID())
1483 ));
1484 }
1485 }
1486
1487 return $bSuccess;
1488 }
1489
1490 public static function RejectRequestToBeMember($userId, $groupId, $relationIdList): bool
1491 {
1492 global $APPLICATION, $USER;
1493
1494 $userId = (int)$userId;
1495 if ($userId <= 0)
1496 {
1497 $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_USERID'), "ERROR_USERID");
1498 return false;
1499 }
1500
1501 $groupId = (int)$groupId;
1502 if ($groupId <= 0)
1503 {
1504 $APPLICATION->ThrowException(Loc::getMessage('SONET_UR_EMPTY_GROUPID'), "ERROR_GROUPID");
1505 return false;
1506 }
1507
1508 if (!is_array($relationIdList))
1509 {
1510 return true;
1511 }
1512
1513 $groupFields = WorkgroupTable::getList([
1514 'select' => [
1515 'NAME',
1516 'INITIATE_PERMS',
1517 'OWNER_ID',
1518 ],
1519 'filter' => ['ID' => $groupId],
1520 ])->fetch();
1521 if (!$groupFields || !is_array($groupFields))
1522 {
1523 $APPLICATION->ThrowException(Loc::getMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
1524 return false;
1525 }
1526
1527 $groupSiteIdList = [];
1528 $rsGroupSite = CSocNetGroup::GetSite($groupId);
1529 while ($groupSiteFields = $rsGroupSite->fetch())
1530 {
1531 $groupSiteIdList[] = $groupSiteFields["LID"];
1532 }
1533
1534 $userRole = CSocNetUserToGroup::GetUserRole($userId, $groupId);
1535 $userIsMember = ($userRole && in_array($userRole, UserToGroupTable::getRolesMember(), true));
1536 $bCanInitiate = (
1537 $USER->IsAdmin()
1538 || CSocNetUser::IsCurrentUserModuleAdmin($groupSiteIdList)
1539 || (
1540 $userRole
1541 && (
1542 (
1543 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_OWNER
1544 && $userId === (int)$groupFields["OWNER_ID"]
1545 )
1546 || (
1547 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_MODERATOR
1548 && in_array($userRole, [ UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR ], true)
1549 )
1550 || (
1551 $groupFields["INITIATE_PERMS"] === UserToGroupTable::ROLE_USER
1552 && $userIsMember
1553 )
1554 )
1555 )
1556 );
1557
1558 if (!$bCanInitiate)
1559 {
1560 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS");
1561 return false;
1562 }
1563
1564 $bSuccess = true;
1565 foreach ($relationIdList as $relationId)
1566 {
1567 $relationId = (int)$relationId;
1568 if ($relationId <= 0)
1569 {
1570 continue;
1571 }
1572
1573 $arRelation = CSocNetUserToGroup::GetByID($relationId);
1574 if (!$arRelation)
1575 {
1576 continue;
1577 }
1578
1579 if (
1580 (int)$arRelation["GROUP_ID"] !== $groupId
1581 || $arRelation["INITIATED_BY_TYPE"] !== SONET_INITIATED_BY_USER
1582 || $arRelation["ROLE"] !== UserToGroupTable::ROLE_REQUEST
1583 )
1584 {
1585 continue;
1586 }
1587
1588 if (CSocNetUserToGroup::Delete($arRelation["ID"]))
1589 {
1590 $arMessageFields = array(
1591 "FROM_USER_ID" => $userId,
1592 "TO_USER_ID" => $arRelation["USER_ID"],
1593 "MESSAGE" => fn (?string $languageId = null) =>
1594 Loc::getMessage(
1595 'SONET_UG_REJECT_MEMBER_MESSAGE_G',
1596 [
1597 '#NAME#' => $groupFields['NAME']
1598 ],
1599 $languageId
1600 )
1601 ,
1602 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
1603 "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM
1604 );
1605 CSocNetMessages::Add($arMessageFields);
1606
1608 'groupId' => (int)$groupId,
1609 'userId' => (int)$arRelation['USER_ID'],
1610 ]);
1611 }
1612 else
1613 {
1614 $errorMessage = "";
1615 if ($e = $APPLICATION->GetException())
1616 {
1617 $errorMessage = $e->GetString();
1618 }
1619 if ($errorMessage === '')
1620 {
1621 $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP");
1622 }
1623
1624 $APPLICATION->ThrowException($errorMessage, "ERROR_CONFIRM_MEMBER");
1625 $bSuccess = false;
1626 }
1627 }
1628
1629 return $bSuccess;
1630 }
1631
1632 public static function UserConfirmRequestToBeMember($targetUserID, $relationID, $bAutoSubscribe = true): bool // request from group confirmed by a user
1633 {
1634 global $APPLICATION;
1635
1636 $targetUserID = (int)$targetUserID;
1637 if ($targetUserID <= 0)
1638 {
1639 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_SENDER_USER_ID");
1640 return false;
1641 }
1642
1643 $relationID = (int)$relationID;
1644 if ($relationID <= 0)
1645 {
1646 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_RELATIONID"), "ERROR_RELATION_ID");
1647 return false;
1648 }
1649
1650 $dbResult = CSocNetUserToGroup::GetList(
1651 array(),
1652 array(
1653 "ID" => $relationID,
1654 "USER_ID" => $targetUserID,
1656 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP
1657 ),
1658 false,
1659 false,
1660 array("ID", "USER_ID", "INITIATED_BY_USER_ID", "GROUP_ID", "GROUP_VISIBLE", "GROUP_SITE_ID", "GROUP_NAME")
1661 );
1662
1663 if ($arResult = $dbResult->Fetch())
1664 {
1665 if (!empty($arResult['GROUP_NAME']))
1666 {
1667 $arResult['GROUP_NAME'] = Emoji::decode($arResult['GROUP_NAME']);
1668 }
1669
1670 $arFields = array(
1672 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
1673 );
1674 if (CSocNetUserToGroup::Update($arResult["ID"], $arFields))
1675 {
1676 $events = GetModuleEvents("socialnetwork", "OnSocNetUserConfirmRequestToBeMember");
1677 while ($arEvent = $events->Fetch())
1678 {
1679 ExecuteModuleEventEx($arEvent, array($arResult["ID"], $arResult));
1680 }
1681
1682 $moderators = UserToGroupTable::getGroupModerators((int)$arResult['GROUP_ID']);
1685 [
1686 'GROUP_ID' => (int)$arResult['GROUP_ID'],
1687 'RECEPIENTS' => array_map(function ($row) { return $row['USER_ID']; }, $moderators),
1688 ]
1689 );
1690
1691 if ($bAutoSubscribe)
1692 {
1694 }
1695
1696 if (Loader::includeModule('im'))
1697 {
1698 $groupSiteId = CSocNetGroup::GetDefaultSiteId($arResult["GROUP_ID"], $arResult["GROUP_SITE_ID"]);
1699
1700 CIMNotify::DeleteByTag("SOCNET|INVITE_GROUP|" . (int)$targetUserID . "|" . (int)$relationID);
1701
1702 $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId);
1703 $groupUrlTemplate = Path::get('group_path_template', $groupSiteId);
1704 $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
1705 $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $arResult["GROUP_ID"], $groupUrlTemplate);
1706
1708 array(
1709 "GROUP_URL" => $groupUrl
1710 ),
1711 $arResult["INITIATED_BY_USER_ID"],
1712 $groupSiteId
1713 );
1714 $url = $arTmp["URLS"]["GROUP_URL"];
1715 $serverName = (
1716 mb_strpos($url, "http://") === 0
1717 || mb_strpos($url, "https://") === 0
1718 ? ""
1719 : $arTmp["SERVER_NAME"]
1720 );
1721 $domainName = (
1722 mb_strpos($url, "http://") === 0
1723 || mb_strpos($url, "https://") === 0
1724 ? ""
1725 : (
1726 isset($arTmp["DOMAIN"])
1727 && !empty($arTmp["DOMAIN"])
1728 ? "//".$arTmp["DOMAIN"]
1729 : ""
1730 )
1731 );
1732
1733 $arMessageFields = array(
1734 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
1735 "TO_USER_ID" => $arResult['USER_ID'],
1736 "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
1737 "NOTIFY_MODULE" => "socialnetwork",
1738 "NOTIFY_EVENT" => "invite_group",
1739 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . (int)$arResult['USER_ID'] . "|". $relationID,
1740 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
1741 Loc::getMessage(
1742 "SONET_UG_CONFIRM_MEMBER_MESSAGE_G",
1743 ['#NAME#' => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"],
1744 $languageId
1745 )
1746 ,
1747 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
1748 Loc::getMessage(
1749 "SONET_UG_CONFIRM_MEMBER_MESSAGE_G",
1750 ['#NAME#' => $arResult['GROUP_NAME']],
1751 $languageId
1752 )
1753 . " (".$serverName.$url.")"
1754 ,
1755 );
1756 CIMNotify::Add($arMessageFields);
1757
1758 $collab = CollabRegistry::getInstance()->get($arResult["GROUP_ID"]);
1759 if ($collab !== null)
1760 {
1761 $senderId = (int)$arResult["USER_ID"];
1762 $chatNotificationResult = ActionMessageFactory::getInstance()
1763 ->getActionMessage(ActionType::AcceptUser, $collab->getId(), $senderId)
1764 ->send();
1765 }
1766 else
1767 {
1768 $chatNotificationResult = UserToGroup::addInfoToChat([
1769 'group_id' => $arResult["GROUP_ID"],
1770 'user_id' => $arResult["USER_ID"],
1771 'action' => UserToGroup::CHAT_ACTION_IN,
1772 'role' => $arFields['ROLE'],
1773 ]);
1774 }
1775
1776 if (!$chatNotificationResult)
1777 {
1778 $arMessageFields = array(
1779 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
1780 "TO_USER_ID" => $arResult["INITIATED_BY_USER_ID"],
1781 "FROM_USER_ID" => $arResult['USER_ID'],
1782 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
1783 "NOTIFY_MODULE" => "socialnetwork",
1784 "NOTIFY_EVENT" => "invite_group",
1785 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP_SUCCESS|" . (int)$arResult["GROUP_ID"],
1786 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
1787 Loc::getMessage(
1788 "SONET_UG_CONFIRM_MEMBER_MESSAGE_MSGVER_1",
1789 ["#NAME#" => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"],
1790 $languageId
1791 )
1792 ,
1793 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
1794 Loc::getMessage(
1795 "SONET_UG_CONFIRM_MEMBER_MESSAGE_MSGVER_1",
1796 ['#NAME#' => $arResult['GROUP_NAME'],
1797 $languageId]
1798 )
1799 ." (".$serverName . $url.")",
1800 );
1801 CIMNotify::Add($arMessageFields);
1802
1804 "TYPE" => "join",
1805 "RELATION_ID" => $arResult["ID"],
1806 "USER_ID" => $arResult["USER_ID"],
1807 "GROUP_ID" => $arResult["GROUP_ID"],
1808 "GROUP_NAME" => htmlspecialcharsbx($arResult["GROUP_NAME"]),
1809 "EXCLUDE_USERS" => array($arResult["INITIATED_BY_USER_ID"])
1810 ));
1811 }
1812 }
1813 }
1814 else
1815 {
1816 $errorMessage = "";
1817 if ($e = $APPLICATION->GetException())
1818 {
1819 $errorMessage = $e->GetString();
1820 }
1821 if ($errorMessage === '')
1822 {
1823 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
1824 }
1825
1826 $APPLICATION->ThrowException($errorMessage, "ERROR_CREATE_RELATION");
1827 return false;
1828 }
1829 }
1830 else
1831 {
1832 $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_GROUP_REQUEST");
1833 return false;
1834 }
1835
1837
1838 return true;
1839 }
1840
1841 public static function UserRejectRequestToBeMember($targetUserID, $relationID): bool
1842 {
1843 global $APPLICATION;
1844
1845 $targetUserID = (int)$targetUserID;
1846 if ($targetUserID <= 0)
1847 {
1848 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_SENDER_USER_ID");
1849 return false;
1850 }
1851
1852 $relationID = (int)$relationID;
1853 if ($relationID <= 0)
1854 {
1855 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_RELATIONID"), "ERROR_RELATION_ID");
1856 return false;
1857 }
1858
1859 $dbResult = CSocNetUserToGroup::GetList(
1860 array(),
1861 array(
1862 "ID" => $relationID,
1863 "USER_ID" => $targetUserID,
1865 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_GROUP
1866 ),
1867 false,
1868 false,
1869 array("ID", "USER_ID", "GROUP_ID", "GROUP_SITE_ID", "INITIATED_BY_USER_ID", "GROUP_NAME")
1870 );
1871
1872 if ($arResult = $dbResult->Fetch())
1873 {
1874 if (!empty($arResult['GROUP_NAME']))
1875 {
1876 $arResult['GROUP_NAME'] = Emoji::decode($arResult['GROUP_NAME']);
1877 }
1878
1880 {
1881 $events = GetModuleEvents("socialnetwork", "OnSocNetUserRejectRequestToBeMember");
1882 while ($arEvent = $events->Fetch())
1883 {
1884 ExecuteModuleEventEx($arEvent, array($arResult["ID"], $arResult));
1885 }
1886
1887 if (Loader::includeModule('im'))
1888 {
1889 $groupSiteId = CSocNetGroup::GetDefaultSiteId($arResult["GROUP_ID"], $arResult["GROUP_SITE_ID"]);
1890 $groupUrl = str_replace(
1891 [ "#group_id#", "#GROUP_ID#" ],
1892 $arResult["GROUP_ID"],
1893 Path::get('group_path_template', $groupSiteId)
1894 );
1896 array(
1897 "GROUP_URL" => $groupUrl
1898 ),
1899 $arResult["INITIATED_BY_USER_ID"],
1900 $groupSiteId
1901 );
1902 $url = $arTmp["URLS"]["GROUP_URL"];
1903 $serverName = (
1904 mb_strpos($url, "http://") === 0
1905 || mb_strpos($url, "https://") === 0
1906 ? ""
1907 : $arTmp["SERVER_NAME"]
1908 );
1909 $domainName = (
1910 mb_strpos($url, "http://") === 0
1911 || mb_strpos($url, "https://") === 0
1912 ? ""
1913 : (
1914 isset($arTmp["DOMAIN"])
1915 && !empty($arTmp["DOMAIN"])
1916 ? "//".$arTmp["DOMAIN"]
1917 : ""
1918 )
1919 );
1920
1921 $arMessageFields = array(
1922 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
1923 "TO_USER_ID" => $arResult["INITIATED_BY_USER_ID"],
1924 "FROM_USER_ID" => $arResult['USER_ID'],
1925 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
1926 "NOTIFY_MODULE" => "socialnetwork",
1927 "NOTIFY_EVENT" => "invite_group",
1928 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP_REJECT|" . (int)$arResult["GROUP_ID"],
1929 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
1930 Loc::getMessage(
1931 "SONET_UG_REJECT_MEMBER_MESSAGE_MSGVER_1",
1932 ["#NAME#" => "<a href=\"".$domainName.$url."\" class=\"bx-notifier-item-action\">".$arResult["GROUP_NAME"]."</a>"],
1933 $languageId
1934 )
1935 ,
1936 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
1937 Loc::getMessage(
1938 "SONET_UG_REJECT_MEMBER_MESSAGE_MSGVER_1",
1939 ['#NAME#' => $arResult['GROUP_NAME']],
1940 $languageId
1941 ) . " (".$serverName.$url.")"
1942 ,
1943 );
1944
1945 CIMNotify::Add($arMessageFields);
1946 }
1947 }
1948 else
1949 {
1950 $errorMessage = "";
1951 if ($e = $APPLICATION->GetException())
1952 {
1953 $errorMessage = $e->GetString();
1954 }
1955 if ($errorMessage === '')
1956 {
1957 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
1958 }
1959
1960 $APPLICATION->ThrowException($errorMessage, "ERROR_DELETE_RELATION");
1961 return false;
1962 }
1963 }
1964 else
1965 {
1966 $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_MEMBER_REQUEST");
1967 return false;
1968 }
1969
1971
1972 return true;
1973 }
1974
1975 public static function TransferModerator2Member($userID, $groupId, $relationIdList): bool
1976 {
1977 global $APPLICATION, $USER;
1978
1979 $userID = (int)$userID;
1980 if ($userID <= 0)
1981 {
1982 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
1983 return false;
1984 }
1985
1986 $groupId = (int)$groupId;
1987 if ($groupId <= 0)
1988 {
1989 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
1990 return false;
1991 }
1992
1993 if (!is_array($relationIdList))
1994 {
1995 return true;
1996 }
1997
1998 $arGroup = WorkgroupTable::getList([
1999 'select' => [
2000 'SITE_ID',
2001 'NAME',
2002 ],
2003 'filter' => ['ID' => $groupId],
2004 ])->fetch();
2005 if (!$arGroup || !is_array($arGroup))
2006 {
2007 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
2008 return false;
2009 }
2010
2011 $bSuccess = true;
2012 $arSuccessRelations = array();
2013 $bIMIncluded = false;
2014 $groupSiteId = SITE_ID;
2015
2016 if (Loader::includeModule('im'))
2017 {
2018 $bIMIncluded = true;
2019 $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $arGroup["SITE_ID"]);
2020 }
2021
2022 $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId);
2023 $groupUrlTemplate = Path::get('group_path_template', $groupSiteId);
2024 $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
2025 $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate);
2026 $relationsToUpdateCount = 0;
2027
2028 foreach ($relationIdList as $relationId)
2029 {
2030 $relationId = (int)$relationId;
2031 if ($relationId <= 0)
2032 {
2033 continue;
2034 }
2035
2036 $arRelation = CSocNetUserToGroup::GetByID($relationId);
2037 if (
2038 !$arRelation
2039 || (int)$arRelation["GROUP_ID"] !== $groupId
2040 || $arRelation["ROLE"] !== UserToGroupTable::ROLE_MODERATOR
2041 )
2042 {
2043 continue;
2044 }
2045
2046 $relationsToUpdateCount++;
2047
2048 $arFields = array(
2050 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2051 );
2052 if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields))
2053 {
2054 $arSuccessRelations[] = $arRelation;
2055
2056 if ($bIMIncluded)
2057 {
2059 array(
2060 "GROUP_URL" => $groupUrl
2061 ),
2062 $arRelation["USER_ID"],
2063 $groupSiteId
2064 );
2065 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
2066 $serverName = (
2067 mb_strpos($groupUrl, "http://") === 0
2068 || mb_strpos($groupUrl, "https://") === 0
2069 ? ""
2070 : $arTmp["SERVER_NAME"]
2071 );
2072 $domainName = (
2073 mb_strpos($groupUrl, "http://") === 0
2074 || mb_strpos($groupUrl, "https://") === 0
2075 ? ""
2076 : (
2077 isset($arTmp["DOMAIN"])
2078 && !empty($arTmp["DOMAIN"])
2079 ? "//".$arTmp["DOMAIN"]
2080 : ""
2081 )
2082 );
2083
2084 $arMessageFields = array(
2085 "TO_USER_ID" => $arRelation["USER_ID"],
2086 "FROM_USER_ID" => $userID,
2087 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
2088 "NOTIFY_MODULE" => "socialnetwork",
2089 "NOTIFY_EVENT" => "moderators_group",
2090 "NOTIFY_TAG" => "SOCNET|MOD_GROUP|" . (int)$userID . "|" . $groupId . "|" . $arRelation["ID"] . "|" . $arRelation["USER_ID"],
2091 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
2092 Loc::getMessage(
2093 "SONET_UG_MOD2MEMBER_MESSAGE",
2094 ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$arGroup["NAME"]."</a>"],
2095 $languageId
2096 )
2097 ,
2098 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
2099 Loc::getMessage(
2100 "SONET_UG_MOD2MEMBER_MESSAGE",
2101 ['#NAME#' => $arGroup["NAME"]],
2102 $languageId
2103 )
2104 . " (".$serverName.$groupUrl.")"
2105 ,
2106 );
2107
2108 CIMNotify::Add($arMessageFields);
2109 }
2110 }
2111 else
2112 {
2113 $errorMessage = "";
2114 if ($e = $APPLICATION->GetException())
2115 {
2116 $errorMessage = $e->GetString();
2117 }
2118 if ($errorMessage === '')
2119 {
2120 $errorMessage = Loc::getMessage("SONET_UR_ERROR_CREATE_USER2GROUP");
2121 }
2122
2123 $APPLICATION->ThrowException($errorMessage, "ERROR_MOD2MEMBER");
2124 $bSuccess = false;
2125 }
2126 }
2127
2128 if ($relationsToUpdateCount <= 0)
2129 {
2130 $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MEM2MOD_EMPTY_CORRECT_LIST"), "MOD2MEM_EMPTY_CORRECT_LIST");
2131 return false;
2132 }
2133
2134 $successfulUserIdList = array();
2135 foreach ($arSuccessRelations as $arRel)
2136 {
2137 $arNotifyParams = array(
2138 "TYPE" => "unmoderate",
2139 "RELATION_ID" => $arRel["ID"],
2140 "USER_ID" => $arRel["USER_ID"],
2141 "GROUP_ID" => $arRel["GROUP_ID"],
2142 "GROUP_NAME" => $arRel["GROUP_NAME"],
2143 "EXCLUDE_USERS" => array($USER->GetID())
2144 );
2146
2147 $successfulUserIdList[] = $arRel["USER_ID"];
2148 }
2149
2150 $successfulUserIdList = array_unique($successfulUserIdList);
2151
2152 if (!empty($successfulUserIdList))
2153 {
2155 'group_id' => $groupId,
2156 'user_id' => $successfulUserIdList,
2157 'set' => false
2158 ));
2159 }
2160
2161 if (
2162 $bSuccess
2163 && count($arSuccessRelations) <= 0
2164 )
2165 {
2166 $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MOD2MEM_INCORRECT_PARAMS"), "MOD2MEM_INCORRECT_PARAMS");
2167 $bSuccess = false;
2168 }
2169
2170 return $bSuccess;
2171 }
2172
2173 public static function TransferMember2Moderator($userID, $groupId, $relationIdList): bool
2174 {
2175 global $APPLICATION, $USER;
2176
2177 $userID = (int)$userID;
2178 if ($userID <= 0)
2179 {
2180 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
2181 return false;
2182 }
2183
2184 $groupId = (int)$groupId;
2185 if ($groupId <= 0)
2186 {
2187 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
2188 return false;
2189 }
2190
2191 if (!is_array($relationIdList))
2192 {
2193 return true;
2194 }
2195
2196 $arGroup = CSocNetGroup::GetByID($groupId);
2197 if (!$arGroup || !is_array($arGroup))
2198 {
2199 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
2200 return false;
2201 }
2202
2203 $bSuccess = true;
2204 $arSuccessRelations = array();
2205
2206 $relationsToUpdateCount = 0;
2207
2208 foreach ($relationIdList as $relationId)
2209 {
2210 $relationId = (int)$relationId;
2211 if ($relationId <= 0)
2212 {
2213 continue;
2214 }
2215
2216 $arRelation = CSocNetUserToGroup::GetByID($relationId);
2217 if (
2218 !$arRelation
2219 || (int)$arRelation["GROUP_ID"] !== $groupId
2220 || $arRelation["ROLE"] !== UserToGroupTable::ROLE_USER
2221 )
2222 {
2223 continue;
2224 }
2225
2226 $relationsToUpdateCount++;
2227
2228 $arFields = array(
2230 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2231 );
2232 if (CSocNetUserToGroup::update($arRelation["ID"], $arFields))
2233 {
2234 $arSuccessRelations[] = $arRelation;
2236 'userId' => $userID,
2237 'groupId' => $groupId,
2238 'relationFields' => $arRelation,
2239 'groupFields' => $arGroup
2240 ));
2241 }
2242 else
2243 {
2244 $errorMessage = "";
2245 if ($e = $APPLICATION->GetException())
2246 {
2247 $errorMessage = $e->GetString();
2248 }
2249 if ($errorMessage === '')
2250 {
2251 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
2252 }
2253
2254 $APPLICATION->ThrowException($errorMessage, "ERROR_MEMBER2MOD");
2255 $bSuccess = false;
2256 }
2257 }
2258
2259 if ($relationsToUpdateCount <= 0)
2260 {
2261 $APPLICATION->ThrowException(GetMessage("SONET_UR_ERROR_MEM2MOD_EMPTY_CORRECT_LIST"), "MOD2MEM_EMPTY_CORRECT_LIST");
2262 return false;
2263 }
2264
2265 $successfulUserIdList = array();
2266 foreach ($arSuccessRelations as $arRel)
2267 {
2268 $arNotifyParams = array(
2269 "TYPE" => "moderate",
2270 "RELATION_ID" => $arRel["ID"],
2271 "USER_ID" => $arRel["USER_ID"],
2272 "GROUP_ID" => $arRel["GROUP_ID"],
2273 "GROUP_NAME" => $arRel["GROUP_NAME"],
2274 "EXCLUDE_USERS" => array($arRel["USER_ID"], $USER->GetID())
2275 );
2277 CSocNetSubscription::Set($arRel["USER_ID"], "SG".$arRel["GROUP_ID"], "Y");
2278
2279 $successfulUserIdList[] = $arRel["USER_ID"];
2280 }
2281
2282 $successfulUserIdList = array_unique($successfulUserIdList);
2283
2284 if (!empty($successfulUserIdList))
2285 {
2287 'group_id' => $groupId,
2288 'user_id' => $successfulUserIdList,
2289 'set' => true
2290 ));
2291 }
2292
2293 if (
2294 $bSuccess
2295 && count($arSuccessRelations) <= 0
2296 )
2297 {
2298 $errorMessage = "";
2299 if ($e = $APPLICATION->GetException())
2300 {
2301 $errorMessage = $e->GetString();
2302 }
2303 if ($errorMessage === '')
2304 {
2305 $errorMessage = Loc::getMessage('SONET_UR_ERROR_MEM2MOD_INCORRECT_PARAMS');
2306 }
2307
2308 $APPLICATION->ThrowException($errorMessage, "MEM2MOD_INCORRECT_PARAMS");
2309 $bSuccess = false;
2310 }
2311
2312 return $bSuccess;
2313 }
2314
2315 public static function BanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin): bool
2316 {
2317 global $APPLICATION;
2318
2319 $userID = (int)$userID;
2320 if ($userID <= 0)
2321 {
2322 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
2323 return false;
2324 }
2325
2326 $groupId = (int)$groupId;
2327 if ($groupId <= 0)
2328 {
2329 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
2330 return false;
2331 }
2332
2333 if (!is_array($relationIdList))
2334 {
2335 return true;
2336 }
2337
2338 $arGroup = CSocNetGroup::GetByID($groupId);
2339 if (!$arGroup || !is_array($arGroup))
2340 {
2341 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
2342 return false;
2343 }
2344
2345 $arUserPerms = CSocNetUserToGroup::InitUserPerms($userID, $arGroup, $currentUserIsAdmin);
2346
2347 if (!$arUserPerms["UserCanModifyGroup"] && !$arUserPerms["UserCanModerateGroup"])
2348 {
2349 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS");
2350 return false;
2351 }
2352
2353 $bSuccess = true;
2354 foreach ($relationIdList as $relationId)
2355 {
2356 $relationId = (int)$relationId;
2357 if ($relationId <= 0)
2358 {
2359 continue;
2360 }
2361
2362 $arRelation = CSocNetUserToGroup::GetByID($relationId);
2363 if (!$arRelation)
2364 {
2365 continue;
2366 }
2367
2368 if (
2369 (int)$arRelation["GROUP_ID"] !== $groupId
2370 || $arRelation["ROLE"] !== UserToGroupTable::ROLE_USER
2371 )
2372 {
2373 continue;
2374 }
2375
2376 $arFields = array(
2378 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2379 );
2380 if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields))
2381 {
2382 $arMessageFields = array(
2383 "FROM_USER_ID" => $userID,
2384 "TO_USER_ID" => $arRelation["USER_ID"],
2385 "MESSAGE" => fn (?string $languageId = null) => Loc::getMessage(
2386 "SONET_UG_BANMEMBER_MESSAGE",
2387 [
2388 "#NAME#" => $arGroup["NAME"]
2389 ],
2390 $languageId
2391 ),
2392 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
2393 "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM
2394 );
2395 CSocNetMessages::Add($arMessageFields);
2396 CSocNetSubscription::DeleteEx($arRelation["USER_ID"], "SG".$arRelation["GROUP_ID"]);
2397
2399 'group_id' => $groupId,
2400 'user_id' => $arRelation["USER_ID"],
2402 ));
2403 }
2404 else
2405 {
2406 $errorMessage = "";
2407 if ($e = $APPLICATION->GetException())
2408 {
2409 $errorMessage = $e->GetString();
2410 }
2411 if ($errorMessage === '')
2412 {
2413 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
2414 }
2415
2416 $APPLICATION->ThrowException($errorMessage, "ERROR_BANMEMBER");
2417 $bSuccess = false;
2418 }
2419 }
2420
2421 return $bSuccess;
2422 }
2423
2424 public static function UnBanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin): bool
2425 {
2426 global $APPLICATION;
2427
2428 $userID = (int)$userID;
2429 if ($userID <= 0)
2430 {
2431 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USERID");
2432 return false;
2433 }
2434
2435 $groupId = (int)$groupId;
2436 if ($groupId <= 0)
2437 {
2438 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
2439 return false;
2440 }
2441
2442 if (!is_array($relationIdList))
2443 {
2444 return true;
2445 }
2446
2447 $arGroup = CSocNetGroup::GetByID($groupId);
2448 if (!$arGroup || !is_array($arGroup))
2449 {
2450 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_GROUP_ID"), "ERROR_NO_GROUP");
2451 return false;
2452 }
2453
2454 $arUserPerms = CSocNetUserToGroup::InitUserPerms($userID, $arGroup, $currentUserIsAdmin);
2455
2456 if (!$arUserPerms["UserCanModifyGroup"] && !$arUserPerms["UserCanModerateGroup"])
2457 {
2458 $APPLICATION->ThrowException(GetMessage("SONET_UG_ERROR_NO_PERMS"), "ERROR_NO_PERMS");
2459 return false;
2460 }
2461
2462 $bSuccess = true;
2463 foreach ($relationIdList as $relationId)
2464 {
2465 $relationId = (int)$relationId;
2466 if ($relationId <= 0)
2467 {
2468 continue;
2469 }
2470
2471 $arRelation = CSocNetUserToGroup::GetByID($relationId);
2472 if (!$arRelation)
2473 {
2474 continue;
2475 }
2476
2477 if (
2478 (int)$arRelation["GROUP_ID"] !== $groupId
2479 || $arRelation["ROLE"] !== UserToGroupTable::ROLE_BAN
2480 )
2481 {
2482 continue;
2483 }
2484
2485 $arFields = array(
2487 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2488 );
2489 if (CSocNetUserToGroup::Update($arRelation["ID"], $arFields))
2490 {
2492 "FROM_USER_ID" => $userID,
2493 "TO_USER_ID" => $arRelation["USER_ID"],
2494 "MESSAGE" => fn (?string $languageId = null) => Loc::getMessage(
2495 "SONET_UG_UNBANMEMBER_MESSAGE",
2496 [
2497 "#NAME#" => $arGroup["NAME"]
2498 ],
2499 $languageId
2500 ),
2501 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
2502 "MESSAGE_TYPE" => SONET_MESSAGE_SYSTEM
2503 ));
2504
2506 'group_id' => $groupId,
2507 'user_id' => $userID,
2508 'action' => UserToGroup::CHAT_ACTION_IN,
2509 'role' => $arFields['ROLE']
2510 ));
2511 }
2512 else
2513 {
2514 $errorMessage = "";
2515 if ($e = $APPLICATION->GetException())
2516 {
2517 $errorMessage = $e->GetString();
2518 }
2519 if ($errorMessage === '')
2520 {
2521 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
2522 }
2523
2524 $APPLICATION->ThrowException($errorMessage, "ERROR_UNBANMEMBER");
2525 $bSuccess = false;
2526 }
2527 }
2528
2529 return $bSuccess;
2530 }
2531
2532 public static function SetOwner($userId, $groupId, $groupFields = [], bool $skipChatMessage = false): bool
2533 {
2534 global $DB, $APPLICATION, $USER;
2535
2536 if (empty($groupFields))
2537 {
2538 $groupFields = WorkgroupTable::getList([
2539 'select' => [
2540 'TYPE',
2541 'SITE_ID',
2542 'OWNER_ID',
2543 'NAME',
2544 ],
2545 'filter' => ['ID' => $groupId],
2546 ])->fetch();
2547 }
2548
2549 if (empty($groupFields))
2550 {
2551 return false;
2552 }
2553
2554 $errorMessage = "";
2555 $DB->StartTransaction();
2556
2557 // setting relations for the old owner
2558 $res = CSocNetUserToGroup::GetList(
2559 array(),
2560 array(
2561 "USER_ID" => $groupFields["OWNER_ID"],
2562 "GROUP_ID" => $groupId,
2563 ),
2564 false,
2565 false,
2566 array('ID', 'USER_ID')
2567 );
2568 if ($existingRelationFields = $res->fetch())
2569 {
2571
2572 $workgroup = WorkgroupTable::getList([
2573 'select' => ['SCRUM_MASTER_ID'],
2574 'filter' => ['ID' => $groupId],
2575 ])->fetchObject();
2576 if (
2577 $workgroup
2578 && $workgroup->getScrumMasterId() === (int)$existingRelationFields['USER_ID']
2579 )
2580 {
2582 }
2583
2584 $relationFields = array(
2585 "ROLE" => $role,
2586 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2587 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER,
2588 "INITIATED_BY_USER_ID" => $USER->GetID(),
2589 );
2590
2591 if (!CSocNetUserToGroup::Update($existingRelationFields["ID"], $relationFields))
2592 {
2593 if ($e = $APPLICATION->GetException())
2594 {
2595 $errorMessage = $e->GetString();
2596 }
2597 if ($errorMessage === '')
2598 {
2599 $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_CURRENT_OWNER');
2600 }
2601
2602 $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_USER2GROUP");
2603 $DB->Rollback();
2604 return false;
2605 }
2606 }
2607
2608 CSocNetUserToGroup::__SpeedFileDelete($groupFields["OWNER_ID"]);
2609
2610 // setting relations for the new owner
2611 $res = CSocNetUserToGroup::GetList(
2612 [],
2613 [
2614 'USER_ID' => $userId,
2615 'GROUP_ID' => $groupId,
2616 ],
2617 false,
2618 false,
2619 [ 'ID', 'ROLE' ]
2620 );
2621 if ($existingRelationFields = $res->Fetch())
2622 {
2623 $relationFields = array(
2625 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2626 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER,
2627 "INITIATED_BY_USER_ID" => $USER->GetID(),
2628 "AUTO_MEMBER" => "N"
2629 );
2630
2631 if (!CSocNetUserToGroup::Update($existingRelationFields["ID"], $relationFields))
2632 {
2633 if ($e = $APPLICATION->GetException())
2634 {
2635 $errorMessage = $e->GetString();
2636 }
2637 if ($errorMessage === '')
2638 {
2639 $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_NEW_OWNER_RELATION');
2640 }
2641
2642 $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_USER2GROUP");
2643 $DB->Rollback();
2644 return false;
2645 }
2646
2647 if (!$skipChatMessage && !in_array($existingRelationFields["ID"], UserToGroupTable::getRolesMember(), true))
2648 {
2650 'group_id' => $groupId,
2651 'user_id' => $userId,
2652 'action' => UserToGroup::CHAT_ACTION_IN,
2653 'role' => $relationFields['ROLE'],
2654 ]);
2655 }
2656
2657 if (Loader::includeModule('im'))
2658 {
2659 CIMNotify::deleteByTag('SOCNET|INVITE_GROUP|' . (int)$userId . '|' . (int)$existingRelationFields['ID']);
2660 }
2661 }
2662 else
2663 {
2664 $relationFields = array(
2665 "USER_ID" => $userId,
2666 "GROUP_ID" => $groupId,
2668 "=DATE_CREATE" => CDatabase::CurrentTimeFunction(),
2669 "=DATE_UPDATE" => CDatabase::CurrentTimeFunction(),
2670 "INITIATED_BY_TYPE" => SONET_INITIATED_BY_USER,
2671 "INITIATED_BY_USER_ID" => $USER->GetID(),
2672 "MESSAGE" => false,
2673 );
2674
2675 if (!CSocNetUserToGroup::Add($relationFields))
2676 {
2677 if ($e = $APPLICATION->GetException())
2678 {
2679 $errorMessage = $e->GetString();
2680 }
2681 if ($errorMessage === '')
2682 {
2683 $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_ADD_NEW_OWNER_RELATION');
2684 }
2685
2686 $APPLICATION->ThrowException($errorMessage, "ERROR_ADD_USER2GROUP");
2687 $DB->Rollback();
2688 return false;
2689 }
2690
2691 if (!$skipChatMessage)
2692 {
2694 'group_id' => $groupId,
2695 'user_id' => $userId,
2696 'action' => UserToGroup::CHAT_ACTION_IN,
2697 'role' => $relationFields['ROLE'],
2698 ]);
2699 }
2700 }
2701
2702 $GROUP_ID = CSocNetGroup::Update($groupId, array("OWNER_ID" => $userId));
2703 if (!$GROUP_ID || $GROUP_ID <= 0)
2704 {
2705 if ($e = $APPLICATION->GetException())
2706 {
2707 $errorMessage = $e->GetString();
2708 }
2709 if ($errorMessage === '')
2710 {
2711 $errorMessage = Loc::getMessage('SONET_UG_ERROR_CANNOT_UPDATE_GROUP');
2712 }
2713
2714 $APPLICATION->ThrowException($errorMessage, "ERROR_UPDATE_GROUP");
2715 $DB->Rollback();
2716 return false;
2717 }
2718
2719 $bIMIncluded = false;
2720 $groupUrl = "";
2721 $groupSiteId = SITE_ID;
2722
2723 if (Loader::includeModule('im'))
2724 {
2725 $bIMIncluded = true;
2726 $groupSiteId = CSocNetGroup::GetDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false);
2727 $workgroupsPage = COption::GetOptionString("socialnetwork", "workgroups_page", "/workgroups/", $groupSiteId);
2728 $groupUrlTemplate = Path::get('group_path_template', $groupSiteId);
2729 $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
2730 $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate);
2731 }
2732
2733 // send message to the old owner
2734 if ($bIMIncluded)
2735 {
2737 array(
2738 "GROUP_URL" => $groupUrl
2739 ),
2740 $groupFields["OWNER_ID"],
2741 $groupSiteId
2742 );
2743 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
2744 $serverName = (
2745 mb_strpos($groupUrl, "http://") === 0
2746 || mb_strpos($groupUrl, "https://") === 0
2747 ? ""
2748 : $arTmp["SERVER_NAME"]
2749 );
2750
2751 $notifyNewOwnerMessageKey = 'SONET_UG_OWNER2MEMBER_MESSAGE';
2752 if (($groupFields['TYPE'] ?? null) === Workgroup\Type::Collab->value)
2753 {
2754 $notifyNewOwnerMessageKey = 'SONET_UG_OWNER2MEMBER_MESSAGE_COLLAB';
2755 }
2757 "TO_USER_ID" => $groupFields["OWNER_ID"],
2758 "FROM_USER_ID" => $USER->GetID(),
2759 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
2760 "NOTIFY_MODULE" => "socialnetwork",
2761 "NOTIFY_EVENT" => "owner_group",
2762 "NOTIFY_TAG" => "SOCNET|OWNER_GROUP|".$groupId,
2763 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
2764 Loc::getMessage(
2765 $notifyNewOwnerMessageKey,
2766 ['#NAME#' => "<a href=\"".$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"],
2767 $languageId
2768 )
2769 ,
2770 "NOTIFY_MESSAGE_OUT" => function (?string $languageId = null) use ($groupFields, $serverName, $groupUrl) {
2771 $message = Loc::getMessage(
2772 "SONET_UG_OWNER2MEMBER_MESSAGE",
2773 ["#NAME#" => $groupFields['NAME']],
2774 $languageId
2775 );
2776
2777 return $message . " (" . $serverName . $groupUrl . ")";
2778 },
2779
2780 );
2781
2782 CIMNotify::Add($messageFields);
2783 }
2784
2785 // send message to the new owner
2786 if ($bIMIncluded)
2787 {
2789 array(
2790 "GROUP_URL" => $groupUrl
2791 ),
2792 $userId,
2793 $groupSiteId
2794 );
2795 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
2796
2797 if (
2798 mb_strpos($groupUrl, "http://") === 0
2799 || mb_strpos($groupUrl, "https://") === 0
2800 )
2801 {
2802 $serverName = "";
2803 }
2804 else
2805 {
2806 $serverName = $arTmp["SERVER_NAME"];
2807 }
2808
2809 $notifyOldOwnerMessageKey = 'SONET_UG_MEMBER2OWNER_MESSAGE';
2810 if (($groupFields['TYPE'] ?? null) === Workgroup\Type::Collab->value)
2811 {
2812 $notifyOldOwnerMessageKey = 'SONET_UG_MEMBER2OWNER_MESSAGE_COLLAB';
2813 }
2814
2816 "TO_USER_ID" => $userId,
2817 "FROM_USER_ID" => $USER->GetID(),
2818 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
2819 "NOTIFY_MODULE" => "socialnetwork",
2820 "NOTIFY_EVENT" => "owner_group",
2821 "NOTIFY_TAG" => "SOCNET|OWNER_GROUP|".$groupId,
2822 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
2823 Loc::getMessage(
2824 $notifyOldOwnerMessageKey,
2825 ["#NAME#" => "<a href=\"".$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"],
2826 $languageId
2827 )
2828 ,
2829 "NOTIFY_MESSAGE_OUT" => function (?string $languageId = null) use ($groupFields, $serverName, $groupUrl) {
2830 $message = Loc::getMessage(
2831 "SONET_UG_MEMBER2OWNER_MESSAGE",
2832 ["#NAME#" => $groupFields['NAME']],
2833 $languageId
2834 );
2835
2836 return $message . " (" . $serverName . $groupUrl . ")";
2837 },
2838 );
2839
2840 CIMNotify::Add($messageFields);
2841 }
2842
2843 $notificationParams = array(
2844 "TYPE" => "owner",
2845 "RELATION_ID" => $existingRelationFields["ID"] ?? null,
2846 "USER_ID" => $userId,
2847 "GROUP_ID" => $groupId,
2848 "GROUP_NAME" => htmlspecialcharsbx($groupFields["NAME"]),
2849 "EXCLUDE_USERS" => array($userId, $groupFields["OWNER_ID"], $USER->GetID())
2850 );
2851 CSocNetUserToGroup::NotifyImToModerators($notificationParams);
2852
2853 CSocNetSubscription::Set($userId, "SG".$groupId, "Y");
2854
2855 $DB->Commit();
2856 return true;
2857 }
2858
2859 public static function DeleteRelation($userId, $groupId): bool
2860 {
2861 global $APPLICATION;
2862
2863 $userId = (int)$userId;
2864 if ($userId <= 0)
2865 {
2866 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_USERID"), "ERROR_USER_ID");
2867 return false;
2868 }
2869
2870 $groupId = (int)$groupId;
2871 if ($groupId <= 0)
2872 {
2873 $APPLICATION->ThrowException(GetMessage("SONET_UR_EMPTY_GROUPID"), "ERROR_GROUPID");
2874 return false;
2875 }
2876
2877 $res = CSocNetUserToGroup::GetList(
2878 array(),
2879 array(
2880 "GROUP_ID" => $groupId,
2881 "USER_ID" => $userId,
2882 ),
2883 false,
2884 false,
2885 [ 'ID', 'USER_ID', 'ROLE', 'GROUP_VISIBLE', 'GROUP_NAME', 'GROUP_SCRUM_MASTER_ID' ]
2886 );
2887
2888 if ($relationFields = $res->Fetch())
2889 {
2890 if (!in_array($relationFields["ROLE"], [
2893 ], true))
2894 {
2895 return false;
2896 }
2897
2898 if ((int)$relationFields['USER_ID'] === (int)$relationFields['GROUP_SCRUM_MASTER_ID'])
2899 {
2900 return false;
2901 }
2902
2903 if (!empty($relationFields['GROUP_NAME']))
2904 {
2905 $relationFields['GROUP_NAME'] = Emoji::decode($relationFields['GROUP_NAME']);
2906 }
2907
2908 if (CSocNetUserToGroup::Delete($relationFields["ID"]))
2909 {
2910 CSocNetSubscription::DeleteEx($userId, "SG".$groupId);
2911
2913 {
2914 $chatNotificationResult = UserToGroup::addInfoToChat(array(
2915 'group_id' => $groupId,
2916 'user_id' => $userId,
2918 ));
2919
2920 if (!$chatNotificationResult)
2921 {
2922 CSocNetUserToGroup::notifyImToModerators(array(
2923 "TYPE" => "unjoin",
2924 "RELATION_ID" => $relationFields["ID"],
2925 "USER_ID" => $userId,
2926 "GROUP_ID" => $groupId,
2927 "GROUP_NAME" => $relationFields["GROUP_NAME"]
2928 ));
2929 }
2930 }
2931 }
2932 else
2933 {
2934 $errorMessage = "";
2935 if ($e = $APPLICATION->GetException())
2936 {
2937 $errorMessage = $e->GetString();
2938 }
2939 if ($errorMessage === '')
2940 {
2941 $errorMessage = Loc::getMessage('SONET_UR_ERROR_CREATE_USER2GROUP');
2942 }
2943
2944 $APPLICATION->ThrowException($errorMessage, "ERROR_DELETE_RELATION");
2945 return false;
2946 }
2947 }
2948 else
2949 {
2950 $APPLICATION->ThrowException(GetMessage("SONET_NO_USER2GROUP"), "ERROR_NO_MEMBER_REQUEST");
2951 return false;
2952 }
2953
2955
2956 return true;
2957 }
2958
2959 public static function InitUserPerms($userId, $groupFields, $isCurrentUserAdmin)
2960 {
2963
2964 $arReturn = array();
2965
2966 $userId = (int)$userId;
2967 $groupId = (int)$groupFields["ID"];
2968 $groupOwnerId = (int)$groupFields["OWNER_ID"];
2969 $groupInitiatePerms = Trim($groupFields["INITIATE_PERMS"]);
2970 $groupVisible = Trim($groupFields["VISIBLE"]);
2971 $groupOpened = Trim($groupFields["OPENED"]);
2972 $groupSpamPerms = Trim(($groupFields["SPAM_PERMS"] ?? ''));
2973
2974 if ($groupId <= 0 || $groupOwnerId <= 0 || !in_array($groupInitiatePerms, $arSocNetAllowedInitiatePerms))
2975 {
2976 return false;
2977 }
2978
2979 $arReturn["Operations"] = [];
2980
2981 if (!in_array($groupSpamPerms, $arSocNetAllowedSpamPerms))
2982 {
2983 $groupSpamPerms = "K";
2984 }
2985
2986 // UserRole - User role in group. False if user is not group member.
2987 // UserIsMember - True in user is group member.
2988 // UserIsAuto - True in user is group auto member.
2989 // UserIsOwner - True if user is group owner.
2990 // UserCanInitiate - True if user can invite friends to group.
2991 // UserCanViewGroup - True if user can view group.
2992 // UserCanAutoJoinGroup - True if user can join group automatically.
2993 // UserCanModifyGroup - True if user can modify group.
2994 // UserCanModerateGroup - True if user can moderate group.
2995
2996 if ($userId <= 0)
2997 {
2998 $arReturn["UserRole"] = false;
2999 $arReturn["UserIsMember"] = false;
3000 $arReturn["UserIsAutoMember"] = false;
3001 $arReturn["UserIsOwner"] = false;
3002 $arReturn['UserIsScrumMaster'] = false;
3003 $arReturn["UserCanInitiate"] = false;
3004 $arReturn["UserCanProcessRequestsIn"] = false;
3005 $arReturn["UserCanViewGroup"] = ($groupVisible === "Y");
3006 $arReturn["UserCanAutoJoinGroup"] = false;
3007 $arReturn["UserCanModifyGroup"] = false;
3008 $arReturn["UserCanModerateGroup"] = false;
3009 $arReturn["UserCanSpamGroup"] = false;
3010 $arReturn["InitiatedByType"] = false;
3011 $arReturn["InitiatedByUserId"] = false;
3012 $arReturn["Operations"]["viewsystemevents"] = false;
3013 }
3014 else
3015 {
3016 if (!isset($groupFields['SCRUM']))
3017 {
3018 $group = Workgroup::getById($groupFields['ID']);
3019 $groupFields['SCRUM'] = ($group && $group->isScrumProject() ? 'Y' : 'N');
3020 }
3021
3022 if (!isset($groupFields['SCRUM_MASTER_ID']))
3023 {
3024 $group = Workgroup::getById($groupFields['ID']);
3025 $groupFields['SCRUM_MASTER_ID'] = ($group ? $group->getScrumMaster() : 0);
3026 }
3027
3028 $arUserRoleExtended = CSocNetUserToGroup::GetUserRole($userId, $groupId, true);
3029 $arReturn["UserRole"] = $arUserRoleExtended["ROLE"];
3030
3031 $arReturn["UserIsMember"] = (
3032 $arReturn["UserRole"]
3033 && in_array($arReturn["UserRole"], UserToGroupTable::getRolesMember(), true)
3034 );
3035 $arReturn["UserIsAutoMember"] = (
3036 $arReturn["UserIsMember"]
3037 && $arUserRoleExtended["AUTO_MEMBER"] === "Y"
3038 );
3039
3040 $arReturn["InitiatedByType"] = false;
3041 $arReturn["InitiatedByUserId"] = false;
3042 if ($arReturn["UserRole"] === UserToGroupTable::ROLE_REQUEST)
3043 {
3044 $dbRelation = CSocNetUserToGroup::GetList(
3045 [],
3046 [ 'USER_ID' => $userId, 'GROUP_ID' => $groupId ],
3047 false,
3048 false,
3049 [ 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID' ]
3050 );
3051 if ($arRelation = $dbRelation->Fetch())
3052 {
3053 $arReturn["InitiatedByType"] = $arRelation["INITIATED_BY_TYPE"];
3054 $arReturn["InitiatedByUserId"] = (int)$arRelation['INITIATED_BY_USER_ID'];
3055 }
3056 }
3057
3058 $arReturn["UserIsOwner"] = ($userId === $groupOwnerId);
3059 $arReturn['UserIsScrumMaster'] = (
3060 $groupFields['SCRUM'] === 'Y'
3061 && (int)$groupFields['SCRUM_MASTER_ID'] === $userId
3062 );
3063
3064 if ($isCurrentUserAdmin)
3065 {
3066 $arReturn["UserCanInitiate"] = true;
3067 $arReturn["UserCanProcessRequestsIn"] = true;
3068 $arReturn["UserCanViewGroup"] = true;
3069 $arReturn["UserCanAutoJoinGroup"] = true;
3070 $arReturn["UserCanModifyGroup"] = true;
3071 $arReturn["UserCanModerateGroup"] = true;
3072 $arReturn["UserCanSpamGroup"] = true;
3073 $arReturn["Operations"]["viewsystemevents"] = true;
3074 }
3075 elseif ($arReturn["UserIsMember"])
3076 {
3077 $arReturn["UserCanInitiate"] = (
3078 (
3079 $groupInitiatePerms === UserToGroupTable::ROLE_OWNER
3080 && $arReturn['UserIsOwner']
3081 )
3082 || (
3083 $groupInitiatePerms === UserToGroupTable::ROLE_MODERATOR
3084 && in_array($arReturn['UserRole'], [
3087 ], true)
3088 )
3089 || ($groupInitiatePerms === UserToGroupTable::ROLE_USER)
3090 );
3091 $arReturn['UserCanProcessRequestsIn'] = (
3092 $arReturn['UserCanInitiate']
3093 && in_array($arReturn['UserRole'], [
3096 ], true)
3097 );
3098 $arReturn["UserCanViewGroup"] = true;
3099 $arReturn["UserCanAutoJoinGroup"] = false;
3100 $arReturn["UserCanModifyGroup"] = $arReturn["UserIsOwner"];
3101 if (
3102 !$arReturn['UserCanModifyGroup']
3103 && $groupFields['SCRUM'] === 'Y'
3104 )
3105 {
3106 if (!isset($groupFields['SCRUM_MASTER_ID']))
3107 {
3108 $group = Workgroup::getById($groupFields['ID']);
3109 $groupFields['SCRUM_MASTER_ID'] = ($group ? $group->getScrumMaster() : 0);
3110 }
3111
3112 $arReturn['UserCanModifyGroup'] = ((int)$groupFields['SCRUM_MASTER_ID'] === $userId);
3113 }
3114 $arReturn["UserCanModerateGroup"] = (in_array($arReturn['UserRole'], [
3117 ], true));
3118 $arReturn['UserCanSpamGroup'] = (
3119 (
3120 $groupSpamPerms === UserToGroupTable::ROLE_OWNER
3121 && $arReturn['UserIsOwner']
3122 )
3123 || (
3124 $groupSpamPerms === UserToGroupTable::ROLE_MODERATOR
3125 && in_array($arReturn["UserRole"], [
3128 ], true)
3129 )
3130 || $groupSpamPerms === UserToGroupTable::ROLE_USER
3131 || $groupSpamPerms === SONET_ROLES_ALL
3132 );
3133 $arReturn["Operations"]["viewsystemevents"] = true;
3134 }
3135 else
3136 {
3137 $arReturn["UserCanInitiate"] = false;
3138 $arReturn["UserCanViewGroup"] = ($groupVisible === "Y");
3139 $arReturn["UserCanAutoJoinGroup"] = ($arReturn["UserCanViewGroup"] && ($groupOpened === "Y"));
3140 $arReturn["UserCanModifyGroup"] = false;
3141 $arReturn["UserCanModerateGroup"] = false;
3142 $arReturn["UserCanSpamGroup"] = ($groupSpamPerms === SONET_ROLES_ALL);
3143 $arReturn["Operations"]["viewsystemevents"] = false;
3144 }
3145 }
3146
3147 if (Loader::includeModule('extranet') && CExtranet::IsExtranetSite())
3148 {
3149 $arReturn["UserCanSpamGroup"] = true;
3150 }
3151
3152 if (!CBXFeatures::IsFeatureEnabled("WebMessenger"))
3153 {
3154 $arReturn["UserCanSpamGroup"] = false;
3155 }
3156
3157 return $arReturn;
3158 }
3159
3160 public static function __SpeedFileCheckMessages($userID)
3161 {
3162 global $DB;
3163
3164 $userID = (int)$userID;
3165 if ($userID <= 0)
3166 {
3167 return;
3168 }
3169
3170 $cnt = 0;
3171 $dbResult = $DB->Query(
3172 "SELECT COUNT(ID) as CNT ".
3173 "FROM b_sonet_user2group ".
3174 "WHERE USER_ID = ".$userID." ".
3175 " AND ROLE = '".$DB->ForSql(UserToGroupTable::ROLE_REQUEST, 1)."' ".
3176 " AND INITIATED_BY_TYPE = '".$DB->ForSql(SONET_INITIATED_BY_GROUP, 1)."' "
3177 );
3178 if ($arResult = $dbResult->Fetch())
3179 {
3180 $cnt = (int)$arResult["CNT"];
3181 }
3182
3183 if ($cnt > 0)
3184 {
3186 }
3187 else
3188 {
3190 }
3191 }
3192
3193 public static function __SpeedFileCreate($userID)
3194 {
3195 global $CACHE_MANAGER;
3196
3197 $userID = (int)$userID;
3198 if ($userID <= 0)
3199 {
3200 return;
3201 }
3202
3203 if ($CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID))
3204 {
3205 $CACHE_MANAGER->Clean("socnet_cg_".$userID);
3206 }
3207 }
3208
3209 public static function __SpeedFileDelete($userID)
3210 {
3211 global $CACHE_MANAGER;
3212
3213 $userID = (int)$userID;
3214 if ($userID <= 0)
3215 {
3216 return;
3217 }
3218
3219 if (!$CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID))
3220 {
3221 $CACHE_MANAGER->Set("socnet_cg_".$userID, true);
3222 }
3223 }
3224
3225 public static function SpeedFileExists($userID): bool
3226 {
3227 global $CACHE_MANAGER;
3228
3229 $userID = (int)$userID;
3230 if ($userID <= 0)
3231 {
3232 return false;
3233 }
3234
3235 return (!$CACHE_MANAGER->Read(86400*30, "socnet_cg_".$userID));
3236 }
3237
3238 /* Module IM callback */
3239 public static function OnBeforeConfirmNotify($module, $tag, $value)
3240 {
3241 global $USER;
3242
3243 if ($module === "socialnetwork")
3244 {
3245 $arTag = explode("|", $tag);
3246 if (
3247 count($arTag) === 4
3248 && $arTag[1] === 'INVITE_GROUP'
3249 )
3250 {
3251 if ($value === 'Y')
3252 {
3253 self::UserConfirmRequestToBeMember($arTag[2], $arTag[3]);
3254 }
3255 else
3256 {
3257 self::UserRejectRequestToBeMember($arTag[2], $arTag[3]);
3258 }
3259 return true;
3260 }
3261
3262 if (
3263 count($arTag) === 6
3264 && $arTag[1] === "REQUEST_GROUP"
3265 )
3266 {
3267 if ($value === "Y")
3268 {
3269 self::ConfirmRequestToBeMember($USER->GetID(), $arTag[3], array($arTag[4]));
3270 }
3271 else
3272 {
3273 self::RejectRequestToBeMember($USER->GetID(), $arTag[3], array($arTag[4]));
3274 }
3275
3276 if (Loader::includeModule('im'))
3277 {
3278 CIMNotify::DeleteBySubTag("SOCNET|REQUEST_GROUP|".$arTag[2]."|".$arTag[3]."|".$arTag[4]);
3279 }
3280
3281 return true;
3282 }
3283 }
3284
3285 return null;
3286 }
3287
3288 public static function NotifyImToModerators($arNotifyParams): void
3289 {
3290 if (!Loader::includeModule('im'))
3291 {
3292 return;
3293 }
3294
3295 if (
3296 !is_array($arNotifyParams)
3297 || !isset(
3298 $arNotifyParams["TYPE"],
3299 $arNotifyParams["USER_ID"],
3300 $arNotifyParams["GROUP_ID"],
3301 $arNotifyParams["RELATION_ID"],
3302 $arNotifyParams["GROUP_NAME"]
3303 )
3304 || (int)$arNotifyParams["USER_ID"] <= 0
3305 || (int)$arNotifyParams["GROUP_ID"] <= 0
3306 || (int)$arNotifyParams["RELATION_ID"] <= 0
3307 || (string)$arNotifyParams["GROUP_NAME"] === ''
3308 || !in_array($arNotifyParams["TYPE"], [
3309 "join",
3310 "unjoin",
3311 "exclude",
3312 "moderate",
3313 "unmoderate",
3314 "owner"
3315 ], true)
3316 )
3317 {
3318 return;
3319 }
3320
3321 $fromUserId = false;
3322 $messageCode = false;
3323 $schemaCode = false;
3324 $notifyTag = false;
3325
3326 switch ($arNotifyParams["TYPE"])
3327 {
3328 case "join":
3329 $fromUserId = $arNotifyParams["USER_ID"];
3330 $messageCode = "SONET_UG_IM_JOIN";
3331 $schemaCode = "inout_group";
3332 $notifyTag = "INOUT_GROUP";
3333 break;
3334 case "unjoin":
3335 $fromUserId = $arNotifyParams["USER_ID"];
3336 $messageCode = "SONET_UG_IM_UNJOIN";
3337 $schemaCode = "inout_group";
3338 $notifyTag = "INOUT_GROUP";
3339 break;
3340 case "exclude":
3341 $fromUserId = $arNotifyParams["USER_ID"];
3342 $messageCode = "SONET_UG_IM_EXCLUDE";
3343 $schemaCode = "inout_group";
3344 $notifyTag = "INOUT_GROUP";
3345 break;
3346 case "moderate":
3347 $fromUserId = $arNotifyParams["USER_ID"];
3348 $messageCode = "SONET_UG_IM_MODERATE";
3349 $schemaCode = "moderators_group";
3350 $notifyTag = "MOD_GROUP";
3351 break;
3352 case "unmoderate":
3353 $fromUserId = $arNotifyParams["USER_ID"];
3354 $messageCode = "SONET_UG_IM_UNMODERATE";
3355 $schemaCode = "moderators_group";
3356 $notifyTag = "MOD_GROUP";
3357 break;
3358 case "owner":
3359 $fromUserId = $arNotifyParams["USER_ID"];
3360 $messageCode = "SONET_UG_IM_OWNER";
3361 $schemaCode = "owner_group";
3362 $notifyTag = "OWNER_GROUP";
3363 break;
3364 default:
3365 }
3366
3367 $gender_suffix = "";
3368 $rsUser = CUser::GetByID($arNotifyParams["USER_ID"]);
3369 if ($arUser = $rsUser->Fetch())
3370 {
3371 switch ($arUser["PERSONAL_GENDER"])
3372 {
3373 case "M":
3374 $gender_suffix = "_M";
3375 break;
3376 case "F":
3377 $gender_suffix = "_F";
3378 break;
3379 default:
3380 $gender_suffix = "";
3381 }
3382 }
3383
3384 $arToUserID = [];
3385
3386 $rsUserToGroup = CSocNetUserToGroup::GetList(
3387 array(),
3388 array(
3389 "GROUP_ID" => $arNotifyParams["GROUP_ID"],
3390 "USER_ACTIVE" => "Y",
3392 ),
3393 false,
3394 false,
3395 array("USER_ID")
3396 );
3397 while ($arUserToGroup = $rsUserToGroup->Fetch())
3398 {
3399 $arToUserID[] = (int)$arUserToGroup["USER_ID"];
3400 }
3401
3402 $arMessageFields = array(
3403 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
3404 "FROM_USER_ID" => $fromUserId,
3405 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
3406 "NOTIFY_MODULE" => "socialnetwork",
3407 "NOTIFY_EVENT" => $schemaCode,
3408 "NOTIFY_TAG" => "SOCNET|" . $notifyTag . "|" . (int)$arNotifyParams["USER_ID"]
3409 . "|" . (int)$arNotifyParams["GROUP_ID"] . "|" . (int)$arNotifyParams["RELATION_ID"],
3410 );
3411
3412 $groups_path = COption::GetOptionString("socialnetwork", "workgroups_page", SITE_DIR."workgroups/");
3413 $group_url_template = str_replace(
3414 $groups_path,
3415 "#GROUPS_PATH#",
3416 Path::get('group_path_template')
3417 );
3418
3419 $groupUrl = str_replace(
3420 "#group_id#",
3421 $arNotifyParams["GROUP_ID"],
3422 $group_url_template
3423 );
3424
3425 foreach ($arToUserID as $to_user_id)
3426 {
3427 if (
3428 $to_user_id === (int)$fromUserId
3429 || (
3430 is_array($arNotifyParams["EXCLUDE_USERS"] ?? null)
3431 && in_array($to_user_id, $arNotifyParams["EXCLUDE_USERS"])
3432 )
3433 )
3434 {
3435 continue;
3436 }
3437
3438 $arMessageFields["TO_USER_ID"] = $to_user_id;
3440 array(
3441 "GROUP_PAGE" => $groupUrl
3442 ),
3443 $to_user_id,
3444 SITE_ID
3445 );
3446
3447 $arMessageFields["NOTIFY_MESSAGE"] = fn (?string $languageId = null) =>
3448 Loc::getMessage(
3449 $messageCode.$gender_suffix,
3450 [
3451 "#group_name#" => "<a href=\"".$arTmp["URLS"]["GROUP_PAGE"]."\" class=\"bx-notifier-item-action\">".$arNotifyParams["GROUP_NAME"]."</a>",
3452 ],
3453 $languageId
3454 );
3455
3456 $arMessageFields["NOTIFY_MESSAGE_OUT"] = fn (?string $languageId = null) =>
3457 Loc::getMessage(
3458 $messageCode.$gender_suffix,
3459 [
3460 "#group_name#" => $arNotifyParams["GROUP_NAME"],
3461 ],
3462 $languageId
3463 )
3464 ." (".$arTmp["SERVER_NAME"].$arTmp["URLS"]["GROUP_PAGE"].")"
3465 ;
3466
3467 CIMNotify::Add($arMessageFields);
3468 }
3469 }
3470
3471 public static function getMessage($message)
3472 {
3473 return Loc::getMessage($message);
3474 }
3475
3476 public static function notifyModeratorAdded($params): void
3477 {
3478 static $groupCache = array();
3479
3480 $userId = (!empty($params['userId']) ? (int)$params['userId'] : 0);
3481 $relationFields = (!empty($params['relationFields']) && is_array($params['relationFields']) ? $params['relationFields'] : array());
3482 $groupFields = (!empty($params['groupFields']) && is_array($params['groupFields']) ? $params['groupFields'] : array());
3483 $groupId = (
3484 !empty($params['groupId'])
3485 ? (int)$params['groupId']
3486 : (!empty($groupFields['ID']) ? (int)$groupFields['ID'] : 0)
3487 );
3488 $relationId = (
3489 !empty($params['relationId'])
3490 ? (int)$params['relationId']
3491 : (!empty($relationFields['ID']) ? (int)$relationFields['ID'] : 0)
3492 );
3493
3494 if (
3495 empty($groupFields)
3496 && $groupId > 0
3497 )
3498 {
3499 if (isset($groupCache[$groupId]))
3500 {
3501 $groupFields = $groupCache[$groupId];
3502 }
3503 else
3504 {
3505 $res = WorkgroupTable::getList(array(
3506 'filter' => array(
3507 '=ID' => $groupId
3508 ),
3509 'select' => array('ID', 'NAME', 'SITE_ID')
3510 ));
3511 $groupFields = $groupCache[$groupId] = $res->fetch();
3512 }
3513 }
3514
3515 if (
3516 empty($relationFields)
3517 && $relationId > 0
3518 )
3519 {
3520 $res = UserToGroupTable::getList(array(
3521 'filter' => array(
3522 '=ID' => $relationId
3523 ),
3524 'select' => array('ID', 'USER_ID')
3525 ));
3526 $relationFields = $res->fetch();
3527 }
3528
3529 if (
3530 $groupId <= 0
3531 || empty($relationFields)
3532 || empty($relationFields['ID'])
3533 || empty($relationFields['USER_ID'])
3534 || empty($groupFields)
3535 || !Loader::includeModule('im')
3536 )
3537 {
3538 return;
3539 }
3540
3541 $groupSiteId = CSocNetGroup::getDefaultSiteId($groupId, $groupFields["SITE_ID"] ?? false);
3542
3543 $workgroupsPage = COption::getOptionString("socialnetwork", "workgroups_page", "/workgroups/", SITE_ID);
3544 $groupUrlTemplate = Path::get('group_path_template');
3545 $groupUrlTemplate = "#GROUPS_PATH#".mb_substr($groupUrlTemplate, mb_strlen($workgroupsPage));
3546 $groupUrl = str_replace(array("#group_id#", "#GROUP_ID#"), $groupId, $groupUrlTemplate);
3547
3548 $arTmp = CSocNetLogTools::processPath(
3549 array(
3550 "GROUP_URL" => $groupUrl
3551 ),
3552 $relationFields["USER_ID"],
3553 $groupSiteId
3554 );
3555 $groupUrl = $arTmp["URLS"]["GROUP_URL"];
3556
3557 $serverName = (
3558 mb_strpos($groupUrl, "http://") === 0
3559 || mb_strpos($groupUrl, "https://") === 0
3560 ? ""
3561 : $arTmp["SERVER_NAME"]
3562 );
3563 $domainName = (
3564 mb_strpos($groupUrl, "http://") === 0
3565 || mb_strpos($groupUrl, "https://") === 0
3566 ? ""
3567 : (
3568 isset($arTmp["DOMAIN"])
3569 && !empty($arTmp["DOMAIN"])
3570 ? "//".$arTmp["DOMAIN"]
3571 : ""
3572 )
3573 );
3574
3575 $arMessageFields = array(
3576 "TO_USER_ID" => $relationFields["USER_ID"],
3577 "FROM_USER_ID" => $userId,
3578 "NOTIFY_TYPE" => IM_NOTIFY_FROM,
3579 "NOTIFY_MODULE" => "socialnetwork",
3580 "NOTIFY_EVENT" => "moderators_group",
3581 "NOTIFY_TAG" => "SOCNET|MOD_GROUP|" . $userId . "|".$groupId."|".$relationFields["ID"]."|".$relationFields["USER_ID"],
3582 "NOTIFY_MESSAGE" => fn (?string $languageId = null) =>
3583 Loc::getMessage(
3584 "SONET_UG_MEMBER2MOD_MESSAGE",
3585 ['#NAME#' => "<a href=\"".$domainName.$groupUrl."\" class=\"bx-notifier-item-action\">".$groupFields["NAME"]."</a>"],
3586 $languageId
3587 )
3588 ,
3589 "NOTIFY_MESSAGE_OUT" => fn (?string $languageId = null) =>
3590 Loc::getMessage(
3591 "SONET_UG_MEMBER2MOD_MESSAGE",
3592 ['#NAME#' => $groupFields["NAME"]],
3593 $languageId
3594 )
3595 ." (".$serverName.$groupUrl.")"
3596 );
3597
3598 CIMNotify::add($arMessageFields);
3599 }
3600
3601 protected static function delayJob(callable $job): void
3602 {
3603 \Bitrix\Main\Application::getInstance()->addBackgroundJob($job, [], static::EVENTS_JOB_PRIORITY);
3604 }
3605}
$connection
Определения actionsdefinitions.php:38
$messageFields
Определения callback_ednaru.php:22
global $APPLICATION
Определения include.php:80
$arResult
Определения generate_coupon.php:16
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
static getInstance()
Определения application.php:98
static getConnection($name="")
Определения application.php:638
Определения error.php:15
Определения event.php:5
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static isModuleInstalled($moduleName)
Определения modulemanager.php:125
Определения emoji.php:10
static normalizeArrayValuesByInt(&$map, $sorted=true)
Определения collection.php:150
static add($recipient, array $parameters, $channelType=\CPullChannel::TYPE_PRIVATE)
Определения event.php:22
static unsetHideRequestPopup(array $params=[])
Определения requestpopup.php:43
static addEvent(string $type, array $data)
Определения counterservice.php:46
static addEvent(string $type, array $data)
Определения service.php:45
static addInfoToChat($params=[])
Определения usertogroup.php:522
static getGroupModerators(int $groupId)
Определения usertogroup.php:220
static AutoSubscribe($userID, $entityType, $entityID)
Определения log_events.php:231
static __SpeedFileDelete($userID)
Определения user_group.php:3209
const LOCK_TIMEOUT
Определения user_group.php:32
static addUniqueUsersToGroup(int $groupId, array $userIds)
Определения user_group.php:465
static ConfirmRequestToBeMember($userId, $groupId, $relationIdList, $autoSubscribe=true)
Определения user_group.php:1254
static BanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin)
Определения user_group.php:2315
static SendRequestToJoinGroup($senderUserId, $userId, $groupId, $message, $sendMail=true)
Определения user_group.php:996
static RejectRequestToBeMember($userId, $groupId, $relationIdList)
Определения user_group.php:1490
static NotifyImToModerators($arNotifyParams)
Определения user_group.php:3288
static SpeedFileExists($userID)
Определения user_group.php:3225
static CheckFields($ACTION, &$relationFields, $id=0)
Определения user_group.php:37
static TransferModerator2Member($userID, $groupId, $relationIdList)
Определения user_group.php:1975
static Delete( $id, $sendExclude=false, bool $skipChatMessage=false, bool $skipStatistics=false, bool $delayEvents=false)
Определения user_group.php:199
static __SpeedFileCheckMessages($userID)
Определения user_group.php:3160
static UnBanMember($userID, $groupId, $relationIdList, $currentUserIsAdmin)
Определения user_group.php:2424
static GetUserRole($userId, $groupId, $extendedReturn=false)
Определения user_group.php:498
static SendRequestToBeMember($userId, $groupId, $message, $requestConfirmUrl="", $autoSubscribe=true)
Определения user_group.php:746
static $roleCache
Определения user_group.php:28
static UserConfirmRequestToBeMember($targetUserID, $relationID, $bAutoSubscribe=true)
Определения user_group.php:1632
static InitUserPerms($userId, $groupFields, $isCurrentUserAdmin)
Определения user_group.php:2959
static DeleteRelation($userId, $groupId)
Определения user_group.php:2859
static SendEvent($userGroupID, $mailTemplate="SONET_INVITE_GROUP")
Определения user_group.php:620
static getMessage($message)
Определения user_group.php:3471
static notifyModeratorAdded($params)
Определения user_group.php:3476
static AddUsersToGroup(int $groupId, array $userIds)
Определения user_group.php:442
static GetGroupUsers(int $groupId)
Определения user_group.php:433
const EVENTS_JOB_PRIORITY
Определения user_group.php:30
static DeleteNoDemand($userId)
Определения user_group.php:361
static GetById($id)
Определения user_group.php:399
static UserRejectRequestToBeMember($targetUserID, $relationID)
Определения user_group.php:1841
static TransferMember2Moderator($userID, $groupId, $relationIdList)
Определения user_group.php:2173
static SetOwner($userId, $groupId, $groupFields=[], bool $skipChatMessage=false)
Определения user_group.php:2532
static delayJob(callable $job)
Определения user_group.php:3601
static OnBeforeConfirmNotify($module, $tag, $value)
Определения user_group.php:3239
static __SpeedFileCreate($userID)
Определения user_group.php:3193
static IsFeatureEnabled($_1488512778)
Определения include.php:116
static ProcessPath($arUrl, $user_id, $explicit_site_id=false)
Определения log_tools.php:5283
static Add($arFields)
Определения messages.php:10
static OnUserRelationsChange($user_id)
Определения search.php:47
global $CACHE_MANAGER
Определения clear_component_cache.php:7
$arFields
Определения dblapprove.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
while($arParentIBlockProperty=$dbParentIBlockProperty->Fetch()) $errorMessage
const IM_MESSAGE_SYSTEM
Определения include.php:21
const IM_NOTIFY_SYSTEM
Определения include.php:38
const IM_NOTIFY_CONFIRM
Определения include.php:36
const IM_NOTIFY_FROM
Определения include.php:37
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $DB
Определения cron_frame.php:29
global $USER
Определения csv_new_run.php:40
$ACTION
Определения csv_new_setup.php:27
endif
Определения csv_new_setup.php:990
const SITE_DIR(!defined('LANG'))
Определения include.php:72
$siteId
Определения ajax.php:8
ExecuteModuleEventEx($arEvent, $arParams=[])
Определения tools.php:5214
htmlspecialcharsEx($str)
Определения tools.php:2685
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
GetMessage($name, $aReplace=null)
Определения tools.php:3397
if(!function_exists(__NAMESPACE__.'\\___972068685'))
Определения license.php:1
$message
Определения payment.php:8
if(intval($iTestTransaction) > 0) $arTmp
Определения payment.php:22
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
</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
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
const SONET_ENTITY_GROUP
Определения include.php:117
global $arSocNetAllowedSpamPerms
Определения include.php:105
global $arSocNetAllowedInitiatePerms
Определения include.php:102
global $arSocNetAllowedInitiatedByType
Определения include.php:114
global $arSocNetAllowedRolesForUserInGroup
Определения include.php:96
const SONET_ROLES_ALL
Определения include.php:35
const SONET_INITIATED_BY_GROUP
Определения include.php:45
const SONET_MESSAGE_SYSTEM
Определения include.php:47
const SONET_INITIATED_BY_USER
Определения include.php:44
const SITE_ID
Определения sonet_set_content_view.php:12
$dbResult
Определения updtr957.php:3
$url
Определения iframe.php:7