Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
usertogroup.php
1<?php
2
10
18use Bitrix\Socialnetwork\Integration;
19
20Loc::loadMessages(__FILE__);
21
23{
24 public const CHAT_ACTION_IN = 'in';
25 public const CHAT_ACTION_OUT = 'out';
26
27 public static function addRelationAutoMembership($params): void
28 {
29 global $USER;
30
31 if (!empty($params['CURRENT_USER_ID']))
32 {
33 $currentUserId = (int)$params['CURRENT_USER_ID'];
34 }
35 elseif (is_object($USER))
36 {
37 $currentUserId = $USER->getId();
38 }
39
40 if ($currentUserId <= 0)
41 {
42 return;
43 }
44
45 static $helper = false;
46
47 $userId = (int)($params['USER_ID'] ?? 0);
48 $groupId = (int)($params['GROUP_ID'] ?? 0);
49 $value = (isset($params['VALUE']) && in_array($params['VALUE'], WorkgroupTable::getAutoMembershipValuesAll(), true) ? $params['VALUE'] : 'Y');
50 $notyfy = (isset($params['NOTIFY']) && $params['NOTIFY'] === "N" ? $params['NOTIFY'] : 'Y');
51
52 if (
53 $userId <= 0
54 || $groupId <= 0
55 )
56 {
57 return;
58 }
59
60 if (!$helper)
61 {
62 $connection = Application::getConnection();
63 $helper = $connection->getSqlHelper();
64 }
65
66 $addFields = [
67 'AUTO_MEMBER' => $value,
68 'USER_ID' => $userId,
69 'GROUP_ID' => $groupId,
70 'ROLE' => (
71 isset($params['ROLE'])
72 && in_array($params['ROLE'], UserToGroupTable::getRolesAll(), true)
73 ? $params['ROLE']
75 ),
76 'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
77 'INITIATED_BY_USER_ID' => $currentUserId,
78 '=DATE_CREATE' => $helper->getCurrentDateTimeFunction(),
79 '=DATE_UPDATE' => $helper->getCurrentDateTimeFunction(),
80 ];
81
82 $relationId = \CSocNetUserToGroup::add($addFields);
83
84 if (
85 !$notyfy
86 || $relationId <= 0
87 || $value !== 'Y'
88 )
89 {
90 return;
91 }
92
93 self::notifyAutoMembership([
94 'GROUP_ID' => $groupId,
95 'USER_ID' => $userId,
96 'RELATION_ID' => $relationId,
97 ]);
98
99 self::addInfoToChat([
100 'group_id' => $groupId,
101 'user_id' => $userId,
102 'action' => self::CHAT_ACTION_IN,
103 'role' => $addFields['ROLE'],
104 ]);
105 }
106
107 public static function changeRelationAutoMembership($params): void
108 {
109 static $helper = false;
110
111 $relationId = (int)($params['RELATION_ID'] ?? 0);
112 $userId = (int)($params['USER_ID'] ?? 0);
113 $groupId = (int)($params['GROUP_ID'] ?? 0);
114 $value = (
115 isset($params['VALUE'])
116 && in_array($params['VALUE'], WorkgroupTable::getAutoMembershipValuesAll(), true)
117 ? $params['VALUE']
118 : 'Y'
119 );
120 $notyfy = (isset($params['NOTIFY']) && $params['NOTIFY'] === 'N' ? $params['NOTIFY'] : 'Y');
121
122 if ($relationId <= 0)
123 {
124 return;
125 }
126
127 if (!$helper)
128 {
129 $connection = Application::getConnection();
130 $helper = $connection->getSqlHelper();
131 }
132
133 $updateFields = [
134 'AUTO_MEMBER' => $value,
135 '=DATE_UPDATE' => $helper->getCurrentDateTimeFunction(),
136 ];
137 if (
138 isset($params['ROLE'])
139 && in_array($params['ROLE'], UserToGroupTable::getRolesAll(), true)
140 )
141 {
142 $updateFields['ROLE'] = $params['ROLE'];
143 }
144 \CSocNetUserToGroup::update($relationId, $updateFields);
145
146 if (
147 !$notyfy
148 || $userId <= 0
149 || $groupId <= 0
150 || $value !== 'Y'
151 )
152 {
153 return;
154 }
155
156 self::notifyAutoMembership([
157 'GROUP_ID' => $groupId,
158 'USER_ID' => $userId,
159 'RELATION_ID' => $relationId,
160 ]);
161
162 self::addInfoToChat([
163 'group_id' => $groupId,
164 'user_id' => $userId,
165 'action' => self::CHAT_ACTION_IN,
166 'role' => ($params['ROLE'] ?? false),
167 ]);
168 }
169
170 private static function notifyAutoMembership($params): void
171 {
172 $userId = (int)($params['USER_ID'] ?? 0);
173 $groupId = (int)($params['GROUP_ID'] ?? 0);
174 $relationId = (int)($params['RELATION_ID'] ?? 0);
175
176 if (
177 $userId <= 0
178 || $groupId <= 0
179 || $relationId <= 0
180 || !Loader::includeModule('im')
181 )
182 {
183 return;
184 }
185 $groupItem = Workgroup::getById($groupId);
186 $groupFields = $groupItem->getFields();
187 $groupUrlData = $groupItem->getGroupUrlData([
188 'USER_ID' => $userId,
189 ]);
190
191 $messageFields = [
192 "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM,
193 "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,
194 "FROM_USER_ID" => $groupFields["OWNER_ID"],
195 "TO_USER_ID" => $userId,
196 "NOTIFY_MODULE" => "socialnetwork",
197 "NOTIFY_EVENT" => "invite_group",
198 "NOTIFY_TAG" => "SOCNET|INVITE_GROUP|" . $userId . '|' . $relationId,
199 "NOTIFY_MESSAGE" => Loc::getMessage(($groupItem->isProject() ? "SOCIALNETWORK_ITEM_USERTOGROUP_AUTO_MEMBER_ADD_IM_PROJECT" : "SOCIALNETWORK_ITEM_USERTOGROUP_AUTO_MEMBER_ADD_IM"), [
200 "#GROUP_NAME#" => "<a href=\"".$groupUrlData['DOMAIN'] . $groupUrlData['URL'] . "\" class=\"bx-notifier-item-action\">" . htmlspecialcharsEx($groupFields["NAME"]) . '</a>',
201 ]
202 ),
203 "NOTIFY_MESSAGE_OUT" => Loc::getMessage("SOCIALNETWORK_ITEM_USERTOGROUP_AUTO_MEMBER_ADD_IM", [
204 "#GROUP_NAME#" => htmlspecialcharsEx($groupFields["NAME"]),
205 ]
206 ) . ' (' . $groupUrlData['SERVER_NAME'] . $groupUrlData['URL'] . ')'
207 ];
208
209 \CIMNotify::deleteBySubTag('SOCNET|REQUEST_GROUP|' . $userId . '|' . $groupId . '|' . $relationId);
210 \CIMNotify::add($messageFields);
211 }
212
213 public static function onAfterUserAdd(&$fields): void
214 {
215 if (
216 $fields['ID'] <= 0
217 || (
218 isset($fields['ACTIVE'])
219 && $fields['ACTIVE'] !== 'Y'
220 )
221 || !self::checkUF()
222 )
223 {
224 return;
225 }
226
227 $deparmentIdList = [];
228 if (
229 isset($fields['UF_DEPARTMENT'])
230 && is_array($fields['UF_DEPARTMENT'])
231 && (int)$fields['UF_DEPARTMENT'][0] > 0
232 )
233 {
234 $deparmentIdList = $fields['UF_DEPARTMENT'];
235 }
236
237 if (Loader::includeModule('intranet'))
238 {
239 $deparmentIdList = array_merge($deparmentIdList, \CIntranetUtils::getSubordinateDepartments($fields['ID'], false));
240 }
241
242 $deparmentIdList = array_unique($deparmentIdList);
243
244 if (
245 empty($deparmentIdList)
246 || !ModuleManager::isModuleInstalled('intranet')
247 || !Loader::includeModule('iblock')
248 )
249 {
250 return;
251 }
252
253 $groupList = self::getConnectedGroups($deparmentIdList);
254 if (empty($groupList))
255 {
256 return;
257 }
258
259 foreach($groupList as $groupId)
260 {
261 self::addRelationAutoMembership([
262 'USER_ID' => $fields['ID'],
263 'GROUP_ID' => $groupId,
264 'NOTIFY' => 'N',
265 ]);
266 }
267 }
268
269 public static function onAfterUserUpdate(&$userFields): void
270 {
271 if (!self::checkUF())
272 {
273 return;
274 }
275
276 if (
277 (int)$userFields['ID'] <= 0
278 || !isset($userFields['UF_DEPARTMENT'])
279 || !ModuleManager::isModuleInstalled('intranet')
280 || !Loader::includeModule('iblock')
281 )
282 {
283 return;
284 }
285
286 $oldGroupList = [];
287 $oldGroupAutoList = [];
288 $newGroupList = [];
289
290 $res = UserToGroupTable::getList([
291 'filter' => [
292 'USER_ID' => (int)$userFields['ID']
293 ],
294 'select' => [ 'GROUP_ID', 'AUTO_MEMBER' ]
295 ]);
296
297 while($relation = $res->fetch())
298 {
299 $oldGroupList[] = $relation['GROUP_ID'];
300 if ($relation['AUTO_MEMBER'] === 'Y')
301 {
302 $oldGroupAutoList[] = $relation['GROUP_ID'];
303 }
304 }
305 $oldGroupList = array_unique($oldGroupList);
306 $oldGroupAutoList = array_unique($oldGroupAutoList);
307
308 if (
309 !empty($userFields['UF_DEPARTMENT'])
310 && is_array($userFields['UF_DEPARTMENT'])
311 )
312 {
313 $userFields['UF_DEPARTMENT'] = array_values($userFields['UF_DEPARTMENT']);
314 }
315
316 $departmentList = (
317 !is_array($userFields['UF_DEPARTMENT'])
318 || empty($userFields['UF_DEPARTMENT'])
319 || (int)$userFields['UF_DEPARTMENT'][0] <= 0
320 ? []
321 : $userFields['UF_DEPARTMENT']
322 );
323
324 if (Loader::includeModule('intranet'))
325 {
326 $departmentList = array_merge($departmentList, \CIntranetUtils::getSubordinateDepartments($userFields['ID'], false));
327 }
328 $departmentList = array_unique($departmentList);
329
330 if (!empty($departmentList))
331 {
332 $newGroupList = self::getConnectedGroups($departmentList);
333 }
334 $groupListPlus = array_diff($newGroupList, $oldGroupList);
335 $groupListMinus = array_diff($oldGroupAutoList, $newGroupList);
336 $groupListMinus = array_diff($groupListMinus, $groupListPlus);
337
338 if (!empty($groupListMinus))
339 {
340 $res = UserToGroupTable::getList([
341 'filter' => [
342 '=USER_ID' => (int)$userFields['ID'],
343 '@GROUP_ID' => $groupListMinus,
345 'AUTO_MEMBER' => 'Y'
346 ],
347 'select' => [ 'ID' ],
348 ]);
349 while($relation = $res->fetch())
350 {
351 \CSocNetUserToGroup::delete($relation['ID']);
352 }
353 }
354
355 $changeList = $addList = $noChangeList = [];
356 if (!empty($groupListPlus))
357 {
358 $res = UserToGroupTable::getList([
359 'filter' => [
360 '=USER_ID' => (int)$userFields["ID"],
361 '@GROUP_ID' => $groupListPlus,
363 ],
364 'select' => [ 'ID', 'GROUP_ID', 'AUTO_MEMBER' ],
365 ]);
366
367 while ($relation = $res->fetch())
368 {
369 if (
370 $relation['AUTO_MEMBER'] === 'Y'
371 || $relation['ROLE'] === UserToGroupTable::ROLE_OWNER
372 )
373 {
374 $noChangeList[] = $relation['GROUP_ID'];
375 }
376 else // UserToGroupTable::ROLE_MODERATOR, UserToGroupTable::ROLE_USER, AUTO_MEMBER = 'N'
377 {
378 $noChangeList[] = $relation['GROUP_ID'];
379 self::changeRelationAutoMembership([
380 'RELATION_ID' => (int)$relation['ID'],
381 'USER_ID' => (int)$userFields["ID"],
382 'GROUP_ID' => (int)$relation['GROUP_ID'],
383 'ROLE' => $relation['ROLE'],
384 'VALUE' => 'Y',
385 'NOTIFY' => 'N',
386 ]);
387 }
388 }
389
390 $groupListPlus = array_diff($groupListPlus, $noChangeList);
391 }
392
393 if (!empty($groupListPlus))
394 {
395 $res = UserToGroupTable::getList([
396 'filter' => [
397 '=USER_ID' => (int)$userFields['ID'],
398 '@GROUP_ID' => $groupListPlus,
400 'AUTO_MEMBER' => 'N',
401 ],
402 'select' => [ 'ID', 'USER_ID', 'GROUP_ID' ],
403 ]);
404
405 while ($relation = $res->fetch())
406 {
407 $changeList[] = (int)$relation['GROUP_ID'];
408 self::changeRelationAutoMembership([
409 'RELATION_ID' => (int)$relation['ID'],
410 'USER_ID' => (int)$relation['USER_ID'],
411 'GROUP_ID' => (int)$relation['GROUP_ID'],
413 'VALUE' => 'Y',
414 ]);
415 }
416 $addList = array_diff($groupListPlus, $changeList);
417 }
418
419 foreach ($addList as $addGroupId)
420 {
421 self::addRelationAutoMembership([
422 'USER_ID' => (int)$userFields['ID'],
423 'GROUP_ID' => $addGroupId,
425 'VALUE' => 'Y',
426 ]);
427 }
428 }
429
430 public static function getConnectedGroups($departmentList): array
431 {
432 static $structureIBlockId = false;
433 static $departmentChainCache = [];
434
435 $result = [];
436
437 if ($structureIBlockId === false)
438 {
439 $structureIBlockId = (int)Option::get('intranet', 'iblock_structure', 0);
440 }
441
442 if ((int)$structureIBlockId <= 0)
443 {
444 return $result;
445 }
446
447 $userDepartmentList = [];
448
449 foreach($departmentList as $departmentId)
450 {
451 $departmentChain = [];
452 if (isset($departmentChainCache[$departmentId]))
453 {
454 $departmentChain = $departmentChainCache[$departmentId];
455 }
456 else
457 {
458 $res = \CIBlockSection::getNavChain($structureIBlockId, $departmentId, [ 'ID' ]);
459 while ($section = $res->fetch())
460 {
461 if ((int)$section['ID'] > 0)
462 {
463 $departmentChain[] = (int)$section['ID'];
464 }
465 }
466 $departmentChainCache[$departmentId] = $departmentChain;
467 }
468 $userDepartmentList = array_merge($userDepartmentList, $departmentChain);
469 }
470
471 $userDepartmentList = array_unique($userDepartmentList);
472
473 if (!empty($userDepartmentList))
474 {
475 $res = WorkgroupTable::getList([
476 'filter' => [
477 '@UF_SG_DEPT' => $userDepartmentList,
478 ],
479 'select' => [ 'ID' ],
480 ]);
481 while ($group = $res->fetch())
482 {
483 if ((int)$group['ID'] > 0)
484 {
485 $result[] = (int)$group['ID'];
486 }
487 }
488 }
489
490 return array_unique($result);
491 }
492
493 private static function checkUF(): bool
494 {
495 $res = \CUserTypeEntity::getList([], [
496 'ENTITY_ID' => 'SONET_GROUP',
497 'FIELD_NAME' => 'UF_SG_DEPT'
498 ]);
499 return ($res && ($res->fetch()));
500 }
501
502 public static function addInfoToChat($params = [])
503 {
504 if (
505 !is_array($params)
506 || !isset($params['group_id'], $params['user_id'], $params['action'])
507 || (int)$params['group_id'] <= 0
508 || (int)$params['user_id'] <= 0
509 || !Integration\Im\Chat\Workgroup::getUseChat()
510 || !Loader::includeModule('im')
511 || !in_array($params['action'], self::getChatActionList(), true)
512 )
513 {
514 return false;
515 }
516
517 $groupId = (int)$params['group_id'];
518 $userId = (int)$params['user_id'];
519 $role = ($params['role'] ?? false);
520
521 $sendMessage = (
522 !isset($params['sendMessage'])
523 || $params['sendMessage']
524 );
525
526 $chatData = Integration\Im\Chat\Workgroup::getChatData([
527 'group_id' => $groupId,
528 'skipAvailabilityCheck' => true,
529 ]);
530
531 if (
532 empty($chatData)
533 || empty($chatData[$groupId])
534 || (int)$chatData[$groupId] <= 0
535 )
536 {
537 return false;
538 }
539
540 $res = \CUser::getById($userId);
541 $user = $res->fetch();
542
543 if (
544 empty($user)
545 || (
546 isset($user['ACTIVE'])
547 && $user['ACTIVE'] === 'N'
548 )
549 )
550 {
551 return false;
552 }
553
554 $groupItem = Workgroup::getById($groupId);
555 $projectSuffix = ($groupItem->isProject() ? '_PROJECT' : '');
556
557 $userName = \CUser::formatName(\CSite::getNameFormat(), $user, true, false);
558 switch($user['PERSONAL_GENDER'])
559 {
560 case "M":
561 $genderSuffix = '_M';
562 break;
563 case "F":
564 $genderSuffix = '_F';
565 break;
566 default:
567 $genderSuffix = '';
568 }
569
570 $chatId = $chatData[$groupId];
571 $chat = new \CIMChat(0);
572
573 switch ($params['action'])
574 {
575 case self::CHAT_ACTION_IN:
576 if ($chat->addUser($chatId, $userId, false, true, true))
577 {
578 if ($role === UserToGroupTable::ROLE_USER)
579 {
580 \Bitrix\Im\Chat::mute($chatId, true, $userId);
581 }
582 $chatMessage = str_replace('#USER_NAME#', $userName, Loc::getMessage('SOCIALNETWORK_ITEM_USERTOGROUP_CHAT_USER_ADD' . $projectSuffix . $genderSuffix));
583 }
584 else
585 {
586 $sendMessage = false;
587 }
588 break;
589 case self::CHAT_ACTION_OUT:
590 if ($chat->deleteUser($chatId, $userId, false, true))
591 {
592 $chatMessage = str_replace('#USER_NAME#', $userName, Loc::getMessage('SOCIALNETWORK_ITEM_USERTOGROUP_CHAT_USER_DELETE' . $projectSuffix . $genderSuffix));
593 }
594 else
595 {
596 $sendMessage = false;
597 }
598 break;
599 default:
600 $chatMessage = '';
601 $sendMessage = false;
602 }
603
604 if ($sendMessage)
605 {
606 $chatMessageFields = [
607 "MESSAGE" => $chatMessage,
608 "SYSTEM" => "Y",
609 "INCREMENT_COUNTER" => "N",
610 "PUSH" => "N"
611 ];
612
613 $availableChatData = Integration\Im\Chat\Workgroup::getChatData([
614 'group_id' => $groupId,
615 ]);
616
617 if (
618 !empty($availableChatData)
619 && !empty($availableChatData[$groupId])
620 && (int)$availableChatData[$groupId] > 0
621 )
622 {
623 return \CIMChat::addMessage(array_merge(
624 $chatMessageFields, [
625 'TO_CHAT_ID' => $chatId,
626 ]
627 ));
628 }
629 }
630 else
631 {
632 return true;
633 }
634
635 return false;
636 }
637
638 private static function getChatActionList(): array
639 {
640 return [ self::CHAT_ACTION_IN, self::CHAT_ACTION_OUT ];
641 }
642
643 public static function addModerators($params = []): bool
644 {
645 global $USER;
646
647 $result = false;
648
649 if (
650 !is_array($params)
651 || !isset($params['group_id'], $params['user_id'])
652 || (int)$params['group_id'] <= 0
653 || empty($params['user_id'])
654 )
655 {
656 return $result;
657 }
658
659 $groupId = (int)$params['group_id'];
660 $userIdList = (
661 is_array($params['user_id'])
662 ? $params['user_id']
663 : [ $params['user_id'] ]
664 );
665 $currentUserId = (
666 isset($params['current_user_id'])
667 && (int)$params['current_user_id'] > 0
668 ? (int)$params['current_user_id']
669 : (
670 is_object($USER)
671 && $USER->isAuthorized()
672 ? $USER->getId()
673 : false
674 )
675 );
676
677 if (!$currentUserId)
678 {
679 return $result;
680 }
681
682 $ownerRelationIdList = [];
683 $memberRelationIdList = [];
684 $otherRelationIdList = [];
685
686 $resRelation = UserToGroupTable::getList([
687 'filter' => [
688 'GROUP_ID' => $groupId,
689 '@USER_ID' => $userIdList
690 ],
691 'select' => [ 'ID', 'USER_ID', 'ROLE' ],
692 ]);
693
694 while ($relation = $resRelation->fetch())
695 {
696 if ($relation['ROLE'] === UserToGroupTable::ROLE_USER)
697 {
698 $memberRelationIdList[$relation['USER_ID']] = $relation['ID'];
699 }
700 elseif ($relation['ROLE'] === UserToGroupTable::ROLE_OWNER)
701 {
702 $ownerRelationIdList[$relation['USER_ID']] = $relation['ID'];
703 }
704 else // ban, request
705 {
706 $otherRelationIdList[$relation['USER_ID']] = $relation['ID'];
707 }
708 }
709
710 if (!empty($memberRelationIdList))
711 {
712 \CSocNetUserToGroup::transferMember2Moderator($currentUserId, $groupId, $memberRelationIdList);
713 }
714
715 foreach ($userIdList as $userId)
716 {
717 if (
718 !array_key_exists($userId, $memberRelationIdList)
719 && !array_key_exists($userId, $ownerRelationIdList)
720 )
721 {
722 if (array_key_exists($userId, $otherRelationIdList))
723 {
724 $relationId = \CSocNetUserToGroup::update($otherRelationIdList[$userId], [
726 '=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
727 ]);
728 }
729 else
730 {
731 $relationId = \CSocNetUserToGroup::add([
732 'USER_ID' => $userId,
733 'GROUP_ID' => $groupId,
735 '=DATE_CREATE' => \CDatabase::CurrentTimeFunction(),
736 '=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
737 'MESSAGE' => '',
738 'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
739 'INITIATED_BY_USER_ID' => $currentUserId,
740 'SEND_MAIL' => 'N',
741 ]);
742 }
743
744 if ($relationId)
745 {
746 \CSocNetUserToGroup::notifyModeratorAdded([
747 'userId' => $currentUserId,
748 'groupId' => $groupId,
749 'relationId' => $relationId
750 ]);
751 }
752 }
753 }
754
755 return true;
756 }
757
758}
static getById($postId=0, $params=array())
Definition post.php:35
static getConnection($name="")
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getConnectedGroups($departmentList)