40 private static array $userScopeIdsCache = [];
52 $userId = (int)CurrentUser::get()->getId();
55 if (!isset(static::$instances[
$userId]))
57 Loader::includeModule(
'ui');
61 return static::$instances[
$userId];
71 return $this->getScopes($entityTypeId,
$moduleId, $loadMetadata);
76 return $this->getScopes($entityTypeId,
$moduleId,
false, $loadMetadata);
79 private function getScopes(
82 bool $excludeEmptyAccessCode =
true,
83 bool $loadMetadata =
true,
87 $key = $entityTypeId .
'-' .
$moduleId .
'-' . ($loadMetadata ?
'Y' :
'N');
89 if (!isset($results[
$key]))
95 && $scopeAccess->isAdminForEntityTypeId($entityTypeId)
98 if (!$isAdminForEntity)
100 $filter[
'@ID'] = $this->getScopesIdByUser();
105 if ($excludeEmptyAccessCode)
110 if ($isAdminForEntity || !empty(
$filter[
'@ID']))
112 $scopes = EntityFormConfigTable::getList([
117 'ACCESS_CODE' =>
'\Bitrix\Ui\EntityForm\EntityFormConfigAcTable:CONFIG.ACCESS_CODE',
122 foreach ($scopes as $scope)
124 $result[$scope[
'ID']][
'NAME'] = HtmlFilter::encode($scope[
'NAME']);
125 $result[$scope[
'ID']][
'AUTO_APPLY_SCOPE'] = $scope[
'AUTO_APPLY_SCOPE'];
128 && !isset(
$result[$scope[
'ID']][
'ACCESS_CODES'][$scope[
'ACCESS_CODE']])
129 && isset($scope[
'ACCESS_CODE'])
132 $accessCode =
new AccessCode($scope[
'ACCESS_CODE']);
133 $member = (
new DataProvider())->getEntity(
134 $accessCode->getEntityType(),
135 $accessCode->getEntityId()
137 $result[$scope[
'ID']][
'ACCESS_CODES'][$scope[
'ACCESS_CODE']] = $scope[
'ACCESS_CODE'];
138 $result[$scope[
'ID']][
'MEMBERS'][$scope[
'ACCESS_CODE']] = $member->getMetaData();
146 return $results[
$key];
155 'lead_details' => [
'lead_details',
'returning_lead_details'],
156 'returning_lead_details' => [
'lead_details',
'returning_lead_details'],
166 return in_array($scopeId, $this->getScopesIdByUser());
174 private function getScopesIdByUser():
array
176 if (isset(self::$userScopeIdsCache[$this->
getUserId()]))
178 return self::$userScopeIdsCache[$this->
getUserId()];
181 $accessCodes = $this->getCurrentUserAccessCodes();
189 '@ACCESS_CODE' => $accessCodes,
193 $scopes = EntityFormConfigAcTable::getList(
$params)->fetchAll();
194 $scopesIds = array_unique(array_column($scopes,
'CONFIG_ID'));
196 self::$userScopeIdsCache[$this->
getUserId()] = $scopesIds;
198 return self::$userScopeIdsCache[$this->
getUserId()];
203 $accessCodes = array_filter($accessCodes,
static fn(
$code) => mb_strpos(
$code,
'CHAT') !== 0);
205 foreach ($accessCodes as &$accessCode)
207 $accessCode = preg_replace(
'|^(SG\d*?)(_[K,A,M])$|',
'$1', $accessCode);
218 if ($row = EntityFormConfigTable::getRowById($scopeId))
220 return (is_array($row[
'CONFIG']) ? $row[
'CONFIG'] :
null);
231 return EntityFormConfigTable::getRowById($scopeId);
240 foreach ($ids as $id)
242 $this->removeById($id);
252 $this->removeScopeMembers($id);
253 return EntityFormConfigTable::delete($id);
263 public function setScope(
string $categoryName,
string $guid,
string $scope,
int $userScopeId = 0, ?
int $userId =
null): void
270 string $entityTypeId,
279 $errors[
'name'] =
new Error(Loc::getMessage(
'FIELD_REQUIRED'));
281 if (empty($accessCodes))
283 $errors[
'accessCodes'] =
new Error(Loc::getMessage(
'FIELD_REQUIRED'));
285 if (empty(
$params[
'categoryName']))
287 $errors[
'categoryName'] =
new Error(Loc::getMessage(
'FIELD_REQUIRED'));
296 $result = EntityFormConfigTable::add([
297 'CATEGORY' => $category,
298 'ENTITY_TYPE_ID' => $entityTypeId,
301 'COMMON' => (
$params[
'common'] ??
'Y'),
302 'AUTO_APPLY_SCOPE' => (
$params[
'forceSetToUsers'] ??
'N'),
303 'OPTION_CATEGORY' =>
$params[
'categoryName']
309 foreach ($accessCodes as $ac)
311 EntityFormConfigAcTable::add([
312 'ACCESS_CODE' => $ac[
'id'],
313 'CONFIG_ID' => $configId,
317 $forceSetToUsers = (
$params[
'forceSetToUsers'] ??
false);
318 if (mb_strtoupper($forceSetToUsers) ===
'FALSE')
320 $forceSetToUsers =
false;
323 Application::getInstance()->addBackgroundJob(
325 'forceSetToUsers' => $forceSetToUsers,
326 'categoryName' => (
$params[
'categoryName'] ??
''),
327 'entityTypeId' => $entityTypeId,
328 'configId' => $configId,
343 foreach ($accessCodes as
$key => $item)
345 if ($item[
'entityId'] === self::TYPE_USER)
347 $accessCodes[
$key][
'id'] = self::CODE_USER . (int)$accessCodes[
$key][
'id'];
349 elseif ($item[
'entityId'] === self::TYPE_DEPARTMENT)
351 $accessCodes[
$key][
'id'] = self::CODE_DEPARTMENT . (int)$accessCodes[
$key][
'id'];
353 elseif ($item[
'entityId'] === self::TYPE_PROJECT)
355 $accessCodes[
$key][
'id'] = self::CODE_PROJECT . (int)$accessCodes[
$key][
'id'];
358 unset($accessCodes[
$key]);
372 foreach ($accessCodes as $ac)
374 $codes[] = $ac[
'id'];
376 $this->setScopeByAccessCodes(
394 string $categoryName,
409 'userScopeId' => $userScopeId,
418 CUserOptions::SetOption($categoryName,
"{$guid}_scope", $value,
false,
$userId);
424 return EntityFormConfigTable::update($id, [
431 return EntityFormConfigTable::update($id, [
443 $this->removeScopeMembers($configId);
451 $accessCodeCollection = EntityFormConfigAcTable::createCollection();
452 foreach ($accessCodes as $accessCode =>
$type)
454 $accessCodeItem = EntityFormConfigAcTable::createObject()
455 ->setAccessCode($accessCode)
456 ->setConfigId($configId);
458 $accessCodeCollection->add($accessCodeItem);
461 return $accessCodeCollection->save(
true);
470 $accessCodes = EntityFormConfigAcTable::getList([
471 'select' => [
'ACCESS_CODE'],
472 'filter' => [
'=CONFIG_ID' => $configId],
475 if (
count($accessCodes))
477 foreach ($accessCodes as $accessCodeEntity)
479 $accessCode =
new AccessCode($accessCodeEntity[
'ACCESS_CODE']);
480 $member = (
new DataProvider())->getEntity($accessCode->getEntityType(), $accessCode->getEntityId());
481 $result[$accessCodeEntity[
'ACCESS_CODE']] = $member->getMetaData();
490 private function removeScopeMembers(
int $configId): void
492 $entity = EntityFormConfigAcTable::getEntity();
495 $filter = [
'CONFIG_ID' => $configId];
498 'DELETE FROM %s WHERE %s',
506 return EntityFormConfigTable::update($id, [
507 'AUTO_APPLY_SCOPE' => $autoApplyScope ?
'Y' :
'N',
511 private function setScopeToDepartment(
512 string $categoryName,
519 $userIds = $this->getUserIdsByDepartment($departmentId);
526 private function setScopeToSocialGroup(
527 string $categoryName,
534 $userIds = $this->getUserIdsBySocialGroup($socialGroupId);
543 Application::getInstance()->addBackgroundJob(
static function() use (
$event)
545 $member =
$event->getParameter(
'member');
547 $memberId = $member->entityId;
548 $departmentId = $member->nodeId;
552 $appliedEntities = [];
553 foreach ($scopes as $scope)
555 if (!in_array($scope->getEntityTypeId(), $appliedEntities))
557 $appliedEntities[] = $scope->getEntityTypeId();
559 $scope->getOptionCategory(),
560 $scope->getEntityTypeId(),
572 Application::getInstance()->addBackgroundJob(
static function() use ($id,
$fields)
574 if (!\
Bitrix\
Main\Loader::includeModule(
'socialnetwork'))
579 if (empty(
$fields[
'ROLE']) &&
$fields[
'ROLE'] !== UserToGroupTable::ROLE_USER)
586 $userToGroup = UserToGroupTable::getById($id)->fetchObject();
593 $memberId = $userToGroup->getUserId();
594 $socialGroupId = $userToGroup->getGroupId();
598 $memberId =
$fields[
'USER_ID'];
599 $socialGroupId =
$fields[
'GROUP_ID'];
605 $appliedEntities = [];
606 foreach ($scopes as $scope)
608 if (!in_array($scope->getEntityTypeId(), $appliedEntities))
610 $appliedEntities[] = $scope->getEntityTypeId();
612 $scope->getOptionCategory(),
613 $scope->getEntityTypeId(),
623 private function getScopesByDepartment(
int $departmentId,
bool $onlyAutoApplyView =
false):
array
626 $nodeRepository = Container::getNodeRepository();
627 $node = $nodeRepository->getById($departmentId);
633 $parentNodes = $nodeRepository->getParentOf($node, DepthLevel::FULL);
634 foreach ($parentNodes as $node)
636 $accessCode = str_replace(
'D',
'DR', $node->accessCode);
637 $accessCodes = array_merge($accessCodes, $this->getScopesByAccessCode($accessCode, $onlyAutoApplyView));
643 private function getScopesBySocialGroupId(
int $socialGroupId,
bool $onlyAutoApplyView =
false):
array
645 $accessCode =
'SG' . $socialGroupId;
647 return $this->getScopesByAccessCode($accessCode, $onlyAutoApplyView);
650 private function getScopesByAccessCode(
string $accessCode,
bool $onlyAutoApplyView =
false)
652 $filter = [
'=ACCESS_CODE' => $accessCode];
653 if ($onlyAutoApplyView)
655 $filter[
'=CONFIG.AUTO_APPLY_SCOPE'] =
'Y';
658 $scopes = EntityFormConfigAcTable::query()
659 ->setSelect([
'ACCESS_CODE',
'CONFIG'])
661 ->setOrder([
'CONFIG.ID' =>
'DESC'])
664 return $scopes->getConfigList();
669 $scope = EntityFormConfigTable::getById($scopeId)->fetchObject();
678 $this->setScopeByAccessCodes(
679 $scope->getOptionCategory(),
680 $scope->getEntityTypeId(),
689 $accessCodes = EntityFormConfigAcTable::query()
690 ->setSelect([
'ACCESS_CODE'])
691 ->setFilter([
'=CONFIG_ID' => $scopeId])
694 foreach ($accessCodes as
$code)
702 private function setScopeByAccessCodes(
703 string $categoryName,
704 string $entityTypeId,
710 $userIdPattern =
'/^U(\d+)$/';
711 $departmentIdPattern =
'/^DR(\d+)$/';
712 $socialGroupIdPattern =
'/^SG(\d+)$/';
713 foreach ($accessCodes as $accessCode)
716 if (preg_match($userIdPattern, $accessCode,
$matches))
728 $this->setScopeToDepartment(
738 $this->setScopeToSocialGroup(
749 private function getUserIdsBySocialGroup(
int $socialGroupId):
array
751 if (!\Bitrix\Main\Loader::includeModule(
'socialnetwork'))
757 $userCollection = UserToGroupTable::query()
758 ->setSelect([
'USER_ID'])
760 '=GROUP_ID' => $socialGroupId,
762 UserToGroupTable::ROLE_MODERATOR,
763 UserToGroupTable::ROLE_USER,
764 UserToGroupTable::ROLE_OWNER,
770 foreach ($userCollection as $user)
772 $userIds[] =
$user->getUserId();
778 private function getUserIdsByDepartment(
int $departmentId):
array
781 if (!\Bitrix\Main\Loader::includeModule(
'humanresources'))
786 $hrServiceLocator = Container::instance();
787 $accessCode =
'DR' . $departmentId;
788 $node = $hrServiceLocator::getNodeRepository()->getByAccessCode($accessCode);
794 $allEmp = $hrServiceLocator::getNodeMemberService()->getAllEmployees($node->id,
true);
795 foreach ($allEmp->getIterator() as $emp)
797 $userIds[] = $emp->entityId;
803 private function getCurrentUserAccessCodes():
array
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)