...Человеческий поиск в разработке...
- Модуль: crm
- Путь к файлу: ~/bitrix/modules/crm/lib/security/controller/querybuilder/compatible.php
- Класс: Bitrix\Crm\Security\Controller\QueryBuilder\Compatible
- Вызов: Compatible::buildForEntity
protected function buildForEntity(Collection $attributes, Options $options, string $permEntity): string { $entityListAttributes = $attributes->getByEntityType($permEntity); $scopeRegex = $this->getScopeRegexForEntity($permEntity); $enableCumulativeMode = \COption::GetOptionString('crm', 'enable_permission_cumulative_mode', 'Y') === 'Y'; $userAccessAttributes = \Bitrix\Crm\Service\Container::getInstance() ->getUserPermissions($attributes->getUserId()) ->getAttributesProvider() ->getUserAttributes() ; $intranetAttrs = []; $allIntranetAttrs = isset($userAccessAttributes['INTRANET']) && is_array($userAccessAttributes['INTRANET']) ? $userAccessAttributes['INTRANET'] : []; if (!empty($allIntranetAttrs)) { foreach ($allIntranetAttrs as $attr) { if (preg_match('/^D\d+$/', $attr)) { $intranetAttrs[] = "'{$attr}'"; } } } $subIntranetAttrs = []; $allSubIntranetAttrs = isset($userAccessAttributes['SUBINTRANET']) && is_array($userAccessAttributes['SUBINTRANET']) ? $userAccessAttributes['SUBINTRANET'] : []; if (!empty($allSubIntranetAttrs)) { foreach ($allSubIntranetAttrs as $attr) { if (preg_match('/^D\d+$/', $attr)) { $subIntranetAttrs[] = "'{$attr}'"; } } } $permissionSets = []; foreach ($entityListAttributes as &$attrs) { if (empty($attrs)) { continue; } $permissionSet = [ 'USER' => '', 'CONCERNED_USER' => '', 'DEPARTMENTS' => [], 'OPENED_ONLY' => '', 'SCOPES' => [], ]; $qty = count($attrs); for ($i = 0; $i < $qty; $i++) { $attr = $attrs[$i]; if ($scopeRegex !== '' && preg_match($scopeRegex, $attr)) { $permissionSet['SCOPES'][] = "'{$attr}'"; } elseif ($attr === 'O') { $permissionSet['OPENED_ONLY'] = "'{$attr}'"; } elseif (preg_match('/^U\d+$/', $attr)) { $permissionSet['USER'] = "'{$attr}'"; $permissionSet['CONCERNED_USER'] = "'C{$attr}'"; } elseif (preg_match('/^D\d+$/', $attr)) { $permissionSet['DEPARTMENTS'][] = "'{$attr}'"; } } if (empty($permissionSet['SCOPES'])) { if ($permissionSet['OPENED_ONLY'] !== '') { //HACK: for OPENED ONLY mode - allow user own entities too. $userAttr = isset($userAccessAttributes['USER']) && is_array($userAccessAttributes['USER']) && !empty($userAccessAttributes['USER']) ? $userAccessAttributes['USER'][0] : ''; if ($userAttr !== '') { $permissionSets[] = [ 'USER' => "'{$userAttr}'", 'CONCERNED_USER' => "'C{$userAttr}'", 'DEPARTMENTS' => [], 'OPENED_ONLY' => '', 'SCOPES' => [], ]; } if ($enableCumulativeMode && !empty($intranetAttrs)) { //OPENED ONLY mode - allow user department entities too. $permissionSets[] = [ 'USER' => '', 'CONCERNED_USER' => '', 'DEPARTMENTS' => array_unique(array_merge($intranetAttrs, $subIntranetAttrs)), 'OPENED_ONLY' => '', 'SCOPES' => [], ]; } } $permissionSets[] = &$permissionSet; unset($permissionSet); } else { $permissionSet = $this->registerPermissionSet($permissionSets, $permissionSet); if ($permissionSet['OPENED_ONLY'] !== '') { //HACK: for OPENED ONLY mode - allow user own entities too. $userAttr = isset($userAccessAttributes['USER']) && is_array($userAccessAttributes['USER']) && !empty($userAccessAttributes['USER']) ? $userAccessAttributes['USER'][0] : ''; if ($userAttr !== '') { $this->registerPermissionSet( $permissionSets, [ 'USER' => "'{$userAttr}'", 'CONCERNED_USER' => "'C{$userAttr}'", 'DEPARTMENTS' => [], 'OPENED_ONLY' => '', 'SCOPES' => $permissionSet['SCOPES'], ] ); } } } } unset($attrs); $isRestricted = false; $subQueries = []; $effectiveEntityIDs = $options->getLimitByIds(); $aliasPrefix = $options->getAliasPrefix(); foreach ($permissionSets as &$permissionSet) { $scopes = $permissionSet['SCOPES']; $scopeQty = count($scopes); if ($scopeQty === 0) { $restrictions = []; if ($permissionSet['OPENED_ONLY'] !== '') { $attr = $permissionSet['OPENED_ONLY']; $restrictions[] = "{$aliasPrefix}P.ATTR = {$attr}"; } elseif ($permissionSet['USER'] !== '') { $restrictions[] = $aliasPrefix . 'P.ATTR = ' . $permissionSet['USER']; if ($permissionSet['CONCERNED_USER'] !== '') { $restrictions[] = $aliasPrefix . 'P.ATTR = ' . $permissionSet['CONCERNED_USER']; } } elseif (!empty($permissionSet['DEPARTMENTS'])) { $departments = $permissionSet['DEPARTMENTS']; $restrictions[] = count($departments) > 1 ? $aliasPrefix . 'P.ATTR IN(' . implode(', ', $departments) . ')' : $aliasPrefix . 'P.ATTR = ' . $departments[0]; } if (!empty($restrictions)) { foreach ($restrictions as $restriction) { $subQuery = "SELECT {$aliasPrefix}P.ENTITY_ID FROM b_crm_entity_perms {$aliasPrefix}P WHERE {$aliasPrefix}P.ENTITY = '{$permEntity}' AND {$restriction}"; if (!empty($effectiveEntityIDs)) { $subQuery .= " AND {$aliasPrefix}P.ENTITY_ID IN (" . implode(', ', $effectiveEntityIDs) . ")"; } $subQueries[] = $subQuery; } if (!$isRestricted) { $isRestricted = true; } } } else { $scopeSql = $scopeQty > 1 ? $aliasPrefix . 'P2.ATTR IN (' . implode(', ', $scopes) . ')' : $aliasPrefix . 'P2.ATTR = ' . $scopes[0]; $restrictions = []; if ($permissionSet['OPENED_ONLY'] !== '') { $attr = $permissionSet['OPENED_ONLY']; $restrictions[] = "{$aliasPrefix}P1.ATTR = {$attr}"; } elseif ($permissionSet['USER'] !== '') { $restrictions[] = $aliasPrefix . 'P1.ATTR = ' . $permissionSet['USER']; if ($permissionSet['CONCERNED_USER'] !== '') { $restrictions[] = $aliasPrefix . 'P1.ATTR = ' . $permissionSet['CONCERNED_USER']; } } elseif (!empty($permissionSet['DEPARTMENTS'])) { $departments = $permissionSet['DEPARTMENTS']; $restrictions[] = count($departments) > 1 ? $aliasPrefix . 'P1.ATTR IN(' . implode(', ', $departments) . ')' : $aliasPrefix . 'P1.ATTR = ' . $departments[0]; } if (!empty($restrictions)) { foreach ($restrictions as $restriction) { $subQuery = "SELECT {$aliasPrefix}P2.ENTITY_ID FROM b_crm_entity_perms {$aliasPrefix}P1 INNER JOIN b_crm_entity_perms {$aliasPrefix}P2 ON {$aliasPrefix}P1.ENTITY = '{$permEntity}' AND {$aliasPrefix}P2.ENTITY = '{$permEntity}' AND {$aliasPrefix}P1.ENTITY_ID = {$aliasPrefix}P2.ENTITY_ID AND {$restriction} AND {$scopeSql}"; if (!empty($effectiveEntityIDs)) { $subQuery .= " AND {$aliasPrefix}P2.ENTITY_ID IN (" . implode(',', $effectiveEntityIDs) . ")"; } $subQueries[] = $subQuery; } } else { $subQuery = "SELECT {$aliasPrefix}P2.ENTITY_ID FROM b_crm_entity_perms {$aliasPrefix}P2 WHERE {$aliasPrefix}P2.ENTITY = '{$permEntity}' AND {$scopeSql}"; if (!empty($effectiveEntityIDs)) { $subQuery .= " AND {$aliasPrefix}P2.ENTITY_ID IN (" . implode(',', $effectiveEntityIDs) . ")"; } $subQueries[] = $subQuery; } if (!$isRestricted) { $isRestricted = true; } } } unset($permissionSet); if (!$isRestricted) { return ''; } if ($options->isReadAllAllowed()) { //Add permission 'Read allowed to Everyone' permission $readAll = \CCrmPerms::ATTR_READ_ALL; $subQuery = "SELECT {$aliasPrefix}P.ENTITY_ID FROM b_crm_entity_perms {$aliasPrefix}P WHERE {$aliasPrefix}P.ENTITY = '{$permEntity}' AND {$aliasPrefix}P.ATTR = '{$readAll}'"; if (!empty($effectiveEntityIDs)) { $subQuery .= " AND {$aliasPrefix}P.ENTITY_ID IN (" . implode(',', $effectiveEntityIDs) . ")"; } $subQueries[] = $subQuery; } $subQuerySql = implode($options->needUseDistinctUnion() ? ' UNION ' : ' UNION ALL ', $subQueries); if ($options->needReturnRawQuery()) { if ($options->getRawQueryLimit() > 0) { $order = $options->getRawQueryOrder(); $subQuerySql = \Bitrix\Main\Application::getConnection()->getSqlHelper()->getTopSql( "{$subQuerySql} ORDER BY ENTITY_ID {$order}", $options->getRawQueryLimit() ) ; } return $subQuerySql; } $identityCol = $options->getIdentityColumnName(); if ($options->needUseJoin()) { return "INNER JOIN ({$subQuerySql}) {$aliasPrefix}GP ON {$aliasPrefix}.{$identityCol} = {$aliasPrefix}GP.ENTITY_ID"; } return "{$aliasPrefix}.{$identityCol} IN ({$subQuerySql})"; }