50 private const READ_LETTER =
'S';
51 private const WRITE_LETTER =
'W';
52 private const FULL_LETTER =
'X';
54 private ?
string $siteId;
55 private array $defaultRights;
59 private array $permissions = [];
66 Loader::requireModule(
'iblock');
80 $this->permissions[] = $permission;
94 $db->startTransaction();
96 foreach ($saver->getIblockIds() as $iblockId)
98 $saver->convertRightsMode($iblockId, $mode);
101 $db->commitTransaction();
105 $db->rollbackTransaction();
117 $deleteAccessCodes = $this->getDeleteAccessCodes();
118 $actualAccessCodes = $this->getActualAccessCodesMap();
119 $iblockCatalogIds = $this->getIblockIds();
121 foreach ($iblockCatalogIds as $iblockId)
123 if (empty($actualAccessCodes))
125 $this->saveIblockRight($iblockId,
null, [], $deleteAccessCodes);
127 foreach ($actualAccessCodes as $taskId => $accessCodes)
129 $this->saveIblockRight(
139 private function getDeleteAccessCodes(): array
143 foreach ($this->permissions as $permission)
145 foreach ($permission->getDeleteAccessCodes() as $accessCode)
147 $result[$accessCode] =
true;
151 return array_keys($result);
154 private function getActualAccessCodesMap(): array
158 foreach ($this->permissions as $permission)
160 $taskId = $this->getIblockRightTaskId($permission);
161 foreach ($permission->getAccessCodes() as $accessCode)
163 $result[$taskId][$accessCode] =
true;
167 foreach ($result as $taskId => & $accessCodes)
169 $accessCodes = array_keys($accessCodes);
181 private function getIblockIds(): array
185 if (!isset($iblockIds))
192 '=IBLOCK.IBLOCK_TYPE_ID' =>
'CRM_PRODUCT_CATALOG',
195 $iblockIds = array_column($rows->fetchAll(),
'IBLOCK_ID');
198 if ($iblockIds && isset($this->siteId))
200 $rows = IblockSiteTable::getList([
205 '=SITE_ID' => $this->siteId,
206 '=IBLOCK_ID' => $iblockIds,
209 $iblockIds = array_column($rows->fetchAll(),
'IBLOCK_ID');
226 private function saveIblockRight(
int $iblockId, ?
int $taskId, array $accessCodes, array $deleteAccessCodes): void
228 if (empty($accessCodes) && empty($deleteAccessCodes))
233 $this->convertRightsMode($iblockId);
235 $usedAccessCodes = [];
236 $iblockRights =
new CIBlockRights($iblockId);
237 $isNeedResetIblockRights =
false;
239 $rights = $iblockRights->GetRights();
240 foreach ($rights as $id => &$right)
242 $rightAccessCode = $right[
'GROUP_CODE'];
243 if (in_array($rightAccessCode, $deleteAccessCodes,
true))
246 $isNeedResetIblockRights =
true;
251 if (!in_array($rightAccessCode, $accessCodes,
true))
255 $usedAccessCodes[] = $rightAccessCode;
257 $rightTaskId = (int)$right[
'TASK_ID'];
258 if ($rightTaskId !== $taskId)
266 $right[
'TASK_ID'] = $taskId;
269 $isNeedResetIblockRights =
true;
277 $newAccessCodes = array_diff($accessCodes, $usedAccessCodes);
278 foreach ($newAccessCodes as $accessCode)
281 'GROUP_CODE' => $accessCode,
282 'TASK_ID' => $taskId,
286 $isNeedResetIblockRights =
true;
290 if (!$isNeedResetIblockRights)
295 $rights = $this->appendDefaultRights($rights);
296 $rights = array_slice($rights, 0, 300,
true);
298 $iblockRights->SetRights($rights);
306 private static function getIblockRightsLetterToTaskId(): array
310 if (!isset($iblockTasks))
312 $rows = TaskTable::getList([
318 'MODULE_ID' =>
'iblock',
321 $iblockTasks = array_column($rows->fetchAll(),
'ID',
'LETTER');
332 private function getIblockRightTaskId(IblockCatalogPermissions $permissions): int
334 $iblockTasks = self::getIblockRightsLetterToTaskId();
336 if ($permissions->getCanFullAccess())
338 return (
int)$iblockTasks[self::FULL_LETTER];
341 if ($permissions->getCanRead() && $permissions->getCanWrite())
343 return (
int)$iblockTasks[self::WRITE_LETTER];
346 if ($permissions->getCanRead())
348 return (
int)$iblockTasks[self::READ_LETTER];
366 $currentRightsMode = CIBlock::GetArrayByID($iblockId,
'RIGHTS_MODE');
367 if ($currentRightsMode === $mode)
374 $currentGroup =
new CIBlockRights($iblockId);
375 $convertGroupRights = [];
376 $iblockTaskIds = array_flip(self::getIblockRightsLetterToTaskId());
377 foreach ($currentGroup->GetRights() as $group)
379 if (!empty($group[
'GROUP_CODE']) && $group[
'GROUP_CODE'][0] ===
'G')
381 $code = (int)mb_substr($group[
'GROUP_CODE'], 1);
382 $isAdminGroup = ($code === 1);
383 if ($code && !$isAdminGroup)
385 $convertGroupRights[$code] = $iblockTaskIds[$group[
'TASK_ID']];
391 $iblock =
new CIBlock();
392 $result = $iblock->Update(
395 'RIGHTS_MODE' => $mode,
396 'GROUP_ID' => CIBlock::GetGroupPermissions($iblockId),
402 throw new SystemException(
"Cannot change iblock '{$iblockId}' rights mode");
407 \CIBlock::SetPermission($iblockId, $convertGroupRights);
416 private function getDefaultIblockRights(): array
418 if (!isset($this->defaultRights))
420 $iblockTasks = self::getIblockRightsLetterToTaskId();
422 $this->defaultRights = [
423 'G2' => $iblockTasks[
'R'],
438 $crmGroups = array_column($rows->fetchAll(),
'ID',
'STRING_ID');
440 'CRM_SHOP_ADMIN' => $iblockTasks[
'X'],
441 'CRM_SHOP_MANAGER' => $iblockTasks[
'W'],
444 foreach ($crmGroupsRights as $groupCode => $rightCode)
446 if (isset($crmGroups[$groupCode]))
448 $this->defaultRights[
'G' . $crmGroups[$groupCode]] = $rightCode;
453 return $this->defaultRights;
463 private function appendDefaultRights(array $rights): array
465 $defaultRights = $this->getDefaultIblockRights();
466 foreach ($rights as $item)
468 $accessCode = $item[
'GROUP_CODE'];
469 $defaultTaskId = $defaultRights[$accessCode] ??
null;
470 if (isset($defaultTaskId))
472 $item[
'TASK_ID'] = $defaultTaskId;
473 unset($defaultRights[$accessCode]);
475 if (empty($defaultRights))
482 if (!empty($defaultRights))
485 foreach ($defaultRights as $accessCode => $taskId)
488 'GROUP_CODE' => $accessCode,
489 'TASK_ID' => $taskId,
500 $shopIblockGroups = [
505 if (!in_array($groupType, $shopIblockGroups,
true))
510 $groupId = self::getShopGroupIdByType($groupType);
516 $currentGroupUserIds = \CGroup::getGroupUser($groupId);
517 $nonGroupUsers = array_diff($allUserIds, $userIds);
520 $removeFromGroup = array_intersect($nonGroupUsers, $currentGroupUserIds);
521 if ($removeFromGroup)
523 $userGroupCollection = UserGroupTable::query()
524 ->where(
'GROUP_ID', $groupId)
525 ->whereIn(
'USER_ID', $removeFromGroup)
529 foreach ($userGroupCollection as $userGroup)
531 $userId = $userGroup->getUserId();
532 $userGroup->delete();
533 \CUser::clearUserGroupCache($userId);
538 $addToGroup = array_diff($userIds, $currentGroupUserIds);
539 foreach ($addToGroup as $userId)
541 \CUser::appendUserGroup($userId, [$groupId]);
545 private static function getShopGroupIdByType(
string $type): ?int
548 'filter' => [
'STRING_ID' => $type],
554 return (
int)$group[
'ID'];