• Модуль: socialnetwork
  • Путь к файлу: ~/bitrix/modules/socialnetwork/lib/helper/workgroup.php
  • Класс: Bitrix\Socialnetwork\Helper\Workgroup
  • Вызов: Workgroup::getByFeatureOperation
static function getByFeatureOperation(array $params = []): array
{
	global $USER, $CACHE_MANAGER;

	$result = [];

	$feature = (string)($params['feature'] ?? '');
	$operation = (string)($params['operation'] ?? '');
	$userId = (int)(
		isset($params['userId'])
			? (int)$params['userId']
			: (is_object($USER) && $USER instanceof \CUser ? $USER->getId() : 0)
	);

	if (
		$feature === ''
		|| $operation === ''
		|| $userId <= 0
	)
	{
		return $result;
	}

	$featuresSettings = \CSocNetAllowed::getAllowedFeatures();
	if (
		empty($featuresSettings)
		|| empty($featuresSettings[$feature])
		|| empty($featuresSettings[$feature]['allowed'])
		|| empty($featuresSettings[$feature]['operations'])
		|| empty($featuresSettings[$feature]['operations'][$operation])
		|| empty($featuresSettings[$feature]['operations'][$operation][FeatureTable::FEATURE_ENTITY_TYPE_GROUP])
		|| !in_array(FeatureTable::FEATURE_ENTITY_TYPE_GROUP, $featuresSettings[$feature]['allowed'], true)
	)
	{
		return $result;
	}

	$cacheTTL = 3600 * 24 * 30;
	$cacheDir = '/sonet/features_perms/' . FeatureTable::FEATURE_ENTITY_TYPE_GROUP . '/list/' . (int)($userId / 1000);
	$cacheId = implode(' ', [ 'entities_list', $feature, $operation, $userId ]);

	$cache = new \CPHPCache();
	if ($cache->initCache($cacheTTL, $cacheId, $cacheDir))
	{
		$cacheValue = $cache->getVars();
		if (is_array($cacheValue))
		{
			$result = $cacheValue;
		}
	}
	else
	{
		$cache->startDataCache();
		$CACHE_MANAGER->startTagCache($cacheDir);

		$CACHE_MANAGER->registerTag('sonet_group');
		$CACHE_MANAGER->registerTag('sonet_features');
		$CACHE_MANAGER->registerTag('sonet_features2perms');
		$CACHE_MANAGER->registerTag('sonet_user2group');

		$defaultRole = $featuresSettings[$feature]['operations'][$operation][FeatureTable::FEATURE_ENTITY_TYPE_GROUP];

		$query = new \Bitrix\Main\Entity\Query(WorkgroupTable::getEntity());
		$query->addFilter('=ACTIVE', 'Y');

		if (
			(
				!is_array($featuresSettings[$feature]['minoperation'])
				|| !in_array($operation, $featuresSettings[$feature]['minoperation'], true)
			)
			&& Option::get('socialnetwork', 'work_with_closed_groups', 'N') !== 'Y'
		)
		{
			$query->addFilter('!=CLOSED', 'Y');
		}

		$query->addSelect('ID');

		$query->registerRuntimeField(
			'',
			new \Bitrix\Main\Entity\ReferenceField('F',
				FeatureTable::getEntity(),
				[
					'=ref.ENTITY_TYPE' => new SqlExpression('?s', FeatureTable::FEATURE_ENTITY_TYPE_GROUP),
					'=ref.ENTITY_ID' => 'this.ID',
					'=ref.FEATURE' => new SqlExpression('?s', $feature),
				],
				[ 'join_type' => 'LEFT' ]
			)
		);
		$query->addSelect('F.ID', 'FEATURE_ID');

		$query->registerRuntimeField(
			'',
			new \Bitrix\Main\Entity\ReferenceField('FP',
				FeaturePermTable::getEntity(),
				[
					'=ref.FEATURE_ID' => 'this.FEATURE_ID',
					'=ref.OPERATION_ID' => new SqlExpression('?s', $operation),
				],
				[ 'join_type' => 'LEFT' ]
			)
		);

		$query->registerRuntimeField(new \Bitrix\Main\Entity\ExpressionField(
			'PERM_ROLE_CALCULATED',
			'CASE WHEN %s IS NULL THEN \''.$defaultRole.'\' ELSE %s END',
			[ 'FP.ROLE', 'FP.ROLE' ]
		));

		$query->registerRuntimeField(
			'',
			new \Bitrix\Main\Entity\ReferenceField('UG',
				UserToGroupTable::getEntity(),
				[
					'=ref.GROUP_ID' => 'this.ID',
					'=ref.USER_ID' => new SqlExpression($userId),
				],
				[ 'join_type' => 'LEFT' ]
			)
		);

		$query->registerRuntimeField(new \Bitrix\Main\Entity\ExpressionField(
			'HAS_ACCESS',
			'CASE
			WHEN
				(
					%s NOT IN (\''.FeaturePermTable::PERM_OWNER.'\', \''.FeaturePermTable::PERM_MODERATOR.'\', \''.FeaturePermTable::PERM_USER.'\')
					OR %s >= %s
				) THEN \'Y\'
				ELSE \'N\'
		END',
			[
				'PERM_ROLE_CALCULATED',
				'PERM_ROLE_CALCULATED', 'UG.ROLE',
			]
		));

		$query->addFilter('=HAS_ACCESS', 'Y');

		$res = $query->exec();

		while ($row = $res->fetch())
		{
			$result[] = [
				'ID' => (int) $row['ID']
			];
		}

		$CACHE_MANAGER->endTagCache();
		$cache->endDataCache($result);
	}

	return $result;
}