Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
workgroup.php
1<?php
2
10
14use Bitrix\Main\Entity\Query;
23use Bitrix\Socialnetwork\EO_WorkgroupPin;
32
34{
35 public static function getSprintDurationList(): array
36 {
37 static $result = null;
38
39 if ($result === null)
40 {
41 $oneWeek = \DateInterval::createFromDateString('1 week')->format('%d') * 86400;
42 $twoWeek = \DateInterval::createFromDateString('2 weeks')->format('%d') * 86400;
43 $threeWeek = \DateInterval::createFromDateString('3 weeks')->format('%d') * 86400;
44 $fourWeek = \DateInterval::createFromDateString('4 weeks')->format('%d') * 86400;
45
46 $result = [
47 $oneWeek => [
48 'TITLE' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_SPRINT_DURATION_ONE_WEEK'),
49 ],
50 $twoWeek => [
51 'TITLE' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_SPRINT_DURATION_TWO_WEEK'),
52 'DEFAULT' => true,
53 ],
54 $threeWeek => [
55 'TITLE' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_SPRINT_DURATION_THREE_WEEK'),
56 ],
57 $fourWeek => [
58 'TITLE' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_SPRINT_DURATION_FOUR_WEEK'),
59 ],
60 ];
61 }
62
63 return $result;
64 }
65
66 public static function getSprintDurationValues(): array
67 {
68 $list = static::getSprintDurationList();
69
70 $result = [];
71 foreach ($list as $key => $item)
72 {
73 $result[$key] = $item['TITLE'];
74 }
75
76 return $result;
77 }
78
79 public static function getSprintDurationDefaultKey()
80 {
81 $list = static::getSprintDurationList();
82 $result = array_key_first($list);
83 foreach ($list as $key => $item)
84 {
85 if (
86 isset($item['DEFAULT'])
87 && $item['DEFAULT'] === true
88 )
89 {
90 $result = $key;
91 break;
92 }
93 }
94
95 return $result;
96 }
97
98 public static function getScrumTaskResponsibleList(): array
99 {
100 return [
101 'A' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_TASK_RESPONSIBLE_AUTHOR'),
102 'M' => Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_TYPE_PROJECT_SCRUM_TASK_RESPONSIBLE_MASTER')
103 ];
104 }
105
106 public static function getTypeCodeByParams($params)
107 {
108 $result = false;
109
110 if (empty($params['fields']))
111 {
112 return $result;
113 }
114
115 $typesList = (
116 !empty($params['typesList'])
117 ? $params['typesList']
118 : self::getTypes($params)
119 );
120
121 foreach ($typesList as $code => $type)
122 {
123 if (
124 (
125 !isset($params['fields']['OPENED'])
126 || $params['fields']['OPENED'] === $type['OPENED']
127 )
128 && (
129 !isset($params['fields']['VISIBLE'])
130 || $params['fields']['VISIBLE'] === $type['VISIBLE']
131 )
132 && $params['fields']['PROJECT'] === $type['PROJECT']
133 && $params['fields']['EXTERNAL'] === $type['EXTERNAL']
134 && (
135 !isset($params['fields']['SCRUM_PROJECT'])
136 || (
137 isset($type['SCRUM_PROJECT'])
138 && $params['fields']['SCRUM_PROJECT'] === $type['SCRUM_PROJECT']
139 )
140 )
141 )
142 {
143 $result = $code;
144 break;
145 }
146 }
147
148 return $result;
149 }
150
151 public static function getProjectTypeCodeByParams($params)
152 {
153 $result = false;
154
155 if (empty($params['fields']))
156 {
157 return $result;
158 }
159
160 $typesList = (
161 !empty($params['typesList'])
162 ? $params['typesList']
163 : static::getProjectPresets($params)
164 );
165
166 foreach ($typesList as $code => $type)
167 {
168 if (
169 ($params['fields']['PROJECT'] ?? '') === ($type['PROJECT'] ?? '')
170 && $params['fields']['SCRUM_PROJECT'] === $type['SCRUM_PROJECT']
171 )
172 {
173 $result = $code;
174 break;
175 }
176 }
177
178 return $result;
179 }
180
181 public static function getConfidentialityTypeCodeByParams($params)
182 {
183 $result = false;
184
185 if (empty($params['fields']))
186 {
187 return $result;
188 }
189
190 $typesList = (
191 !empty($params['typesList'])
192 ? $params['typesList']
193 : self::getConfidentialityPresets($params)
194 );
195
196 foreach ($typesList as $code => $type)
197 {
198 if (
199 ($params['fields']['OPENED'] ?? '') === ($type['OPENED'] ?? '')
200 && (
201 isset($params['fields']['VISIBLE'])
202 && $params['fields']['VISIBLE'] === $type['VISIBLE']
203 )
204 && ($params['fields']['PROJECT'] ?? '') === ($type['PROJECT'] ?? '')
205 )
206 {
207 $result = $code;
208 break;
209 }
210 }
211
212 return $result;
213 }
214
215 public static function getTypeByCode($params = [])
216 {
217 $result = false;
218
219 if (
220 !is_array($params)
221 || empty($params['code'])
222 )
223 {
224 return $result;
225 }
226
227 $code = $params['code'];
228 $typesList = (
229 !empty($params['typesList'])
230 ? $params['typesList']
231 : self::getTypes($params)
232 );
233
234 if (
235 !empty($typesList)
236 && is_array($typesList)
237 && !empty($typesList[$code])
238 )
239 {
240 $result = $typesList[$code];
241 }
242
243 return $result;
244 }
245
246 public static function getEditFeaturesAvailability()
247 {
248 static $result = null;
249
250 if ($result !== null)
251 {
252 return $result;
253 }
254
255 $result = true;
256
257 if (!ModuleManager::isModuleInstalled('bitrix24'))
258 {
259 return $result;
260 }
261
262 if (\CBitrix24::isNfrLicense())
263 {
264 return $result;
265 }
266
267 if (\CBitrix24::isDemoLicense())
268 {
269 return $result;
270 }
271
272 if (
273 \CBitrix24::getLicenseType() !== 'project'
274 || !Option::get('socialnetwork', 'demo_edit_features', false)
275 )
276 {
277 return $result;
278 }
279
280 $result = false; // static!
281
282 return $result;
283 }
284
290 public static function getByFeatureOperation(array $params = []): array
291 {
292 global $USER, $CACHE_MANAGER;
293
294 $result = [];
295
296 $feature = (string)($params['feature'] ?? '');
297 $operation = (string)($params['operation'] ?? '');
298 $userId = (int)(
299 isset($params['userId'])
300 ? (int)$params['userId']
301 : (is_object($USER) && $USER instanceof \CUser ? $USER->getId() : 0)
302 );
303
304 if (
305 $feature === ''
306 || $operation === ''
307 || $userId <= 0
308 )
309 {
310 return $result;
311 }
312
313 $featuresSettings = \CSocNetAllowed::getAllowedFeatures();
314 if (
315 empty($featuresSettings)
316 || empty($featuresSettings[$feature])
317 || empty($featuresSettings[$feature]['allowed'])
318 || empty($featuresSettings[$feature]['operations'])
319 || empty($featuresSettings[$feature]['operations'][$operation])
320 || empty($featuresSettings[$feature]['operations'][$operation][FeatureTable::FEATURE_ENTITY_TYPE_GROUP])
321 || !in_array(FeatureTable::FEATURE_ENTITY_TYPE_GROUP, $featuresSettings[$feature]['allowed'], true)
322 )
323 {
324 return $result;
325 }
326
327 $cacheTTL = 3600 * 24 * 30;
328 $cacheDir = '/sonet/features_perms/' . FeatureTable::FEATURE_ENTITY_TYPE_GROUP . '/list/' . (int)($userId / 1000);
329 $cacheId = implode(' ', [ 'entities_list', $feature, $operation, $userId ]);
330
331 $cache = new \CPHPCache();
332 if ($cache->initCache($cacheTTL, $cacheId, $cacheDir))
333 {
334 $cacheValue = $cache->getVars();
335 if (is_array($cacheValue))
336 {
337 $result = $cacheValue;
338 }
339 }
340 else
341 {
342 $cache->startDataCache();
343 $CACHE_MANAGER->startTagCache($cacheDir);
344
345 $CACHE_MANAGER->registerTag('sonet_group');
346 $CACHE_MANAGER->registerTag('sonet_features');
347 $CACHE_MANAGER->registerTag('sonet_features2perms');
348 $CACHE_MANAGER->registerTag('sonet_user2group');
349
350 $defaultRole = $featuresSettings[$feature]['operations'][$operation][FeatureTable::FEATURE_ENTITY_TYPE_GROUP];
351
352 $query = new \Bitrix\Main\Entity\Query(WorkgroupTable::getEntity());
353 $query->addFilter('=ACTIVE', 'Y');
354
355 if (
356 (
357 !is_array($featuresSettings[$feature]['minoperation'])
358 || !in_array($operation, $featuresSettings[$feature]['minoperation'], true)
359 )
360 && Option::get('socialnetwork', 'work_with_closed_groups', 'N') !== 'Y'
361 )
362 {
363 $query->addFilter('!=CLOSED', 'Y');
364 }
365
366 $query->addSelect('ID');
367
368 $query->registerRuntimeField(
369 '',
370 new \Bitrix\Main\Entity\ReferenceField('F',
371 FeatureTable::getEntity(),
372 [
373 '=ref.ENTITY_TYPE' => new SqlExpression('?s', FeatureTable::FEATURE_ENTITY_TYPE_GROUP),
374 '=ref.ENTITY_ID' => 'this.ID',
375 '=ref.FEATURE' => new SqlExpression('?s', $feature),
376 ],
377 [ 'join_type' => 'LEFT' ]
378 )
379 );
380 $query->addSelect('F.ID', 'FEATURE_ID');
381
382 $query->registerRuntimeField(
383 '',
384 new \Bitrix\Main\Entity\ReferenceField('FP',
385 FeaturePermTable::getEntity(),
386 [
387 '=ref.FEATURE_ID' => 'this.FEATURE_ID',
388 '=ref.OPERATION_ID' => new SqlExpression('?s', $operation),
389 ],
390 [ 'join_type' => 'LEFT' ]
391 )
392 );
393
394 $query->registerRuntimeField(new \Bitrix\Main\Entity\ExpressionField(
395 'PERM_ROLE_CALCULATED',
396 'CASE WHEN %s IS NULL THEN \''.$defaultRole.'\' ELSE %s END',
397 [ 'FP.ROLE', 'FP.ROLE' ]
398 ));
399
400 $query->registerRuntimeField(
401 '',
402 new \Bitrix\Main\Entity\ReferenceField('UG',
403 UserToGroupTable::getEntity(),
404 [
405 '=ref.GROUP_ID' => 'this.ID',
406 '=ref.USER_ID' => new SqlExpression($userId),
407 ],
408 [ 'join_type' => 'LEFT' ]
409 )
410 );
411
412 $query->registerRuntimeField(new \Bitrix\Main\Entity\ExpressionField(
413 'HAS_ACCESS',
414 'CASE
415 WHEN
416 (
418 OR %s >= %s
419 ) THEN \'Y\'
420 ELSE \'N\'
421 END',
422 [
423 'PERM_ROLE_CALCULATED',
424 'PERM_ROLE_CALCULATED', 'UG.ROLE',
425 ]
426 ));
427
428 $query->addFilter('=HAS_ACCESS', 'Y');
429
430 $res = $query->exec();
431
432 while ($row = $res->fetch())
433 {
434 $result[] = [
435 'ID' => (int) $row['ID']
436 ];
437 }
438
439 $CACHE_MANAGER->endTagCache();
440 $cache->endDataCache($result);
441 }
442
443 return $result;
444 }
445
446 public static function checkAnyOpened(array $idList = []): bool
447 {
448 if (empty($idList))
449 {
450 return false;
451 }
452
453 $res = WorkgroupTable::getList([
454 'filter' => [
455 '@ID' => $idList,
456 '=OPENED' => 'Y',
457 '=VISIBLE' => 'Y',
458 ],
459 'select' => [ 'ID' ],
460 'limit' => 1,
461 ]);
462 if ($res->fetch())
463 {
464 return true;
465 }
466
467 return false;
468 }
469
470 public static function getPermissions(array $params = []): array
471 {
472 global $USER, $APPLICATION;
473
474 static $result = [];
475
476 $userId = (int)($params['userId'] ?? (is_object($USER) ? $USER->getId() : 0));
477 $groupId = (int)($params['groupId'] ?? 0);
478 if ($groupId <= 0)
479 {
480 $APPLICATION->throwException('Empty workgroup Id', 'SONET_HELPER_WORKGROUP_EMPTY_GROUP');
481 }
482
483 if (
484 empty($result[$userId] ?? null)
485 || !($result[$userId][$groupId] ?? null)
486 )
487 {
488 $group = Item\Workgroup::getById($groupId);
489 if (!$group)
490 {
491 return self::getEmptyPermissions();
492 }
493 $groupFields = $group->getFields();
494 if (empty($groupFields))
495 {
496 return self::getEmptyPermissions();
497 }
498
499 $result[$userId][$groupId] = \CSocNetUserToGroup::initUserPerms(
500 $userId,
501 $groupFields,
502 \CSocNetUser::isCurrentUserModuleAdmin(),
503 );
504 }
505
506 if (is_array($result[$userId][$groupId]))
507 {
508 return $result[$userId][$groupId];
509 }
510
511 return self::getEmptyPermissions();
512 }
513
514 public static function getEmptyPermissions(): array
515 {
516 return [
517 'Operations' => false,
518 'UserRole' => false,
519 'UserIsMember' => false,
520 'UserIsAutoMember' => false,
521 'InitiatedByType' => false,
522 'InitiatedByUserId' => false,
523 'UserIsOwner' => false,
524 'UserIsScrumMaster' => false,
525 'UserCanInitiate' => false,
526 'UserCanProcessRequestsIn' => false,
527 'UserCanViewGroup' => false,
528 'UserCanAutoJoinGroup' => false,
529 'UserCanModifyGroup' => false,
530 'UserCanModerateGroup' => false,
531 'UserCanSpamGroup' => false,
532 ];
533 }
534
535 public static function isGroupCopyFeatureEnabled(): bool
536 {
537 return
538 !ModuleManager::isModuleInstalled('bitrix24')
539 || (
540 Loader::includeModule('bitrix24')
541 && \Bitrix\Bitrix24\Feature::isFeatureEnabled('socnet_group_copy')
542 )
543 ;
544 }
545
546 public static function setArchive(array $fields = []): bool
547 {
548 global $APPLICATION;
549
550 if (!isset($fields['archive']))
551 {
552 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
553 }
554
555 $groupId = (int)($fields['groupId'] ?? 0);
556 $archive = (bool)$fields['archive'];
557 $currentUserId = User::getCurrentUserId();
558
559 if ($groupId <= 0)
560 {
561 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
562 }
563
564 $filter = [
565 'ID' => $groupId,
566 ];
567
568 $isCurrentUserAdmin = static::isCurrentUserModuleAdmin();
569
570 if (!$isCurrentUserAdmin)
571 {
572 $filter['CHECK_PERMISSIONS'] = $currentUserId;
573 }
574
575 $res = \CSocNetGroup::getList([], $filter);
576 if (!($groupFields = $res->fetch()))
577 {
578 throw new ObjectNotFoundException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_GROUP_NO_FOUND'));
579 }
580
582 'groupId' => $groupId,
583 ]))
584 {
585 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
586 }
587
588 if (!\CSocNetGroup::update($groupId, [ 'CLOSED' => ($archive ? 'Y' : 'N') ], false, true, false))
589 {
590 if ($ex = $APPLICATION->getException())
591 {
592 $errorMessage = $ex->getString();
593 $errorCode = $ex->getId();
594 }
595 else
596 {
597 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
598 $errorCode = 100;
599 }
600
601 throw new SystemException($errorMessage, $errorCode);
602 }
603
604 return true;
605 }
606
607 public static function setOwner(array $fields = []): bool
608 {
609 global $APPLICATION;
610
611 $groupId = (int) ($fields['groupId'] ?? 0);
612 $newOwnerId = (int) ($fields['userId'] ?? 0);
613 $currentUserId = User::getCurrentUserId();
614
615 if ($groupId <= 0)
616 {
617 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
618 }
619
620 if ($newOwnerId <= 0)
621 {
622 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
623 }
624
625 $filter = [
626 'ID' => $groupId,
627 ];
628
629 $isCurrentUserAdmin = static::isCurrentUserModuleAdmin();
630
631 if (!$isCurrentUserAdmin)
632 {
633 $filter['CHECK_PERMISSIONS'] = $currentUserId;
634 }
635
636 $res = \CSocNetGroup::getList([], $filter);
637 if (!($groupFields = $res->fetch()))
638 {
639 throw new ObjectNotFoundException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_GROUP_NO_FOUND'));
640 }
641
642 $groupPerms = static::getPermissions([
643 'groupId' => $groupId,
644 ]);
645
646 if (!$groupPerms['UserCanModifyGroup'])
647 {
648 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
649 }
650
651 if (!\CSocNetUserToGroup::setOwner($newOwnerId, $groupFields['ID'], $groupFields))
652 {
653 if ($ex = $APPLICATION->getException())
654 {
655 $errorMessage = $ex->getString();
656 }
657 else
658 {
659 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
660 }
661
662 throw new \Exception($errorMessage, 100);
663 }
664
665 return true;
666 }
667
668 public static function setScrumMaster(array $fields = []): bool
669 {
670 $groupId = (int)($fields['groupId'] ?? 0);
671 $newScrumMasterId = (int)($fields['userId'] ?? 0);
672 $currentUserId = User::getCurrentUserId();
673
674 if ($groupId <= 0)
675 {
676 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
677 }
678
679 if ($newScrumMasterId <= 0)
680 {
681 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
682 }
683
685 'userId' => $newScrumMasterId,
686 'groupId' => $groupId,
687 ]))
688 {
689 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
690 }
691
692 if (!\CSocNetGroup::Update($groupId, [
693 'SCRUM_MASTER_ID' => $newScrumMasterId,
694 ]))
695 {
696 throw new \Exception(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'), 100);
697 }
698
699 $relation = UserToGroupTable::getList([
700 'filter' => [
701 'USER_ID' => $newScrumMasterId,
702 'GROUP_ID' => $groupId,
703 ],
704 'select' => [ 'ID', 'ROLE' ]
705 ])->fetchObject();
706
707 if ($relation)
708 {
709 if (
710 !in_array($relation->getRole(), [UserToGroupTable::ROLE_OWNER, UserToGroupTable::ROLE_MODERATOR], true)
711 && !\CSocNetUserToGroup::Update($relation->getId(), [
713 ])
714 )
715 {
716 throw new \Exception(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'), 100);
717 }
718 }
719 else
720 {
721 static $helper = null;
722 if (!$helper)
723 {
724 $connection = Application::getConnection();
725 $helper = $connection->getSqlHelper();
726 }
727
728 if (!\CSocNetUserToGroup::Add([
729 'AUTO_MEMBER' => 'N',
730 'USER_ID' => $newScrumMasterId,
731 'GROUP_ID' => $groupId,
733 'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
734 'INITIATED_BY_USER_ID' => $currentUserId,
735 '=DATE_CREATE' => $helper->getCurrentDateTimeFunction(),
736 '=DATE_UPDATE' => $helper->getCurrentDateTimeFunction(),
737 ]))
738 {
739 throw new \RuntimeException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'), 100);
740 }
741 }
742
743 return true;
744 }
745
746 public static function setModerator(array $fields = []): bool
747 {
748 global $APPLICATION;
749
750 $groupId = (int)($fields['groupId'] ?? 0);
751 $userId = (int)($fields['userId'] ?? 0);
752 $currentUserId = User::getCurrentUserId();
753
754 if ($groupId <= 0)
755 {
756 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
757 }
758
759 if ($userId <= 0)
760 {
761 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
762 }
763
764 try
765 {
766 $relation = static::getRelation([
767 '=GROUP_ID' => $groupId,
768 '=USER_ID' => $userId,
769 ]);
770 }
771 catch (\Exception $e)
772 {
773 throw new \Exception($e->getMessage(), $e->getCode());
774 }
775
777 'userId' => $userId,
778 'groupId' => $groupId,
779 ]))
780 {
781 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
782 }
783
784 if (!\CSocNetUserToGroup::transferMember2Moderator(
785 $currentUserId,
786 $groupId,
787 [ $relation->getId() ]
788 ))
789 {
790 if ($ex = $APPLICATION->getException())
791 {
792 $errorMessage = $ex->getString();
793 }
794 else
795 {
796 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
797 }
798
799 throw new \Exception($errorMessage, 100);
800 }
801
802 return true;
803 }
804
805 public static function removeModerator(array $fields = []): bool
806 {
807 global $APPLICATION;
808
809 $groupId = (int)($fields['groupId'] ?? 0);
810 $userId = (int)($fields['userId'] ?? 0);
811 $currentUserId = User::getCurrentUserId();
812
813 if ($groupId <= 0)
814 {
815 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
816 }
817
818 if ($userId <= 0)
819 {
820 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
821 }
822
823 try
824 {
825 $relation = static::getRelation([
826 '=GROUP_ID' => $groupId,
827 '=USER_ID' => $userId,
828 ]);
829 }
830 catch (\Exception $e)
831 {
832 throw new \Exception($e->getMessage(), $e->getCode());
833 }
834
836 'userId' => $userId,
837 'groupId' => $groupId,
838 ]))
839 {
840 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
841 }
842
843 if (!\CSocNetUserToGroup::TransferModerator2Member(
844 $currentUserId,
845 $groupId,
846 [ $relation->getId() ]
847 ))
848 {
849 if ($ex = $APPLICATION->getException())
850 {
851 $errorMessage = $ex->getString();
852 }
853 else
854 {
855 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
856 }
857
858 throw new \Exception($errorMessage, 100);
859 }
860
861 return true;
862 }
863
864 public static function setModerators(array $fields = []): bool
865 {
866 $groupId = (int)($fields['groupId'] ?? 0);
867 $userIds = array_map('intval', array_filter($fields['userIds'] ?? []));
868
869 if ($groupId <= 0)
870 {
871 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
872 }
873
874 $currentUserId = User::getCurrentUserId();
875 $isCurrentUserModuleAdmin = static::isCurrentUserModuleAdmin();
876
877 $groupPerms = static::getPermissions(['groupId' => $groupId]);
878 if (!$groupPerms || (!$groupPerms['UserCanModifyGroup'] && !$isCurrentUserModuleAdmin))
879 {
880 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
881 }
882
883 $currentModeratorRelations = static::getCurrentModeratorRelations($groupId);
884 $moderatorsToAdd = array_diff($userIds, array_keys($currentModeratorRelations));
885 $moderatorsToRemove = array_diff_key($currentModeratorRelations, array_fill_keys($userIds, true));
886
887 if (!empty($moderatorsToRemove))
888 {
889 \CSocNetUserToGroup::TransferModerator2Member(
890 $currentUserId,
891 $groupId,
892 $moderatorsToRemove
893 );
894 }
895
896 if (!empty($moderatorsToAdd))
897 {
898 [$ownerRelations, $memberRelations, $otherRelations] = static::getUserRelations($groupId, $moderatorsToAdd);
899
900 if (!empty($memberRelations))
901 {
902 \CSocNetUserToGroup::transferMember2Moderator(
903 $currentUserId,
904 $groupId,
905 $memberRelations
906 );
907 }
908
909 $moderatorsToAdd = array_diff($moderatorsToAdd, array_keys($memberRelations), array_keys($ownerRelations));
910 foreach ($moderatorsToAdd as $userId)
911 {
912 if (array_key_exists($userId, $otherRelations))
913 {
914 $relationId = static::transferToModerators($otherRelations[$userId]);
915 }
916 else
917 {
918 $relationId = static::addToModerators($userId, $groupId);
919 }
920
921 if ($relationId)
922 {
923 static::sendNotifications($userId, $groupId, $relationId);
924 }
925 }
926 }
927
928 return true;
929 }
930
931 private static function getCurrentModeratorRelations(int $groupId): array
932 {
933 $currentModeratorRelations = [];
934
935 $relationResult = UserToGroupTable::getList([
936 'select' => ['ID', 'USER_ID'],
937 'filter' => [
938 'GROUP_ID' => $groupId,
940 ],
941 ]);
942 while ($relation = $relationResult->fetch())
943 {
944 $currentModeratorRelations[$relation['USER_ID']] = $relation['ID'];
945 }
946
947 return $currentModeratorRelations;
948 }
949
950 private static function getUserRelations(int $groupId, array $userIds): array
951 {
952 $ownerRelations = [];
953 $memberRelations = [];
954 $otherRelations = [];
955
956 $relationResult = UserToGroupTable::getList([
957 'select' => ['ID', 'USER_ID', 'ROLE'],
958 'filter' => [
959 'GROUP_ID' => $groupId,
960 '@USER_ID' => $userIds,
961 ],
962 ]);
963 while ($relation = $relationResult->fetch())
964 {
965 $id = $relation['ID'];
966 $userId = $relation['USER_ID'];
967
968 switch ($relation['ROLE'])
969 {
971 $ownerRelations[$userId] = $id;
972 break;
973
975 $memberRelations[$userId] = $id;
976 break;
977
978 default:
979 $otherRelations[$userId] = $id;
980 break;
981 }
982 }
983
984 return [$ownerRelations, $memberRelations, $otherRelations];
985 }
986
987 private static function transferToModerators(int $relationId)
988 {
989 return \CSocNetUserToGroup::update(
990 $relationId,
991 [
993 '=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
994 ]
995 );
996 }
997
998 private static function addToModerators(int $userId, int $groupId)
999 {
1000 return \CSocNetUserToGroup::add([
1001 'USER_ID' => $userId,
1002 'GROUP_ID' => $groupId,
1004 '=DATE_CREATE' => \CDatabase::CurrentTimeFunction(),
1005 '=DATE_UPDATE' => \CDatabase::CurrentTimeFunction(),
1006 'MESSAGE' => '',
1007 'INITIATED_BY_TYPE' => UserToGroupTable::INITIATED_BY_GROUP,
1008 'INITIATED_BY_USER_ID' => User::getCurrentUserId(),
1009 'SEND_MAIL' => 'N',
1010 ]);
1011 }
1012
1013 private static function sendNotifications(int $userId, int $groupId, int $relationId): void
1014 {
1015 \CSocNetUserToGroup::notifyModeratorAdded([
1016 'userId' => User::getCurrentUserId(),
1017 'groupId' => $groupId,
1018 'relationId' => $relationId,
1019 ]);
1020 Item\UserToGroup::addInfoToChat([
1021 'group_id' => $groupId,
1022 'user_id' => $userId,
1023 'action' => Item\UserToGroup::CHAT_ACTION_IN,
1024 'sendMessage' => false,
1026 ]);
1027 }
1028
1029 public static function join(array $fields = []): bool
1030 {
1031 $groupId = (int)($fields['groupId'] ?? 0);
1032 $userId = (int)($fields['userId'] ?? User::getCurrentUserId());
1033
1034 if ($groupId <= 0)
1035 {
1036 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1037 }
1038
1039 if ($userId <= 0)
1040 {
1041 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1042 }
1043
1045 'userId' => $userId,
1046 'groupId' => $groupId,
1047 ]))
1048 {
1049 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1050 }
1051
1052 $relation = UserToGroupTable::getList([
1053 'filter' => [
1054 'USER_ID' => $userId,
1055 'GROUP_ID' => $groupId,
1056 ],
1057 'select' => [ 'ID', 'ROLE', 'INITIATED_BY_TYPE' ],
1058 ])->fetchObject();
1059
1060 if (
1061 $relation
1062 && $relation->getRole() === UserToGroupTable::ROLE_REQUEST
1063 && $relation->getInitiatedByType() === UserToGroupTable::INITIATED_BY_GROUP
1064 )
1065 {
1066 if (!\CSocNetUserToGroup::userConfirmRequestToBeMember($userId, $relation->getId(), false))
1067 {
1068 throw new \RuntimeException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1069 }
1070
1071 $confirmationNeeded = false;
1072 }
1073 else
1074 {
1075 $requestConfirmUrl = \CComponentEngine::MakePathFromTemplate(Path::get('group_requests_path_template'), [ 'group_id' => $groupId ]);
1076 if (!\CSocNetUserToGroup::sendRequestToBeMember($userId, $groupId, '', $requestConfirmUrl, false))
1077 {
1078 throw new \RuntimeException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1079 }
1080
1081 $confirmationNeeded = !(WorkgroupTable::getList([
1082 'filter' => [
1083 'ID' => $groupId
1084 ],
1085 'select' => [ 'OPENED' ]
1086 ])->fetchObject()->getOpened());
1087 }
1088
1089 return $confirmationNeeded;
1090 }
1091
1092 public static function leave(array $fields = []): bool
1093 {
1094 $groupId = (int)($fields['groupId'] ?? 0);
1095 $userId = (int)($fields['userId'] ?? User::getCurrentUserId());
1096
1098 'userId' => $userId,
1099 'groupId' => $groupId,
1100 ]))
1101 {
1102 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1103 }
1104
1105 if (!\CSocNetUserToGroup::deleteRelation($userId, $groupId))
1106 {
1107 throw new \RuntimeException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1108 }
1109
1110 return true;
1111 }
1112
1113 public static function deleteOutgoingRequest(array $fields = []): bool
1114 {
1115 $groupId = (int)($fields['groupId'] ?? 0);
1116 $userId = (int)($fields['userId'] ?? 0);
1117
1118 if ($groupId <= 0)
1119 {
1120 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1121 }
1122
1123 if ($userId <= 0)
1124 {
1125 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1126 }
1127
1128 try
1129 {
1130 $relation = static::getRelation([
1131 '=GROUP_ID' => $groupId,
1132 '=USER_ID' => $userId,
1133 ]);
1134 }
1135 catch (\Exception $e)
1136 {
1137 throw new \Exception($e->getMessage(), $e->getCode());
1138 }
1139
1141 'userId' => $userId,
1142 'groupId' => $groupId,
1143 ]))
1144 {
1145 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1146 }
1147
1148 try
1149 {
1150 self::deleteRelation([
1151 'relationId' => $relation->getId(),
1152 ]);
1153 }
1154 catch (\Exception $e)
1155 {
1156 throw new \Exception($e->getMessage(), $e->getCode());
1157 }
1158
1159 return true;
1160 }
1161
1162 public static function deleteIncomingRequest(array $fields = []): bool
1163 {
1164 $groupId = (int)($fields['groupId'] ?? 0);
1165 $userId = (int)($fields['userId'] ?? 0);
1166
1167 if ($groupId <= 0)
1168 {
1169 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1170 }
1171
1172 if ($userId <= 0)
1173 {
1174 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1175 }
1176
1177 try
1178 {
1179 $relation = static::getRelation([
1180 '=GROUP_ID' => $groupId,
1181 '=USER_ID' => $userId,
1182 ]);
1183 }
1184 catch (\Exception $e)
1185 {
1186 throw new \Exception($e->getMessage(), $e->getCode());
1187 }
1188
1190 'userId' => $userId,
1191 'groupId' => $groupId,
1192 ]))
1193 {
1194 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1195 }
1196
1197 try
1198 {
1199 self::deleteRelation([
1200 'relationId' => $relation->getId(),
1201 ]);
1202 }
1203 catch (\Exception $e)
1204 {
1205 throw new \Exception($e->getMessage(), $e->getCode());
1206 }
1207
1208 return true;
1209 }
1210
1211 public static function exclude(array $fields = []): bool
1212 {
1213 global $APPLICATION;
1214
1215 $groupId = (int)($fields['groupId'] ?? 0);
1216 $userId = (int)($fields['userId'] ?? 0);
1217
1218 if ($groupId <= 0)
1219 {
1220 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1221 }
1222
1223 if ($userId <= 0)
1224 {
1225 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1226 }
1227
1228 try
1229 {
1230 $relation = static::getRelation([
1231 '=GROUP_ID' => $groupId,
1232 '=USER_ID' => $userId,
1233 ]);
1234 }
1235 catch (\Exception $e)
1236 {
1237 throw new \Exception($e->getMessage(), $e->getCode());
1238 }
1239
1241 'userId' => $userId,
1242 'groupId' => $groupId,
1243 ]))
1244 {
1245 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1246 }
1247
1248 if (!\CSocNetUserToGroup::delete($relation->getId(), true))
1249 {
1250 if ($ex = $APPLICATION->getException())
1251 {
1252 $errorMessage = $ex->getString();
1253 }
1254 else
1255 {
1256 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1257 }
1258
1259 throw new \Exception($errorMessage, 100);
1260 }
1261
1262 return true;
1263 }
1264
1265 public static function deleteRelation(array $fields = []): bool
1266 {
1267 global $APPLICATION;
1268
1269 $relationId = (int)($fields['relationId'] ?? 0);
1270
1271 if ($relationId <= 0)
1272 {
1273 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_RELATION_ID'));
1274 }
1275
1276 try
1277 {
1278 $relation = static::getRelation([
1279 '=ID' => $relationId,
1280 ]);
1281 }
1282 catch (\Exception $e)
1283 {
1284 throw new \Exception($e->getMessage(), $e->getCode());
1285 }
1286
1287 if (!\CSocNetUserToGroup::delete($relation->getId()))
1288 {
1289 if ($ex = $APPLICATION->getException())
1290 {
1291 $errorMessage = $ex->getString();
1292 }
1293 else
1294 {
1295 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1296 }
1297
1298 throw new \Exception($errorMessage, 100);
1299 }
1300
1301 return true;
1302 }
1303
1304 public static function acceptIncomingRequest(array $fields = []): bool
1305 {
1306 global $APPLICATION;
1307
1308 $groupId = (int)($fields['groupId'] ?? 0);
1309 $userId = (int)($fields['userId'] ?? 0);
1310
1311 if ($groupId <= 0)
1312 {
1313 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1314 }
1315
1316 if ($userId <= 0)
1317 {
1318 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1319 }
1320
1321 try
1322 {
1323 $relation = static::getRelation([
1324 '=GROUP_ID' => $groupId,
1325 '=USER_ID' => $userId,
1326 ]);
1327 }
1328 catch (\Exception $e)
1329 {
1330 throw new \Exception($e->getMessage(), $e->getCode());
1331 }
1332
1334 'userId' => $userId,
1335 'groupId' => $groupId,
1336 ]))
1337 {
1338 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1339 }
1340
1341 if (!\CSocNetUserToGroup::confirmRequestToBeMember(
1343 $groupId,
1344 [ $relation->getId() ]
1345 ))
1346 {
1347 if ($ex = $APPLICATION->getException())
1348 {
1349 $errorMessage = $ex->getString();
1350 }
1351 else
1352 {
1353 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1354 }
1355
1356 throw new \Exception($errorMessage, 100);
1357 }
1358
1359 return true;
1360 }
1361
1362 public static function acceptOutgoingRequest(array $fields = []): bool
1363 {
1364 global $APPLICATION;
1365
1366 $groupId = (int) ($fields['groupId'] ?? 0);
1367 $userId = (int) ($fields['userId'] ?? 0);
1368
1369 if ($groupId <= 0)
1370 {
1371 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1372 }
1373
1374 if ($userId <= 0)
1375 {
1376 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1377 }
1378
1379 try
1380 {
1381 $relation = static::getRelation([
1382 '=GROUP_ID' => $groupId,
1383 '=USER_ID' => $userId,
1384 ]);
1385 }
1386 catch (\Exception $e)
1387 {
1388 throw new \Exception($e->getMessage(), $e->getCode());
1389 }
1390
1391 if (!\CSocNetUserToGroup::UserConfirmRequestToBeMember($userId, $relation->getId()))
1392 {
1393 if ($ex = $APPLICATION->getException())
1394 {
1395 $errorMessage = $ex->getString();
1396 }
1397 else
1398 {
1399 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1400 }
1401
1402 throw new \Exception($errorMessage, 100);
1403 }
1404
1405 return true;
1406 }
1407
1408 public static function rejectOutgoingRequest(array $fields = []): bool
1409 {
1410 global $APPLICATION;
1411
1412 $groupId = (int) ($fields['groupId'] ?? 0);
1413 $userId = (int) ($fields['userId'] ?? 0);
1414
1415 if ($groupId <= 0)
1416 {
1417 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1418 }
1419
1420 if ($userId <= 0)
1421 {
1422 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1423 }
1424
1425 try
1426 {
1427 $relation = static::getRelation([
1428 '=GROUP_ID' => $groupId,
1429 '=USER_ID' => $userId,
1430 ]);
1431 }
1432 catch (\Exception $e)
1433 {
1434 throw new \Exception($e->getMessage(), $e->getCode());
1435 }
1436
1437 if (!\CSocNetUserToGroup::userRejectRequestToBeMember($userId, $relation->getId()))
1438 {
1439 if ($ex = $APPLICATION->getException())
1440 {
1441 $errorMessage = $ex->getString();
1442 }
1443 else
1444 {
1445 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1446 }
1447
1448 throw new \Exception($errorMessage, 100);
1449 }
1450
1451 return true;
1452 }
1453
1454 public static function rejectIncomingRequest(array $fields = []): bool
1455 {
1456 global $APPLICATION;
1457
1458 $groupId = (int)($fields['groupId'] ?? 0);
1459 $userId = (int)($fields['userId'] ?? 0);
1460
1461 if ($groupId <= 0)
1462 {
1463 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1464 }
1465
1466 if ($userId <= 0)
1467 {
1468 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_USER_ID'));
1469 }
1470
1471 try
1472 {
1473 $relation = static::getRelation([
1474 '=GROUP_ID' => $groupId,
1475 '=USER_ID' => $userId,
1476 ]);
1477 }
1478 catch (\Exception $e)
1479 {
1480 throw new \Exception($e->getMessage(), $e->getCode());
1481 }
1482
1484 'userId' => $userId,
1485 'groupId' => $groupId,
1486 ]))
1487 {
1488 throw new AccessDeniedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_NO_PERMS'));
1489 }
1490
1491 if (!\CSocNetUserToGroup::rejectRequestToBeMember(
1493 $groupId,
1494 [ $relation->getId() ]
1495 ))
1496 {
1497 if ($ex = $APPLICATION->getException())
1498 {
1499 $errorMessage = $ex->getString();
1500 }
1501 else
1502 {
1503 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1504 }
1505
1506 throw new \Exception($errorMessage, 100);
1507 }
1508
1509 return true;
1510 }
1511
1512 public static function disconnectDepartment(array $fields = []): bool
1513 {
1514 global $APPLICATION;
1515
1516 $departmentId = (int)($fields['departmentId'] ?? 0);
1517 $groupId = (int)($fields['groupId'] ?? 0);
1518
1519 if ($groupId <= 0)
1520 {
1521 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1522 }
1523
1524 if ($departmentId <= 0)
1525 {
1526 throw new ArgumentException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_DEPARTMENT_ID'));
1527 }
1528
1529 if (!ModuleManager::isModuleInstalled('intranet'))
1530 {
1531 throw new NotImplementedException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1532 }
1533
1534 $workgroup = Item\Workgroup::getById($groupId);
1535 if (!$workgroup)
1536 {
1537 throw new ObjectNotFoundException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_WRONG_GROUP_ID'));
1538 }
1539
1540 if (!isset($workgroup->getFields()['UF_SG_DEPT']))
1541 {
1542 throw new \Exception(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1543 }
1544
1545 $workgroupFields = $workgroup->getFields();
1546 $currentDepartmentsList = $workgroupFields['UF_SG_DEPT']['VALUE'];
1547
1548 if (
1549 !is_array($currentDepartmentsList)
1550 || empty($currentDepartmentsList)
1551 )
1552 {
1553 throw new \Exception(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED'));
1554 }
1555
1556 $currentDepartmentsList = array_map('intval', array_unique($currentDepartmentsList));
1557
1558 if (!\CSocNetGroup::update(
1559 $groupId,
1560 [
1561 'NAME' => $workgroupFields['NAME'],
1562 'UF_SG_DEPT' => array_diff($currentDepartmentsList, [ $departmentId ]),
1563 ]
1564 ))
1565 {
1566 if ($ex = $APPLICATION->getException())
1567 {
1568 $errorMessage = $ex->getString();
1569 }
1570 else
1571 {
1572 $errorMessage = Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_OPERATION_FAILED');
1573 }
1574
1575 throw new \Exception($errorMessage, 100);
1576 }
1577
1578 return true;
1579 }
1580
1581 protected static function getRelation(array $filter = []): \Bitrix\Socialnetwork\EO_UserToGroup
1582 {
1583 $res = UserToGroupTable::getList([
1584 'filter' => $filter,
1585 'select' => [ 'ID', 'USER_ID', 'GROUP_ID', 'ROLE', 'INITIATED_BY_TYPE', 'INITIATED_BY_USER_ID', 'AUTO_MEMBER' ]
1586 ]);
1587
1588 if (!$result = $res->fetchObject())
1589 {
1590 throw new ObjectNotFoundException(Loc::getMessage('SOCIALNETWORK_HELPER_WORKGROUP_ERROR_RELATION_NOT_FOUND'));
1591 }
1592
1593 return $result;
1594 }
1595
1599 public static function canCreate(array $params = []): bool
1600 {
1601 return Helper\Workgroup\Access::canCreate($params);
1602 }
1603
1604 public static function isCurrentUserModuleAdmin(bool $checkSession = false): bool
1605 {
1606 $result = null;
1607 if ($result === null)
1608 {
1609 $result = \CSocNetUser::isCurrentUserModuleAdmin(SITE_ID, $checkSession);
1610 }
1611
1612 return $result;
1613 }
1614
1618 public static function getCurrentUserId(): int
1619 {
1620 return User::getCurrentUserId();
1621 }
1622
1623 public static function getProjectPresets($params = []): array
1624 {
1625 static $useProjects = null;
1626 static $extranetInstalled = null;
1627
1628 if ($extranetInstalled === null)
1629 {
1630 $extranetInstalled = self::isExtranetInstalled();
1631 }
1632
1633 $entityOptions = [];
1634 if (!empty($params['entityOptions']) && is_array($params['entityOptions']))
1635 {
1636 $entityOptions = $params['entityOptions'];
1637 }
1638
1639 $result = [];
1640 $sort = 0;
1641
1642 if ($useProjects === null)
1643 {
1644 $useProjects = (
1645 ModuleManager::isModuleInstalled('intranet')
1646 && self::checkEntityOption([ 'project' ], $entityOptions)
1647 );
1648 }
1649
1650 if ($useProjects)
1651 {
1652 if (self::checkEntityOption([ '!landing', '!scrum' ], $entityOptions))
1653 {
1654 $result['project'] = [
1655 'SORT' => $sort += 10,
1656 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_PROJECT'),
1657 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_PROJECT_DESC'),
1658 'VISIBLE' => 'Y',
1659 'OPENED' => 'Y',
1660 'PROJECT' => 'Y',
1661 'SCRUM_PROJECT' => 'N',
1662 'EXTERNAL' => 'N',
1663 ];
1664 }
1665
1666 if (self::checkEntityOption([ 'scrum', '!extranet', '!landing' ], $entityOptions))
1667 {
1668 $result['scrum'] = [
1669 'SORT' => $sort += 10,
1670 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_SCRUM'),
1671 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_SCRUM_DESC'),
1672 'VISIBLE' => 'N',
1673 'OPENED' => 'N',
1674 'PROJECT' => 'Y',
1675 'SCRUM_PROJECT' => 'Y',
1676 'EXTERNAL' => 'N',
1677 ];
1678 }
1679 }
1680
1681 if (self::checkEntityOption([ '!scrum' ], $entityOptions))
1682 {
1683 $result['group'] = [
1684 'SORT' => $sort += 10,
1685 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_GROUP'),
1686 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_PROJECT_PRESET_GROUP_DESC'),
1687 'VISIBLE' => 'Y',
1688 'OPENED' => 'Y',
1689 'PROJECT' => 'N',
1690 'SCRUM_PROJECT' => 'N',
1691 'EXTERNAL' => 'N',
1692 ];
1693 }
1694
1695 return $result;
1696 }
1697
1698 public static function getConfidentialityPresets(array $params = []): array
1699 {
1700 static $useProjects = null;
1701
1702 $currentExtranetSite = (
1703 !empty($params)
1704 && isset($params['currentExtranetSite'])
1705 && $params['currentExtranetSite']
1706 );
1707
1708 $entityOptions = (
1709 !empty($params['entityOptions'])
1710 && is_array($params['entityOptions'])
1711 ? $params['entityOptions']
1712 : []
1713 );
1714
1715 $result = [];
1716 $sort = 0;
1717
1718 if ($useProjects === null)
1719 {
1720 $useProjects = (
1721 ModuleManager::isModuleInstalled('intranet')
1722 && self::checkEntityOption([ 'project' ], $entityOptions)
1723 );
1724 }
1725
1726 if (!$currentExtranetSite)
1727 {
1728 if (self::checkEntityOption([ 'open', '!extranet', '!landing' ], $entityOptions))
1729 {
1730 $result['open'] = [
1731 'SORT' => $sort += 10,
1732 'NAME' => ($useProjects ? Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_OPEN') : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_OPEN')),
1733 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_OPEN_DESC3'),
1734 'VISIBLE' => 'Y',
1735 'OPENED' => 'Y',
1736 'EXTERNAL' => 'N',
1737 ];
1738 }
1739
1740 if (self::checkEntityOption([ '!open', '!extranet', '!landing' ], $entityOptions))
1741 {
1742 $result['closed'] = [
1743 'SORT' => $sort += 10,
1744 'NAME' => ($useProjects ? Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED') : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED')),
1745 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_DESC3'),
1746 'VISIBLE' => 'Y',
1747 'OPENED' => 'N',
1748 'EXTERNAL' => 'N',
1749 ];
1750 }
1751
1752 if (self::checkEntityOption([ '!open', '!extranet', '!landing' ], $entityOptions))
1753 {
1754 $result['secret'] = [
1755 'SORT' => $sort += 10,
1756 'NAME' => ($useProjects ?
1757 Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_SECRET_1')
1758 : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_SECRET_1')
1759 ),
1760 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_SECRET_DESC3_1'),
1761 'VISIBLE' => 'N',
1762 'OPENED' => 'N',
1763 'EXTERNAL' => 'N',
1764 ];
1765 }
1766 }
1767
1768 return $result;
1769 }
1770
1771 protected static function checkEntityOption(array $keysList = [], array $entityOptions = []): bool
1772 {
1773 $result = true;
1774
1775 foreach ($keysList as $key)
1776 {
1777 if (
1778 !empty($entityOptions)
1779 && (
1780 (
1781 isset($entityOptions[$key])
1782 && !$entityOptions[$key]
1783 )
1784 || (
1785 preg_match('/^\!(\w+)$/', $key, $matches)
1786 && isset($entityOptions[$matches[1]])
1787 && $entityOptions[$matches[1]]
1788 )
1789 )
1790 )
1791 {
1792 $result = false;
1793 break;
1794 }
1795 }
1796
1797 return $result;
1798 }
1799
1800 public static function getPresets($params = []): array
1801 {
1802 static $useProjects = null;
1803 static $extranetInstalled = null;
1804 static $landingInstalled = null;
1805
1806 if ($extranetInstalled === null)
1807 {
1808 $extranetInstalled = self::isExtranetInstalled();
1809 }
1810
1811 if ($landingInstalled === null)
1812 {
1813 $landingInstalled = ModuleManager::isModuleInstalled('landing');
1814 }
1815
1816 $currentExtranetSite = (
1817 !empty($params)
1818 && isset($params['currentExtranetSite'])
1819 && $params['currentExtranetSite']
1820 );
1821
1822 $entityOptions = (
1823 !empty($params)
1824 && is_array($params['entityOptions'])
1825 && !empty($params['entityOptions'])
1826 ? $params['entityOptions']
1827 : []
1828 );
1829
1830 $fullMode = (
1831 !empty($params)
1832 && isset($params['fullMode'])
1833 && $params['fullMode']
1834 );
1835
1836 $result = [];
1837 $sort = 0;
1838
1839 if ($useProjects === null)
1840 {
1841 $useProjects = (
1842 ModuleManager::isModuleInstalled('intranet')
1843 && self::checkEntityOption([ 'project' ], $entityOptions)
1844 );
1845 }
1846
1847 if (!$currentExtranetSite)
1848 {
1849 if (self::checkEntityOption([ 'open', '!extranet', '!landing' ], $entityOptions))
1850 {
1851 $result['project-open'] = [
1852 'SORT' => $sort += 10,
1853 'NAME' => ($useProjects ? Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_OPEN') : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_OPEN')),
1854 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_OPEN_DESC'),
1855 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_OPEN_DESC2'),
1856 'VISIBLE' => 'Y',
1857 'OPENED' => 'Y',
1858 'PROJECT' => ($useProjects ? 'Y' : 'N' ),
1859 'EXTERNAL' => 'N',
1860 'TILE_CLASS' => 'social-group-tile-item-cover-open ' . ($useProjects ? 'social-group-tile-item-icon-project-open' : 'social-group-tile-item-icon-group-open')
1861 ];
1862 }
1863
1864 if (self::checkEntityOption([ '!open', '!extranet', '!landing' ], $entityOptions))
1865 {
1866 $result['project-closed'] = [
1867 'SORT' => $sort += 10,
1868 'NAME' => ($useProjects ? Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED') : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED')),
1869 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_DESC'),
1870 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_DESC'),
1871 'VISIBLE' => 'N',
1872 'OPENED' => 'N',
1873 'PROJECT' => ($useProjects ? 'Y' : 'N' ),
1874 'EXTERNAL' => 'N',
1875 'TILE_CLASS' => 'social-group-tile-item-cover-close ' . ($useProjects ? 'social-group-tile-item-icon-project-close' : 'social-group-tile-item-icon-group-close')
1876 ];
1877 }
1878
1879 if (
1880 $useProjects
1881 && self::checkEntityOption([ 'project', 'scrum', '!extranet', '!landing' ], $entityOptions)
1882 )
1883 {
1884 $result['project-scrum'] = [
1885 'SORT' => $sort += 10,
1886 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM'),
1887 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_DESC'),
1888 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_DESC'),
1889 'VISIBLE' => 'N',
1890 'OPENED' => 'N',
1891 'PROJECT' => 'Y',
1892 'SCRUM_PROJECT' => 'Y',
1893 'EXTERNAL' => 'N',
1894 'TILE_CLASS' => 'social-group-tile-item-cover-scrum social-group-tile-item-icon-project-scrum'
1895 ];
1896 }
1897
1898 if (
1899 $fullMode
1900 && self::checkEntityOption([ '!open', '!extranet', '!landing' ], $entityOptions)
1901 )
1902 {
1903 $result['project-closed-visible'] = [
1904 'SORT' => $sort += 10,
1905 'NAME' => ($useProjects ? Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_VISIBLE') : Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_VISIBLE')),
1906 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_VISIBLE_DESC'),
1907 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_CLOSED_VISIBLE_DESC'),
1908 'VISIBLE' => 'Y',
1909 'OPENED' => 'N',
1910 'PROJECT' => ($useProjects ? 'Y' : 'N' ),
1911 'EXTERNAL' => 'N',
1912 'TILE_CLASS' => ''
1913 ];
1914 }
1915 }
1916
1917 if (
1918 $extranetInstalled
1919 && self::checkEntityOption([ 'extranet', '!landing' ], $entityOptions)
1920 )
1921 {
1922 $result['project-external'] = [
1923 'SORT' => $sort += 10,
1924 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_EXTERNAL'),
1925 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_EXTERNAL_DESC'),
1926 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GP_EXTERNAL_DESC'),
1927 'VISIBLE' => 'N',
1928 'OPENED' => 'N',
1929 'PROJECT' => ($useProjects ? 'Y' : 'N' ),
1930 'EXTERNAL' => 'Y',
1931 'TILE_CLASS' => 'social-group-tile-item-cover-outer social-group-tile-item-icon-project-outer'
1932 ];
1933 }
1934
1935 if (
1936 $landingInstalled
1937 && self::checkEntityOption([ '!project', 'landing', '!extranet' ], $entityOptions)
1938 )
1939 {
1940 $result['group-landing'] = [
1941 'SORT' => $sort += 10,
1942 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING2'),
1943 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING_DESC2_MSGVER_1'),
1944 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING_DESC2_MSGVER_1'),
1945 'VISIBLE' => 'N',
1946 'OPENED' => 'N',
1947 'PROJECT' => 'N',
1948 'EXTERNAL' => 'N',
1949 'LANDING' => 'Y',
1950 'TILE_CLASS' => 'social-group-tile-item-cover-public social-group-tile-item-icon-group-public'
1951 ];
1952 }
1953
1954 return $result;
1955 }
1956
1957 public static function getTypes($params = []): array
1958 {
1959 static $intranetInstalled = null;
1960 static $extranetInstalled = null;
1961 static $landingInstalled = null;
1962
1963 if ($intranetInstalled === null)
1964 {
1965 $intranetInstalled = ModuleManager::isModuleInstalled('intranet');
1966 }
1967
1968 if ($extranetInstalled === null)
1969 {
1970 $extranetInstalled = static::isExtranetInstalled();
1971 }
1972
1973 if ($landingInstalled === null)
1974 {
1975 $landingInstalled = ModuleManager::isModuleInstalled('landing');
1976 }
1977
1978 $currentExtranetSite = (
1979 !empty($params)
1980 && isset($params['currentExtranetSite'])
1981 && $params['currentExtranetSite']
1982 );
1983
1984 $categoryList = [];
1985 if (!empty($params['category']) && is_array($params['category']))
1986 {
1987 $categoryList = $params['category'];
1988 }
1989
1990 $entityOptions = [];
1991 if (!empty($params['entityOptions']) && is_array($params['entityOptions']))
1992 {
1993 $entityOptions = $params['entityOptions'];
1994 }
1995
1996 $fullMode = (
1997 !empty($params)
1998 && isset($params['fullMode'])
1999 && $params['fullMode']
2000 );
2001
2002 $result = [];
2003 $sort = 0;
2004
2005 if (
2006 $intranetInstalled
2007 && (
2008 empty($categoryList)
2009 || in_array('projects', $categoryList, true)
2010 )
2011 )
2012 {
2013 if (!$currentExtranetSite)
2014 {
2015 if (self::checkEntityOption([ 'project', 'open', '!extranet', '!landing' ], $entityOptions))
2016 {
2017 $result['project-open'] = array(
2018 'SORT' => $sort += 10,
2019 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_OPEN'),
2020 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_OPEN_DESC'),
2021 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_OPEN_DESC2'),
2022 'VISIBLE' => 'Y',
2023 'OPENED' => 'Y',
2024 'PROJECT' => 'Y',
2025 'SCRUM_PROJECT' => 'N',
2026 'EXTERNAL' => 'N',
2027 'TILE_CLASS' => 'social-group-tile-item-cover-open social-group-tile-item-icon-project-open'
2028 );
2029 }
2030
2031 if (self::checkEntityOption([ 'project', '!open', '!extranet', '!landing' ], $entityOptions))
2032 {
2033 $result['project-closed'] = array(
2034 'SORT' => $sort += 10,
2035 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED'),
2036 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED_DESC'),
2037 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED_DESC'),
2038 'VISIBLE' => 'N',
2039 'OPENED' => 'N',
2040 'PROJECT' => 'Y',
2041 'SCRUM_PROJECT' => 'N',
2042 'EXTERNAL' => 'N',
2043 'TILE_CLASS' => 'social-group-tile-item-cover-close social-group-tile-item-icon-project-close'
2044 );
2045 }
2046
2047 if (self::checkEntityOption([ 'project', 'scrum', '!extranet', '!landing' ], $entityOptions))
2048 {
2049 $result['project-scrum'] = [
2050 'SORT' => $sort += 10,
2051 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM2'),
2052 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_DESC2'),
2053 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_DESC2'),
2054 'VISIBLE' => 'N',
2055 'OPENED' => 'N',
2056 'PROJECT' => 'Y',
2057 'SCRUM_PROJECT' => 'Y',
2058 'EXTERNAL' => 'N',
2059 'TILE_CLASS' => 'social-group-tile-item-cover-scrum social-group-tile-item-icon-project-scrum'
2060 ];
2061 }
2062
2063 if (
2064 $fullMode
2065 && self::checkEntityOption([ 'project', '!open', '!extranet', '!landing' ], $entityOptions)
2066 )
2067 {
2068 $result['project-closed-visible'] = array(
2069 'SORT' => $sort += 10,
2070 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED_VISIBLE'),
2071 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED_VISIBLE_DESC'),
2072 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_CLOSED_VISIBLE_DESC'),
2073 'VISIBLE' => 'Y',
2074 'OPENED' => 'N',
2075 'PROJECT' => 'Y',
2076 'SCRUM_PROJECT' => 'N',
2077 'EXTERNAL' => 'N',
2078 'TILE_CLASS' => ''
2079 );
2080 }
2081 }
2082
2083 if (
2084 $extranetInstalled
2085 && self::checkEntityOption([ 'project', 'scrum', 'extranet', '!landing' ], $entityOptions)
2086 )
2087 {
2088 $result['project-scrum-extranet'] = [
2089 'SORT' => $sort += 10,
2090 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_EXTERNAL'),
2091 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_EXTERNAL_DESC'),
2092 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_SCRUM_EXTERNAL_DESC'),
2093 'VISIBLE' => 'N',
2094 'OPENED' => 'N',
2095 'PROJECT' => 'Y',
2096 'SCRUM_PROJECT' => 'Y',
2097 'EXTERNAL' => 'Y',
2098 'TILE_CLASS' => 'social-group-tile-item-cover-scrum social-group-tile-item-icon-project-scrum'
2099 ];
2100 }
2101
2102 if (
2103 $extranetInstalled
2104 && self::checkEntityOption([ 'project', 'extranet', '!landing' ], $entityOptions)
2105 )
2106 {
2107 $result['project-external'] = array(
2108 'SORT' => $sort += 10,
2109 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_EXTERNAL'),
2110 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_EXTERNAL_DESC'),
2111 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_PROJECT_EXTERNAL_DESC'),
2112 'VISIBLE' => 'N',
2113 'OPENED' => 'N',
2114 'PROJECT' => 'Y',
2115 'SCRUM_PROJECT' => 'N',
2116 'EXTERNAL' => 'Y',
2117 'TILE_CLASS' => 'social-group-tile-item-cover-outer social-group-tile-item-icon-project-outer'
2118 );
2119 }
2120 }
2121
2122 if (
2123 !$currentExtranetSite
2124 && (
2125 empty($categoryList)
2126 || in_array('groups', $categoryList)
2127 )
2128 )
2129 {
2130 if (self::checkEntityOption([ '!project', 'open', '!extranet', '!landing' ], $entityOptions))
2131 {
2132 $result['group-open'] = array(
2133 'SORT' => $sort += 10,
2134 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_OPEN'),
2135 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_OPEN_DESC'),
2136 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_OPEN_DESC2'),
2137 'VISIBLE' => 'Y',
2138 'OPENED' => 'Y',
2139 'PROJECT' => 'N',
2140 'SCRUM_PROJECT' => 'N',
2141 'EXTERNAL' => 'N',
2142 'TILE_CLASS' => 'social-group-tile-item-cover-open social-group-tile-item-icon-group-open'
2143 );
2144 }
2145
2146 if (self::checkEntityOption([ '!project', '!open', '!extranet', '!landing' ], $entityOptions))
2147 {
2148 $result['group-closed'] = array(
2149 'SORT' => $sort += 10,
2150 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED'),
2151 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_DESC'),
2152 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_DESC'),
2153 'VISIBLE' => 'N',
2154 'OPENED' => 'N',
2155 'PROJECT' => 'N',
2156 'SCRUM_PROJECT' => 'N',
2157 'EXTERNAL' => 'N',
2158 'TILE_CLASS' => 'social-group-tile-item-cover-close social-group-tile-item-icon-group-close'
2159 );
2160 if ($fullMode)
2161 {
2162 $result['group-closed-visible'] = array(
2163 'SORT' => $sort = $sort + 10,
2164 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_VISIBLE'),
2165 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_VISIBLE_DESC'),
2166 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_CLOSED_VISIBLE_DESC'),
2167 'VISIBLE' => 'Y',
2168 'OPENED' => 'N',
2169 'PROJECT' => 'N',
2170 'SCRUM_PROJECT' => 'N',
2171 'EXTERNAL' => 'N',
2172 'TILE_CLASS' => ''
2173 );
2174 }
2175 }
2176 }
2177
2178 if (
2179 $extranetInstalled
2180 && self::checkEntityOption([ '!project', 'extranet', '!landing' ], $entityOptions)
2181 )
2182 {
2183 $result['group-external'] = array(
2184 'SORT' => $sort += 10,
2185 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_EXTERNAL'),
2186 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_EXTERNAL_DESC'),
2187 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_EXTERNAL_DESC'),
2188 'VISIBLE' => 'N',
2189 'OPENED' => 'N',
2190 'PROJECT' => 'N',
2191 'SCRUM_PROJECT' => 'N',
2192 'EXTERNAL' => 'Y',
2193 'TILE_CLASS' => 'social-group-tile-item-cover-outer social-group-tile-item-icon-group-outer'
2194 );
2195 }
2196
2197 if (
2198 $landingInstalled
2199 && self::checkEntityOption([ '!project', 'landing', '!extranet' ], $entityOptions)
2200 )
2201 {
2202 $result['group-landing'] = array(
2203 'SORT' => $sort += 10,
2204 'NAME' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING_MSGVER_1'),
2205 'DESCRIPTION' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING_DESC_MSGVER_1'),
2206 'DESCRIPTION2' => Loc::getMessage('SOCIALNETWORK_ITEM_WORKGROUP_TYPE_GROUP_LANDING_DESC_MSGVER_1'),
2207 'VISIBLE' => 'N',
2208 'OPENED' => 'N',
2209 'PROJECT' => 'N',
2210 'SCRUM_PROJECT' => 'N',
2211 'EXTERNAL' => 'N',
2212 'LANDING' => 'Y',
2213 'TILE_CLASS' => 'social-group-tile-item-cover-public social-group-tile-item-icon-group-public'
2214 );
2215 }
2216
2217 return $result;
2218 }
2219
2220 protected static function isExtranetInstalled(): bool
2221 {
2222 return (
2223 ModuleManager::isModuleInstalled('extranet')
2224 && Option::get('extranet', 'extranet_site') !== ''
2225 );
2226 }
2227
2228 public static function getAvatarTypes(): array
2229 {
2230 return array_merge(self::getDefaultAvatarTypes(), self::getColoredAvatarTypes());
2231 }
2232
2233 public static function getDefaultAvatarTypes(): array
2234 {
2235 return [
2236 'folder' => [
2237 'sort' => 100,
2238 'mobileUrl' => '/bitrix/images/socialnetwork/workgroup/folder.png',
2239 'webCssClass' => 'folder',
2240 'entitySelectorUrl' => '/bitrix/images/socialnetwork/workgroup/folder.png',
2241 ],
2242 'checks' => [
2243 'sort' => 200,
2244 'mobileUrl' => '/bitrix/images/socialnetwork/workgroup/checks.png',
2245 'webCssClass' => 'tasks',
2246 'entitySelectorUrl' => '/bitrix/images/socialnetwork/workgroup/checks.png',
2247 ],
2248 'pie' => [
2249 'sort' => 300,
2250 'mobileUrl' => '/bitrix/images/socialnetwork/workgroup/pie.png',
2251 'webCssClass' => 'chart',
2252 'entitySelectorUrl' => '/bitrix/images/socialnetwork/workgroup/pie.png',
2253 ],
2254 'bag' => [
2255 'sort' => 400,
2256 'mobileUrl' => '/bitrix/images/socialnetwork/workgroup/bag.png',
2257 'webCssClass' => 'briefcase',
2258 'entitySelectorUrl' => '/bitrix/images/socialnetwork/workgroup/bag.png',
2259 ],
2260 'members' => [
2261 'sort' => 500,
2262 'mobileUrl' => '/bitrix/images/socialnetwork/workgroup/members.png',
2263 'webCssClass' => 'group',
2264 'entitySelectorUrl' => '/bitrix/images/socialnetwork/workgroup/members.png',
2265 ],
2266 ];
2267 }
2268
2269 public static function getColoredAvatarTypes(): array
2270 {
2271 $colors = self::getAvatarColors();
2272
2273 $avatarTypes = [];
2274 foreach ($colors as $color)
2275 {
2276 $avatarTypes["space_$color"] = [
2277 'sort' => 600,
2278 'mobileUrl' => "/bitrix/images/socialnetwork/workgroup/space_$color.png",
2279 'webCssClass' => "space_$color",
2280 'entitySelectorUrl' => "/bitrix/images/socialnetwork/workgroup/space_$color.png",
2281 ];
2282 }
2283
2284 return $avatarTypes;
2285 }
2286
2287 public static function getAvatarColors(): array
2288 {
2289 return [
2290 '55D0E0',
2291 'FB6DBA',
2292 '29AD49',
2293 'C27D3C',
2294 '05B5AB',
2295 'A77BDE',
2296 '90BF00',
2297 '559BE6',
2298 'D959CC',
2299 ];
2300 }
2301
2302 public static function getAvatarTypeWebCssClass($type = ''): string
2303 {
2304 $result = '';
2305 $types = static::getAvatarTypes();
2306 if (empty($types[$type]))
2307 {
2308 return $result;
2309 }
2310
2311 return $types[$type]['webCssClass'];
2312 }
2313
2314 public static function getAvatarEntitySelectorUrl($type = ''): string
2315 {
2316 $result = '';
2317 $types = static::getAvatarTypes();
2318 if (empty($types[$type]))
2319 {
2320 return $result;
2321 }
2322
2323 return $types[$type]['entitySelectorUrl'];
2324 }
2325
2326 public static function getAdditionalData(array $params = []): array
2327 {
2328 global $USER;
2329
2330 $ids = (
2331 is_array($params['ids'])
2332 ? array_filter(
2333 array_map(
2334 static function($val) { return (int)$val; },
2335 $params['ids']
2336 ),
2337 static function ($val) { return $val > 0; }
2338 )
2339 : []
2340 );
2341 $features = (
2342 is_array($params['features'])
2343 ? array_filter(
2344 array_map(
2345 static function($val) { return trim((string)$val); },
2346 $params['features']
2347 ),
2348 static function ($val) { return !empty($val); }
2349 )
2350 : []
2351 );
2352 $mandatoryFeatures = (
2353 is_array($params['mandatoryFeatures'])
2354 ? array_filter(
2355 array_map(
2356 static function($val) { return trim((string)$val); },
2357 $params['mandatoryFeatures']
2358 ),
2359 static function ($val) { return !empty($val); }
2360 )
2361 : []
2362 );
2363 $currentUserId = (int)($params['currentUserId'] ?? $USER->getId());
2364 if (empty($ids))
2365 {
2366 return $ids;
2367 }
2368
2369 $featuresSettings = \CSocNetAllowed::getAllowedFeatures();
2370
2371 $result = [];
2372 $userRoles = [];
2373
2374 $res = UserToGroupTable::getList([
2375 'filter' => [
2376 'GROUP_ID' => $ids,
2377 'USER_ID' => $currentUserId,
2378 ],
2379 'select' => [ 'GROUP_ID', 'ROLE', 'INITIATED_BY_TYPE' ]
2380
2381 ]);
2382 while ($relationFields = $res->fetch())
2383 {
2384 $userRoles[(int)$relationFields['GROUP_ID']] = [
2385 'ROLE' => $relationFields['ROLE'],
2386 'INITIATED_BY_TYPE' => $relationFields['INITIATED_BY_TYPE'],
2387 ];
2388 }
2389
2390 foreach ($features as $feature)
2391 {
2392 $activeFeaturesList = \CSocNetFeatures::isActiveFeature(SONET_ENTITY_GROUP, $ids, $feature);
2393 $filteredIds = array_keys(array_filter($activeFeaturesList, static function($val) { return $val; }));
2394
2395 if (
2396 empty($filteredIds)
2397 || !isset($featuresSettings[$feature])
2398 )
2399 {
2400 $permissions = [];
2401 }
2402 else
2403 {
2404 $minOperationList = $featuresSettings[$feature]['minoperation'];
2405 if (!is_array($minOperationList))
2406 {
2407 $minOperationList = [ $minOperationList ];
2408 }
2409
2410 $permissions = [];
2411 foreach ($minOperationList as $minOperation)
2412 {
2413 $operationPermissions = \CSocNetFeaturesPerms::getOperationPerm(SONET_ENTITY_GROUP, $filteredIds, $feature, $minOperation);
2414 foreach ($operationPermissions as $groupId => $role)
2415 {
2416 if (
2417 !isset($permissions[$groupId])
2418 || $role > $permissions[$groupId]
2419 )
2420 {
2421 $permissions[$groupId] = $role;
2422 }
2423 }
2424 }
2425 }
2426
2427 foreach ($ids as $id)
2428 {
2429 if (!isset($result[$id]))
2430 {
2431 $result[$id] = [];
2432 }
2433
2434 if (!isset($result[$id]['FEATURES']))
2435 {
2436 $result[$id]['FEATURES'] = [];
2437 }
2438
2439 if (
2440 in_array($feature, $mandatoryFeatures, true)
2441 || (
2442 isset($permissions[$id])
2443 && (
2444 !in_array($permissions[$id], UserToGroupTable::getRolesMember(), true)
2445 || (
2446 isset($userRoles[$id])
2447 && $userRoles[$id]['ROLE'] <= $permissions[$id]
2448 )
2449 )
2450 )
2451 )
2452 {
2453 $result[$id]['FEATURES'][] = $feature;
2454 }
2455 }
2456 }
2457
2458 foreach ($ids as $id)
2459 {
2460 $result[$id]['ROLE'] = ($userRoles[$id]['ROLE'] ?? '');
2461 $result[$id]['INITIATED_BY_TYPE'] = ($userRoles[$id]['INITIATED_BY_TYPE'] ?? '');
2462 }
2463
2464 return $result;
2465 }
2466
2467 public static function mutateScrumFormFields(array &$fields = []): void
2468 {
2469 if (empty($fields['SCRUM_MASTER_ID']))
2470 {
2471 return;
2472 }
2473
2474 $fields['PROJECT'] = 'Y';
2475
2476 if (empty($fields['SUBJECT_ID']))
2477 {
2478 $siteId = (!empty($fields['SITE_ID']) ? $fields['SITE_ID'] : SITE_ID);
2479
2480 $subjectQueryObject = \CSocNetGroupSubject::getList(
2481 [
2482 'SORT' => 'ASC',
2483 'NAME' => 'ASC'
2484 ],
2485 [
2486 'SITE_ID' => $siteId,
2487 ],
2488 false,
2489 false,
2490 [ 'ID' ]
2491 );
2492 if ($subject = $subjectQueryObject->fetch())
2493 {
2494 $fields['SUBJECT_ID'] = (int)$subject['ID'];
2495 }
2496 }
2497 }
2498
2499 public static function pin(int $groupId, string $mode = ''): ?bool
2500 {
2501 if (
2502 $groupId <= 0
2503 || !Helper\Workgroup\Access::canView(['groupId' => $groupId])
2504 || static::getIsPinned($groupId, $mode)
2505 )
2506 {
2507 return false;
2508 }
2509
2510 $userId = User::getCurrentUserId();
2511
2512 try
2513 {
2514 WorkgroupPinTable::add([
2515 'GROUP_ID' => $groupId,
2516 'USER_ID' => $userId,
2517 'CONTEXT' => $mode,
2518 ]);
2519 }
2520 catch (\Exception $e)
2521 {
2522 return null;
2523 }
2524
2525 static::sendPinChangedPushEvent($groupId, $userId, 'pin');
2526
2527 return true;
2528 }
2529
2530 public static function unpin(int $groupId, string $mode = ''): ?bool
2531 {
2532 if (
2533 $groupId <= 0
2534 || !Helper\Workgroup\Access::canView(['groupId' => $groupId])
2535 || !($isPinned = static::getIsPinned($groupId, $mode))
2536 )
2537 {
2538 return false;
2539 }
2540
2541 $tableDeleteResult = WorkgroupPinTable::delete($isPinned->get('ID'));
2542 if (!$tableDeleteResult->isSuccess())
2543 {
2544 return null;
2545 }
2546
2547 static::sendPinChangedPushEvent($groupId, User::getCurrentUserId(), 'unpin');
2548
2549 return true;
2550 }
2551
2552 private static function getIsPinned(int $groupId, string $mode): ?EO_WorkgroupPin
2553 {
2554 $query = WorkgroupPinTable::query();
2555 $query
2556 ->setSelect(['ID', 'GROUP_ID', 'USER_ID'])
2557 ->where('GROUP_ID', $groupId)
2558 ->where('USER_ID', User::getCurrentUserId())
2559 ->setLimit(1)
2560 ;
2561
2562 if ($mode === '')
2563 {
2564 $query->where(
2565 Query::filter()
2566 ->logic('or')
2567 ->whereNull('CONTEXT')
2568 ->where('CONTEXT', '')
2569 );
2570 }
2571 else
2572 {
2573 $query->where('CONTEXT', $mode);
2574 }
2575
2576 return $query->exec()->fetchObject();
2577 }
2578
2579 private static function sendPinChangedPushEvent(int $groupId, int $userId, string $action): void
2580 {
2581 PushService::addEvent(
2582 [$userId],
2583 [
2584 'module_id' => 'socialnetwork',
2585 'command' => 'workgroup_pin_changed',
2586 'params' => [
2587 'GROUP_ID' => $groupId,
2588 'USER_ID' => $userId,
2589 'ACTION' => $action,
2590 ],
2591 ]
2592 );
2593 }
2594}
static getConnection($name="")
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static get(string $key='', $siteId=SITE_ID)
Definition path.php:17
static canSetModerator(array $params=[])
Definition access.php:509
static canRemoveModerator(array $params=[])
Definition access.php:560
static canDeleteIncomingRequest(array $params=[])
Definition access.php:283
static canSetScrumMaster(array $params=[])
Definition access.php:181
static canModify(array $params=[])
Definition access.php:77
static canExclude(array $params=[])
Definition access.php:385
static canDeleteOutgoingRequest(array $params=[])
Definition access.php:232
static canProcessIncomingRequest(array $params=[])
Definition access.php:334
static getRelation(array $filter=[])
static checkEntityOption(array $keysList=[], array $entityOptions=[])
static join(array $fields=[])
static canCreate(array $params=[])
static setOwner(array $fields=[])
static acceptOutgoingRequest(array $fields=[])
static unpin(int $groupId, string $mode='')
static setArchive(array $fields=[])
static setModerator(array $fields=[])
static setModerators(array $fields=[])
static rejectIncomingRequest(array $fields=[])
static pin(int $groupId, string $mode='')
static disconnectDepartment(array $fields=[])
static getPermissions(array $params=[])
static rejectOutgoingRequest(array $fields=[])
static setScrumMaster(array $fields=[])
static leave(array $fields=[])
static checkAnyOpened(array $idList=[])
static exclude(array $fields=[])
static getByFeatureOperation(array $params=[])
static isCurrentUserModuleAdmin(bool $checkSession=false)
static deleteIncomingRequest(array $fields=[])
static acceptIncomingRequest(array $fields=[])
static deleteOutgoingRequest(array $fields=[])
static mutateScrumFormFields(array &$fields=[])
static removeModerator(array $fields=[])
static getConfidentialityPresets(array $params=[])
static deleteRelation(array $fields=[])
static getConfidentialityTypeCodeByParams($params)
static getAdditionalData(array $params=[])