...Человеческий поиск в разработке...
- Модуль: crm
- Путь к файлу: ~/bitrix/modules/crm/lib/security/controller/querybuilder/controllerbased.php
- Класс: Bitrix\Crm\Security\Controller\QueryBuilder\ControllerBased
- Вызов: ControllerBased::build
public function build( Collection $attributes, Options $options ): string { $restrictionMap = $this->getRestrictionsByAttributes($attributes, $options); $dataSourceTable = $this->controller->getTableName(); $prefix = $options->getAliasPrefix(); $finalSqlConditions = []; $unRestrictedEntityTypes = []; $isEntityWithCategories = $this->controller->hasCategories(); foreach ($restrictionMap as $restriction) { $entityTypes = isset($restriction['ENTITY_TYPES']) ? $restriction['ENTITY_TYPES'] : []; $categoryIds = isset($restriction['CATEGORY_ID']) ? $restriction['CATEGORY_ID'] : []; $categoriesCount = $isEntityWithCategories ? count($categoryIds) : 0; $progressSqlCondition = ''; $categoryIdSqlCondition = ''; if ($categoriesCount > 1) { $slug = implode(",", $categoryIds); $categoryIdSqlCondition = "{$prefix}P.CATEGORY_ID IN ({$slug})"; } elseif ($categoriesCount === 1) { $categoryId = $categoryIds[0]; $categoryIdSqlCondition = "{$prefix}P.CATEGORY_ID = {$categoryId}"; $progressSqlCondition = $this->getProgressSqlCondition($restriction['PROGRESS_STEPS'] ?? [], $prefix); } elseif (!$isEntityWithCategories) { $progressSqlCondition = $this->getProgressSqlCondition($restriction['PROGRESS_STEPS'] ?? [], $prefix); } $categoryIdSqlConditionWithAnd = $categoryIdSqlCondition === '' ? '' : "{$categoryIdSqlCondition} AND "; $isOpened = isset($restriction['OPENED']) && $restriction['OPENED']; $userIDs = isset($restriction['USER_IDS']) ? $restriction['USER_IDS'] : []; $hasOnlyCategoryCondition = false; if (!$isOpened && empty($userIDs) && $progressSqlCondition === '') { if ($categoryIdSqlCondition !== '') { $finalSqlConditions[] = $categoryIdSqlCondition; $hasOnlyCategoryCondition = true; } $unRestrictedEntityTypes = array_merge($unRestrictedEntityTypes, $entityTypes); } else { $isProcessed = false; if ($isOpened) { $baseSqlCondition = "{$categoryIdSqlConditionWithAnd}{$prefix}P.IS_OPENED = 'Y'"; $finalSqlConditions[] = $progressSqlCondition === '' ? "({$baseSqlCondition})" : "({$baseSqlCondition} AND {$progressSqlCondition})"; $isProcessed = true; } if (!empty($userIDs)) { if (count($userIDs) === 1) { $baseSqlCondition = "{$categoryIdSqlConditionWithAnd}{$prefix}P.USER_ID = {$userIDs[0]}"; } else { $slug = implode(',', $userIDs); $baseSqlCondition = "{$categoryIdSqlConditionWithAnd}{$prefix}P.USER_ID IN ({$slug})"; } $finalSqlConditions[] = $progressSqlCondition === '' ? "({$baseSqlCondition})" : "({$baseSqlCondition} AND {$progressSqlCondition})"; $isProcessed = true; } if (!$isProcessed) { $finalSqlConditions[] = "({$categoryIdSqlConditionWithAnd}{$progressSqlCondition})"; } } } // / Leave for the backward compatibility. Observer access logic moved to the access_attrs table. if (\Bitrix\Main\Config\Option::get('crm', 'CRM_MOVE_OBSERVERS_TO_ACCESS_ATTR_IN_WORK', 'Y') === 'Y') { $finalSqlConditions = array_merge( $finalSqlConditions, $this->buildObserverSqlCondition( $attributes->getUserId(), array_diff($attributes->getAllowedEntityTypes(), $unRestrictedEntityTypes), $prefix ) ); } $finalSqlConditions = array_filter($finalSqlConditions); if (empty($finalSqlConditions)) { return ''; } if ($options->isReadAllAllowed() && !$hasOnlyCategoryCondition) { $finalSqlConditions[] = "({$categoryIdSqlConditionWithAnd}{$prefix}P.IS_ALWAYS_READABLE = 'Y')"; } $querySqlCondition = implode(' OR ', $finalSqlConditions); if ($options->needReturnRawQuery()) { $distinct = $options->isUseRawQueryDistinct() ? 'DISTINCT ' : ''; $querySql = "SELECT {$distinct}{$prefix}P.ENTITY_ID FROM {$dataSourceTable} {$prefix}P WHERE {$querySqlCondition}"; if ($options->getRawQueryLimit() > 0) { $order = $options->getRawQueryOrder(); $querySql = Application::getConnection()->getSqlHelper()->getTopSql( $querySql . " ORDER BY ENTITY_ID {$order}", $options->getRawQueryLimit() ) ; } return $querySql; } $identity = $options->getIdentityColumnName(); if ($options->needUseJoin()) { return "INNER JOIN {$dataSourceTable} {$prefix}P ON {$prefix}.{$identity} = {$prefix}P.ENTITY_ID AND ({$querySqlCondition})"; } return "{$prefix}.{$identity} IN (SELECT {$prefix}P.ENTITY_ID FROM {$dataSourceTable} {$prefix}P WHERE {$querySqlCondition})"; }