• Модуль: socialnetwork
  • Путь к файлу: ~/bitrix/modules/socialnetwork/lib/integration/ui/entityselector/projectprovider.php
  • Класс: BitrixSocialnetworkIntegrationUIEntitySelectorProjectProvider
  • Вызов: ProjectProvider::getFeaturesPermissionsQuery
static function getFeaturesPermissionsQuery($currentUserId, $featuresList = [])
{
	$helper = BitrixMainApplication::getConnection()->getSqlHelper();
	$globalFeatures = CSocNetAllowed::getAllowedFeatures();

	$workWithClosedGroups = (Option::get('socialnetwork', 'work_with_closed_groups', 'N') === 'Y');

	$query = new BitrixMainEntityQuery(WorkgroupTable::getEntity());
	$query->addSelect('ID');

	if ($currentUserId > 0)
	{
		$query->registerRuntimeField(new Reference(
			'UG',
			UserToGroupTable::getEntity(),
			Join::on('this.ID', 'ref.GROUP_ID')
				->where('ref.USER_ID', $currentUserId),
			[ 'join_type' => 'INNER' ]
		));
	}

	$hasFilter = false;

	$featureEntity = clone FeatureTable::getEntity();

	foreach ($featuresList as $feature => $operationsList)
	{
		if (empty($operationsList))
		{
			continue;
		}

		$hasFilter = true;

		$defaultPerm = 'A';
		foreach ($globalFeatures[$feature]['operations'] as $operation => $perms)
		{
			if (
				!in_array($operation, $operationsList, true)
				|| !is_set($perms[FeatureTable::FEATURE_ENTITY_TYPE_GROUP])
			)
			{
				continue;
			}

			if ($perms[FeatureTable::FEATURE_ENTITY_TYPE_GROUP] > $defaultPerm)
			{
				$defaultPerm = $perms[FeatureTable::FEATURE_ENTITY_TYPE_GROUP];
			}
		}

		$query->registerRuntimeField(new Reference(
			"F_{$feature}",
			$featureEntity,
			Join::on('this.ID', 'ref.ENTITY_ID')
				->where('ref.ENTITY_TYPE', FeatureTable::FEATURE_ENTITY_TYPE_GROUP)
				->where('ref.FEATURE', $feature),
			[ 'join_type' => 'LEFT' ]
		));

		$featureEntity->addField(new Reference(
			"FP_{$feature}",
			FeaturePermTable::class,
			Join::on('this.ID', 'ref.FEATURE_ID'),
			[ 'join_type' => 'LEFT' ]
		));

		$query->where(BitrixMainEntityQuery::filter()
			->logic('or')
			->whereIn("F_{$feature}.FP_{$feature}.OPERATION_ID", $operationsList)
			->whereNull("F_{$feature}.FP_{$feature}.OPERATION_ID")
		);

		if ($currentUserId > 0)
		{
			$minOperationsList = ($globalFeatures[$feature]['minoperation'] ?? []);
			if (!is_array($minOperationsList))
			{
				$minOperationsList = [ $minOperationsList ];
			}

			$conditionsList = [];
			$substitutes = [];

			if (!$workWithClosedGroups && !empty($minOperationsList))
			{
				$minOperations = implode(', ', array_map(static function($operation) use ($helper) { return "'" . $helper->forSql($operation) . "'"; }, $minOperationsList));
				$conditionsList[] = "WHEN %s = 'Y' AND %s NOT IN ({$minOperations}) THEN 'A'";
				$substitutes[] = 'CLOSED';
				$substitutes[] = "F_{$feature}.FP_{$feature}.OPERATION_ID";
			}

			$conditionsList[] = "WHEN %s = 'N' AND %s IN ('N', 'L') THEN 'K'";
			$substitutes[] = 'VISIBLE';
			$substitutes[] = "F_{$feature}.FP_{$feature}.ROLE";

			$conditionsList[] = 'WHEN %s IS NOT NULL THEN %s';
			$substitutes[] = "F_{$feature}.FP_{$feature}.ROLE";
			$substitutes[] = "F_{$feature}.FP_{$feature}.ROLE";

			$conditions = implode(' ', $conditionsList);

			$query->registerRuntimeField(new ExpressionField(
				"MIN_PERMISSION_{$feature}",
				"CASE {$conditions} ELSE '{$defaultPerm}' END",
				$substitutes
			));

			$query->registerRuntimeField(
				new ExpressionField(
					"HAS_ACCESS_{$feature}",
					'CASE WHEN %s <= %s THEN 1 ELSE 0 END',
					[
						'UG.ROLE',
						"MIN_PERMISSION_{$feature}",
					]
				)
			);
			$query->where("HAS_ACCESS_{$feature}", 1);
		}
		else
		{
			$query->registerRuntimeField(new ExpressionField(
				"MIN_PERMISSION_{$feature}",
				"CASE WHEN %s IS NOT NULL THEN %s ELSE '{$defaultPerm}' END",
				[
					"F_{$feature}.FP_{$feature}.ROLE",
					"F_{$feature}.FP_{$feature}.ROLE"
				]
			));

			$query->where("MIN_PERMISSION_{$feature}", 'N');
		}
	}

	return ($hasFilter ? $query : false);
}