Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
AccessInstaller.php
1<?php
10
28use Throwable;
29
31{
32 private Connection $db;
33
34 public function __construct(Connection $db)
35 {
36 $this->db = $db;
37 }
38
39 public function createTables(): void
40 {
41 $this->db->Query("
42 CREATE TABLE IF NOT EXISTS b_catalog_role (
43 ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
44 NAME VARCHAR(250) NOT NULL,
45 PRIMARY KEY (ID)
46 );
47 ");
48
49 $this->db->Query("
50 CREATE TABLE IF NOT EXISTS b_catalog_role_relation (
51 ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
52 ROLE_ID INT UNSIGNED NOT NULL,
53 RELATION VARCHAR(8) NOT NULL DEFAULT '',
54 PRIMARY KEY (ID),
55 INDEX ROLE_ID (ROLE_ID),
56 INDEX RELATION (RELATION)
57 );
58 ");
59
60 $this->db->Query("
61 CREATE TABLE IF NOT EXISTS b_catalog_permission (
62 ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
63 ROLE_ID INT UNSIGNED NOT NULL,
64 PERMISSION_ID VARCHAR(32) NOT NULL DEFAULT '0',
65 VALUE INT NOT NULL DEFAULT '0',
66 PRIMARY KEY (ID),
67 INDEX ROLE_ID (ROLE_ID),
68 INDEX PERMISSION_ID (PERMISSION_ID)
69 );
70 ");
71 }
72
73 public static function installByAgent(): void
74 {
76
77 (new self($db))->install();
78 }
79
80 public static function installClean(): void
81 {
83
84 (new self($db))->install(false);
85 }
86
87 public function install($convertExisted = true): void
88 {
90 if (!$this->db->lock($lockName, 600))
91 {
92 return;
93 }
94
95 try
96 {
98
99 $this->db->startTransaction();
100 if ($convertExisted)
101 {
102 $this->fillSystemPermissions();
103 }
104 else
105 {
106 $this->fillDefaultSystemPermissions();
107 }
108 $this->db->commitTransaction();
109
111 }
112 catch (Throwable $e)
113 {
114 $this->db->rollbackTransaction();
115 throw $e;
116 }
117 finally
118 {
119 $this->db->unlock($lockName);
120 }
121 }
122
123 private function fillSystemPermissions(): void
124 {
125 if (PermissionTable::getCount())
126 {
127 return;
128 }
129
130 $catalogGroupTasks = GroupTaskTable::getList([
131 'filter' => [
132 'TASK.MODULE_ID' => 'catalog',
133 '!=TASK.LETTER' => 'D'
134 ],
135 'select' => [
136 'GROUP_ID',
137 'GROUP_NAME' => 'GROUP.NAME',
138 'TASK_ID',
139 ],
140 ])
141 ->fetchAll()
142 ;
143
144 if (!$catalogGroupTasks)
145 {
146 $this->fillDefaultSystemPermissions();
147
148 return;
149 }
150
151 $this->fillGroupTaskPermissions($catalogGroupTasks);
152 $this->fillDefaultSystemPermissions([RoleDictionary::ROLE_STOCKMAN]);
153 }
154
155 private function fillGroupTaskPermissions(array $catalogGroupTasks): void
156 {
157 $taskIds = array_column($catalogGroupTasks, 'TASK_ID');
158 $taskOperations = TaskOperationTable::getList([
159 'filter' => [
160 'TASK_ID' => $taskIds,
161 ],
162 'select' => [
163 'TASK_ID',
164 'OPERATION_NAME' => 'OPERATION.NAME',
165 ],
166 ]);
167
169 $storeDocumentsInstallerMap = [
170 ActionDictionary::ACTION_STORE_DOCUMENT_VIEW => PermissionDictionary::CATALOG_STORE_DOCUMENT_VIEW,
171 ActionDictionary::ACTION_STORE_DOCUMENT_MODIFY => PermissionDictionary::CATALOG_STORE_DOCUMENT_MODIFY,
172 ActionDictionary::ACTION_STORE_DOCUMENT_CANCEL => PermissionDictionary::CATALOG_STORE_DOCUMENT_CANCEL,
173 ActionDictionary::ACTION_STORE_DOCUMENT_CONDUCT => PermissionDictionary::CATALOG_STORE_DOCUMENT_CONDUCT,
174 ActionDictionary::ACTION_STORE_DOCUMENT_DELETE => PermissionDictionary::CATALOG_STORE_DOCUMENT_DELETE,
175 ActionDictionary::ACTION_STORE_DOCUMENT_ALLOW_NEGATION_PRODUCT_QUANTITY => PermissionDictionary::CATALOG_STORE_DOCUMENT_ALLOW_NEGATION_PRODUCT_QUANTITY,
176 ];
177 $permissionMap = array_merge($permissionMap, $storeDocumentsInstallerMap);
178
179 $taskPermissionMap = [];
180 while ($taskOperation = $taskOperations->fetch())
181 {
182 $taskId = $taskOperation['TASK_ID'];
183 $taskPermissionMap[$taskId] ??= [];
184
185 $newActions = ActionDictionary::getLegacyMap()[$taskOperation['OPERATION_NAME']] ?? [];
186 foreach ($newActions as $newAction)
187 {
188 $permission = $permissionMap[$newAction] ?? null;
189 if (!$permission)
190 {
191 continue;
192 }
193
194 if (in_array($permission, $storeDocumentsInstallerMap, true))
195 {
196 $documents = null;
197 if ($permission === PermissionDictionary::CATALOG_STORE_DOCUMENT_ALLOW_NEGATION_PRODUCT_QUANTITY)
198 {
199 $documents = [
203 ];
204 }
205 $taskPermissionMap[$taskId] = array_merge(
206 $taskPermissionMap[$taskId],
207 PermissionDictionary::getStoreDocumentPermissionRules([$permission], $documents)
208 );
209 }
210 else
211 {
212 $taskPermissionMap[$taskId][] = $permission;
213 }
214 }
215 }
216
217 $groups = [];
218 foreach ($catalogGroupTasks as $groupTask)
219 {
220 $groups[$groupTask['GROUP_ID']] ??= [];
221 $groups[$groupTask['GROUP_ID']]['NAME'] = $groupTask['GROUP_NAME'];
222 $groups[$groupTask['GROUP_ID']]['PERMISSIONS'][] = $taskPermissionMap[$groupTask['TASK_ID']];
223 }
224
225 $crmAdminGroupIds = [];
226 $crmAdminGroups = GroupTable::getList([
227 'filter' => ['=STRING_ID' => ShopGroupAssistant::SHOP_ADMIN_USER_GROUP_CODE],
228 'select' => ['ID'],
229 ]);
230 while ($crmAdminGroup = $crmAdminGroups->fetch())
231 {
232 $crmAdminGroupIds[] = (int)$crmAdminGroup['ID'];
233 }
234
235 foreach ($groups as $groupId => &$group)
236 {
237 $group['PERMISSIONS'] = array_unique(array_merge(...$group['PERMISSIONS']));
238 if (in_array($groupId, $crmAdminGroupIds, true))
239 {
240 $group['PERMISSIONS'][] = PermissionDictionary::CATALOG_SETTINGS_EDIT_RIGHTS;
241 }
242 }
243
244 $groupRoleMap = $this->fillGroupPermissions($groups);
245 $this->fillGroupUserRoleRelations($groupRoleMap);
246 }
247
248 private function fillGroupPermissions(array $groups): array
249 {
250 $query = [];
251 $result = [];
252 foreach ($groups as $groupId => $groupData)
253 {
254 if (!is_array($groupData['PERMISSIONS']) || !$groupData['PERMISSIONS'])
255 {
256 continue;
257 }
258
259 $role = RoleTable::add([
260 'NAME' => $groupData['NAME']
261 ]);
262
263 if (!$role->isSuccess())
264 {
265 continue;
266 }
267
268 $roleId = $role->getId();
269 foreach ($groupData['PERMISSIONS'] as $permissionId)
270 {
271 if ($permissionId === PermissionDictionary::CATALOG_PRODUCT_EDIT_ENTITY_PRICE && Option::get('crm', 'enable_product_price_edit') !== 'Y')
272 {
273 continue;
274 }
275
276 $value = PermissionDictionary::getDefaultPermissionValue($permissionId);
277 $query[] = "('{$roleId}', '{$permissionId}', '{$value}')";
278 }
279
280 $result[$groupId] = $roleId;
281 }
282
283 if (!empty($query))
284 {
285 RoleUtil::insertPermissions($query);
286 }
287
288 return $result;
289 }
290
291 private function fillGroupUserRoleRelations(array $groupRoleMap): void
292 {
293 $userGroups = UserGroupTable::getList([
294 'select' => ['USER_ID', 'GROUP_ID'],
295 'filter' => [
296 '=GROUP_ID' => array_keys($groupRoleMap),
297 '=USER.ACTIVE' => 'Y',
298 '=USER.IS_REAL_USER' => 'Y',
299 ],
300 ]);
301
302 $valuesData = [];
303 while ($user = $userGroups->fetch())
304 {
305 $groupId = (int)($groupRoleMap[$user['GROUP_ID']] ?? 0);
306 if ($groupId > 0)
307 {
308 $valuesData[] = new SqlExpression("(?, ?)", $groupId, "U{$user['USER_ID']}");
309 }
310 }
311
312 if (!$valuesData)
313 {
314 return;
315 }
316
317 $query = '
318 INSERT INTO b_catalog_role_relation
319 (ROLE_ID, RELATION)
320 VALUES ' . implode(',', $valuesData) . '
321 ';
322
323 Application::getConnection()->query($query);
324 }
325
326 private function fillDefaultSystemPermissions(array $roles = null): void
327 {
328 $map = RoleMap::getDefaultMap();
329
330 if ($roles !== null)
331 {
332 $map = array_intersect_key($map, array_flip($roles));
333 if (!$map)
334 {
335 return;
336 }
337 }
338
339 $query = [];
340 $roleNameIdMap = [];
341 foreach ($map as $roleName => $roleClass)
342 {
343 if (is_subclass_of($roleClass, Role\Base::class))
344 {
345 $roleMapItem = new $roleClass();
346 }
347 else
348 {
349 continue;
350 }
351
352 $role = RoleTable::add([
353 'NAME' => $roleName
354 ]);
355
356 if (!$role->isSuccess())
357 {
358 continue;
359 }
360
361 $roleId = $role->getId();
362 $roleNameIdMap[$roleName] = $roleId;
363 foreach ($roleMapItem->getMap() as $item)
364 {
365 $query[] = new SqlExpression(
366 '(?i,?,?)',
367 $roleId,
368 $item['permissionId'],
369 $item['value']
370 );
371 }
372 }
373
374 RoleUtil::insertPermissions($query);
375
376 if (!array_intersect_key($map, array_flip([RoleDictionary::ROLE_DIRECTOR, RoleDictionary::ROLE_SALESMAN])))
377 {
378 return;
379 }
380
381 $userGroups = GroupTable::getList([
382 'filter' => [
383 '=STRING_ID' => [
386 ]
387 ],
388 'select' => ['ID', 'STRING_ID']
389 ]);
390
391 $defaultGroupRoleMap = [];
392 while ($userGroup = $userGroups->fetch())
393 {
394 $role =
395 $userGroup['STRING_ID'] === ShopGroupAssistant::SHOP_ADMIN_USER_GROUP_CODE && $map[RoleDictionary::ROLE_DIRECTOR]
396 ? $roleNameIdMap[RoleDictionary::ROLE_DIRECTOR]
397 : $roleNameIdMap[RoleDictionary::ROLE_SALESMAN]
398 ;
399
400 $defaultGroupRoleMap[$userGroup['ID']] = $role;
401 }
402
403 if (!$defaultGroupRoleMap)
404 {
405 return;
406 }
407
408 $this->fillGroupUserRoleRelations($defaultGroupRoleMap);
409 }
410}
static getConnection($name="")
static getList(array $parameters=array())