ControllerBased::build

  1. Bitrix24 API (v. 23.675.0)
  2. crm
  3. ControllerBased
  4. build
  • Модуль: 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})";
}

Добавить комментарий