Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
IblockCatalogPermissionsSaver.php
1<?php
2
4
16use CIBlock;
17use CIBlockRights;
18use Throwable;
19
46{
50 private const READ_LETTER = 'S';
51 private const WRITE_LETTER = 'W';
52 private const FULL_LETTER = 'X';
53
54 private ?string $siteId;
55 private array $defaultRights;
59 private array $permissions = [];
60
64 public function __construct(string $siteId = null)
65 {
66 Loader::requireModule('iblock');
67
68 $this->siteId = $siteId ?? Context::getCurrent()->getSite();
69 }
70
78 public function add(IblockCatalogPermissions $permission): void
79 {
80 $this->permissions[] = $permission;
81 }
82
83 public static function convertRightsModeByAgent(string $mode): void
84 {
86 {
87 return;
88 }
89
90 $saver = new self();
92 try
93 {
94 $db->startTransaction();
95
96 foreach ($saver->getIblockIds() as $iblockId)
97 {
98 $saver->convertRightsMode($iblockId, $mode);
99 }
100
101 $db->commitTransaction();
102 }
103 catch (Throwable $e)
104 {
105 $db->rollbackTransaction();
106 throw $e;
107 }
108 }
109
115 public function save(): void
116 {
117 $deleteAccessCodes = $this->getDeleteAccessCodes();
118 $actualAccessCodes = $this->getActualAccessCodesMap();
119 $iblockCatalogIds = $this->getIblockIds();
120
121 foreach ($iblockCatalogIds as $iblockId)
122 {
123 if (empty($actualAccessCodes))
124 {
125 $this->saveIblockRight($iblockId, null, [], $deleteAccessCodes);
126 }
127 foreach ($actualAccessCodes as $taskId => $accessCodes)
128 {
129 $this->saveIblockRight(
130 $iblockId,
131 $taskId,
132 $accessCodes,
133 $deleteAccessCodes
134 );
135 }
136 }
137 }
138
139 private function getDeleteAccessCodes(): array
140 {
141 $result = [];
142
143 foreach ($this->permissions as $permission)
144 {
145 foreach ($permission->getDeleteAccessCodes() as $accessCode)
146 {
147 $result[$accessCode] = true;
148 }
149 }
150
151 return array_keys($result);
152 }
153
154 private function getActualAccessCodesMap(): array
155 {
156 $result = [];
157
158 foreach ($this->permissions as $permission)
159 {
160 $taskId = $this->getIblockRightTaskId($permission);
161 foreach ($permission->getAccessCodes() as $accessCode)
162 {
163 $result[$taskId][$accessCode] = true;
164 }
165 }
166
167 foreach ($result as $taskId => & $accessCodes)
168 {
169 $accessCodes = array_keys($accessCodes);
170 }
171 unset($accessCodes);
172
173 return $result;
174 }
175
181 private function getIblockIds(): array
182 {
183 static $iblockIds;
184
185 if (!isset($iblockIds))
186 {
188 'select' => [
189 'IBLOCK_ID',
190 ],
191 'filter' => [
192 '=IBLOCK.IBLOCK_TYPE_ID' => 'CRM_PRODUCT_CATALOG',
193 ],
194 ]);
195 $iblockIds = array_column($rows->fetchAll(), 'IBLOCK_ID');
196
197 // filter by site
198 if ($iblockIds && isset($this->siteId))
199 {
200 $rows = IblockSiteTable::getList([
201 'select' => [
202 'IBLOCK_ID',
203 ],
204 'filter' => [
205 '=SITE_ID' => $this->siteId,
206 '=IBLOCK_ID' => $iblockIds,
207 ],
208 ]);
209 $iblockIds = array_column($rows->fetchAll(), 'IBLOCK_ID');
210 }
211 }
212
213 return $iblockIds;
214 }
215
226 private function saveIblockRight(int $iblockId, ?int $taskId, array $accessCodes, array $deleteAccessCodes): void
227 {
228 if (empty($accessCodes) && empty($deleteAccessCodes))
229 {
230 return;
231 }
232
233 $this->convertRightsMode($iblockId);
234
235 $usedAccessCodes = [];
236 $iblockRights = new CIBlockRights($iblockId);
237 $isNeedResetIblockRights = false;
238
239 $rights = $iblockRights->GetRights();
240 foreach ($rights as $id => &$right)
241 {
242 $rightAccessCode = $right['GROUP_CODE'];
243 if (in_array($rightAccessCode, $deleteAccessCodes, true))
244 {
245 unset($rights[$id]);
246 $isNeedResetIblockRights = true;
247
248 continue;
249 }
250
251 if (!in_array($rightAccessCode, $accessCodes, true))
252 {
253 continue;
254 }
255 $usedAccessCodes[] = $rightAccessCode;
256
257 $rightTaskId = (int)$right['TASK_ID'];
258 if ($rightTaskId !== $taskId)
259 {
260 if (empty($taskId))
261 {
262 unset($rights[$id]);
263 }
264 else
265 {
266 $right['TASK_ID'] = $taskId;
267 }
268
269 $isNeedResetIblockRights = true;
270 }
271 }
272 unset($right);
273
274 if (!empty($taskId))
275 {
276 $i = 0;
277 $newAccessCodes = array_diff($accessCodes, $usedAccessCodes);
278 foreach ($newAccessCodes as $accessCode)
279 {
280 $rights["n{$i}"] = [
281 'GROUP_CODE' => $accessCode,
282 'TASK_ID' => $taskId,
283 ];
284 $i++;
285
286 $isNeedResetIblockRights = true;
287 }
288 }
289
290 if (!$isNeedResetIblockRights)
291 {
292 return;
293 }
294
295 $rights = $this->appendDefaultRights($rights);
296 $rights = array_slice($rights, 0, 300, true);
297
298 $iblockRights->SetRights($rights);
299 }
300
306 private static function getIblockRightsLetterToTaskId(): array
307 {
308 static $iblockTasks;
309
310 if (!isset($iblockTasks))
311 {
312 $rows = TaskTable::getList([
313 'select' => [
314 'ID',
315 'LETTER',
316 ],
317 'filter' => [
318 'MODULE_ID' => 'iblock',
319 ],
320 ]);
321 $iblockTasks = array_column($rows->fetchAll(), 'ID', 'LETTER');
322 }
323
324 return $iblockTasks;
325 }
326
332 private function getIblockRightTaskId(IblockCatalogPermissions $permissions): int
333 {
334 $iblockTasks = self::getIblockRightsLetterToTaskId();
335
336 if ($permissions->getCanFullAccess())
337 {
338 return (int)$iblockTasks[self::FULL_LETTER];
339 }
340
341 if ($permissions->getCanRead() && $permissions->getCanWrite())
342 {
343 return (int)$iblockTasks[self::WRITE_LETTER];
344 }
345
346 if ($permissions->getCanRead())
347 {
348 return (int)$iblockTasks[self::READ_LETTER];
349 }
350
351 return 0;
352 }
353
363 private function convertRightsMode(int $iblockId, string $mode = IblockTable::RIGHTS_EXTENDED): void
364 {
365 $mode = ($mode === IblockTable::RIGHTS_EXTENDED) ? IblockTable::RIGHTS_EXTENDED : IblockTable::RIGHTS_SIMPLE;
366 $currentRightsMode = CIBlock::GetArrayByID($iblockId, 'RIGHTS_MODE');
367 if ($currentRightsMode === $mode)
368 {
369 return;
370 }
371
372 if ($mode === IblockTable::RIGHTS_SIMPLE)
373 {
374 $currentGroup = new CIBlockRights($iblockId);
375 $convertGroupRights = [];
376 $iblockTaskIds = array_flip(self::getIblockRightsLetterToTaskId());
377 foreach ($currentGroup->GetRights() as $group)
378 {
379 if (!empty($group['GROUP_CODE']) && $group['GROUP_CODE'][0] === 'G')
380 {
381 $code = (int)mb_substr($group['GROUP_CODE'], 1);
382 $isAdminGroup = ($code === 1);
383 if ($code && !$isAdminGroup)
384 {
385 $convertGroupRights[$code] = $iblockTaskIds[$group['TASK_ID']];
386 }
387 }
388 }
389 }
390
391 $iblock = new CIBlock();
392 $result = $iblock->Update(
393 $iblockId,
394 [
395 'RIGHTS_MODE' => $mode,
396 'GROUP_ID' => CIBlock::GetGroupPermissions($iblockId),
397 ]
398 );
399
400 if (!$result)
401 {
402 throw new SystemException("Cannot change iblock '{$iblockId}' rights mode");
403 }
404
405 if ($mode === IblockTable::RIGHTS_SIMPLE && $convertGroupRights)
406 {
407 \CIBlock::SetPermission($iblockId, $convertGroupRights);
408 }
409 }
410
416 private function getDefaultIblockRights(): array
417 {
418 if (!isset($this->defaultRights))
419 {
420 $iblockTasks = self::getIblockRightsLetterToTaskId();
421
422 $this->defaultRights = [
423 'G2' => $iblockTasks['R'],
424 ];
425
426 $rows = GroupTable::getList([
427 'select' => [
428 'ID',
429 'STRING_ID',
430 ],
431 'filter' => [
432 '@STRING_ID' => [
433 'CRM_SHOP_ADMIN',
434 'CRM_SHOP_MANAGER',
435 ],
436 ],
437 ]);
438 $crmGroups = array_column($rows->fetchAll(), 'ID', 'STRING_ID');
439 $crmGroupsRights = [
440 'CRM_SHOP_ADMIN' => $iblockTasks['X'],
441 'CRM_SHOP_MANAGER' => $iblockTasks['W'],
442 ];
443
444 foreach ($crmGroupsRights as $groupCode => $rightCode)
445 {
446 if (isset($crmGroups[$groupCode]))
447 {
448 $this->defaultRights['G' . $crmGroups[$groupCode]] = $rightCode;
449 }
450 }
451 }
452
453 return $this->defaultRights;
454 }
455
463 private function appendDefaultRights(array $rights): array
464 {
465 $defaultRights = $this->getDefaultIblockRights();
466 foreach ($rights as $item)
467 {
468 $accessCode = $item['GROUP_CODE'];
469 $defaultTaskId = $defaultRights[$accessCode] ?? null;
470 if (isset($defaultTaskId))
471 {
472 $item['TASK_ID'] = $defaultTaskId;
473 unset($defaultRights[$accessCode]);
474
475 if (empty($defaultRights))
476 {
477 break;
478 }
479 }
480 }
481
482 if (!empty($defaultRights))
483 {
484 $i = count($rights);
485 foreach ($defaultRights as $accessCode => $taskId)
486 {
487 $rights["n{$i}"] = [
488 'GROUP_CODE' => $accessCode,
489 'TASK_ID' => $taskId,
490 ];
491 $i++;
492 }
493 }
494
495 return $rights;
496 }
497
498 public static function updateShopAccessGroup(array $userIds, array $allUserIds, string $groupType): void
499 {
500 $shopIblockGroups = [
503 ];
504
505 if (!in_array($groupType, $shopIblockGroups, true))
506 {
507 return;
508 }
509
510 $groupId = self::getShopGroupIdByType($groupType);
511 if (!$groupId)
512 {
513 return;
514 }
515
516 $currentGroupUserIds = \CGroup::getGroupUser($groupId);
517 $nonGroupUsers = array_diff($allUserIds, $userIds);
518 if ($nonGroupUsers)
519 {
520 $removeFromGroup = array_intersect($nonGroupUsers, $currentGroupUserIds);
521 if ($removeFromGroup)
522 {
523 $userGroupCollection = UserGroupTable::query()
524 ->where('GROUP_ID', $groupId)
525 ->whereIn('USER_ID', $removeFromGroup)
526 ->fetchCollection()
527 ;
528
529 foreach ($userGroupCollection as $userGroup)
530 {
531 $userId = $userGroup->getUserId();
532 $userGroup->delete();
533 \CUser::clearUserGroupCache($userId);
534 }
535 }
536 }
537
538 $addToGroup = array_diff($userIds, $currentGroupUserIds);
539 foreach ($addToGroup as $userId)
540 {
541 \CUser::appendUserGroup($userId, [$groupId]);
542 }
543 }
544
545 private static function getShopGroupIdByType(string $type): ?int
546 {
547 $group = GroupTable::getRow([
548 'filter' => ['STRING_ID' => $type],
549 'select' => ['ID']
550 ]);
551
552 if ($group)
553 {
554 return (int)$group['ID'];
555 }
556
557 return null;
558 }
559}
static updateShopAccessGroup(array $userIds, array $allUserIds, string $groupType)
static getConnection($name="")
static getCurrent()
Definition context.php:241
static getRow(array $parameters)
static getList(array $parameters=array())