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