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;
}