Обратим внимание на структуру $arResult['CURRENT_ACCSESS']. В ней задаются права, доступные текущему пользователю по умолчанию. Далее получаем его идентификатор и определяем реальное состояние прав. Сразу отметим, что код обработки некоторых ситуаций, прежде всего, исключения «закрытых» и необщительных пользователей вынесен в конец модуля (поскольку он одинаков для обоих типов лент, и групповой и индивидуальной). Вкратце, схема довольно проста: добавим ID владельца в массив $arEntityUsersID, если мы каким-то образом узнали, что он не хочет, чтобы его записи видели посторонние, то есть, если не включен режим вывода сообщений из блога владельца ленты.
$isModuleAdmin = CSocNetUser::IsCurrentUserModuleAdmin();
$currentUserID = $GLOBALS['USER']->GetID();
if($arResult['ENTITY_TYPE'] == 'G') {
//для ленты групп проверим право на доступ к ней
$arResult['GROUP_INFO'] = CSocNetGroup::GetByID($arResult['ENTITY_ID']);
$arCurrentUserPerms = CSocNetUserToGroup::InitUserPerms($currentUserID, $arResult['GROUP_INFO'], $isModuleAdmin);
$arResult['CURRENT_ACCSESS']['canViewGroup'] = $arCurrentUserPerms['UserCanViewGroup'];
unset($arCurrentUserPerms);
if($arParams['INC_SELF_MESSAGES'] && $arResult['CURRENT_ACCSESS']['canViewGroup']) {
$arResult['CURRENT_ACCSESS']['canViewGroupSelfMessages'] = CSocNetFeaturesPerms::CanPerformOperation($currentUserID, SONET_ENTITY_GROUP, $arResult['ENTITY_ID'], 'blog', 'view_post', $isModuleAdmin);
}
} else {
//для ленты пользователя проверим доступ к ней текущего пользователя
$arCurrentUserPerms = CSocNetUserPerms::InitUserPerms($currentUserID, $arResult['ENTITY_ID'], $isModuleAdmin);
$arResult['CURRENT_ACCSESS']['canViewUserFriends'] = $arCurrentUserPerms['Operations']['viewfriends'];
$arResult['CURRENT_ACCSESS']['canViewUserGroups'] = $arCurrentUserPerms['Operations']['viewgroups'];
if($arParams['INC_SELF_MESSAGES']) {
//если не нужно включать в ленту сообщения из своего блога, то и проверять ID пользователя не будем (экономим на количестве кэш-файлов)
$arResult['CURRENT_ACCSESS']['canViewUserSelfMessages'] = $currentUserID == $arResult['ENTITY_ID'];
}
unset($arCurrentUserPerms);
}
unset($currentUserID, $isModuleAdmin);
Значение $arResult['CURRENT_ACCSESS'] и будет дополнительным идентификатором кэша:
if($this->StartResultCache(false, array($arNavigation, $arResult['CURRENT_ACCSESS']), $cachePath)) {
//код компонента
//подключение шаблона, сохранения результатов в кэш.
$this->IncludeComponentTemplate();
}
Где $arNavigation – массив управляющих параметров для постраничной навигации, $cachePath – путь для хранения кэш-файла. Определение идентификаторов друзей и групп для получения по ним ID блогов в этом случае будет выглядеть примерно так (исходный текст несколько сокращен для обозримости).
//массив идентификаторов пользователей, из блогов которых будут выбираться записи
$arEntityUsersID = array();
//массив идентификаторов групп, из блогов которых будут выбираться записи
$arEntityGroupsID = array();
if($arResult['ENTITY_TYPE'] == 'U') {
//лента пользователя
//можно ли смотреть друзей для данного пользователя, доступны ли вообще блоги и друзья
$getFriends = false;
if($arResult['CURRENT_ACCSESS']['canViewUserFriends']) {
$getFriends = CPTK_SocialNetwork::IsAllowedFeature(SONET_ENTITY_USER, 'blog') && CSocNetUser::IsFriendsAllowed();
}
//можно ли смотреть группы для данного пользователя и доступны ли вообще блоги для групп
if($arResult['CURRENT_ACCSESS']['canViewUserGroups']) {
$getGroups = CPTK_SocialNetwork::IsAllowedFeature(SONET_ENTITY_GROUP, 'blog');
}
Определим ID друзей пользователя
if($getFriends) {
$arOrderUR = array();
$arFilterUR = array(
'RELATION' => SONET_RELATIONS_FRIEND,
'USER_ID' => $arResult['ENTITY_ID'],
);
$arGroupByUR = false;
$arNavigationUR = false;
$arSelectFieldsUR = array(
'FIRST_USER_ID',
'SECOND_USER_ID'
);
$rsItems = CSocNetUserRelations::GetList($arOrderUR, $arFilterUR, $arGroupByUR, $arNavigationUR, $arSelectFieldsUR);
while($arItem = $rsItems->Fetch())
{
$id_ = $arItem['FIRST_USER_ID'] == $arResult['ENTITY_ID'] ? intval($arItem['SECOND_USER_ID']) : intval($arItem['FIRST_USER_ID']);
$arEntityUsersID[$id_] = $id_;
}
unset($rsItems, $id_, $arOrderUR, $arGroupByUR, $arNavigationUR, $arSelectFieldsUR);
}
Здесь же важно заполнить записью массив $arEntityUsersID, на случай если пользователь запретил смотреть своих друзей.
if($arParams['INC_SELF_MESSAGES']) {
$arEntityUsersID[$arResult['ENTITY_ID']] = $arResult['ENTITY_ID'];
}
//Определим ID видимых и НЕ закрытых групп пользователя
if($getGroups)
{
$arOrderGR = array();
$arFilterGR = array(
'USER_ID' => $arResult['ENTITY_ID'],
'<=ROLE' => SONET_ROLES_USER,
'GROUP_SITE_ID' => SITE_ID,
'GROUP_ACTIVE' => 'Y',
'GROUP_VISIBLE' => 'Y'
);
$arGroupByGR = false;
$arNavigationGR = false;
$arSelectFieldsGR = array(
'GROUP_ID',
'GROUP_NAME'
);
$rsItems = CSocNetUserToGroup::GetList($arOrderGR, $arFilterGR, $arGroupByGR, $arNavigationGR, $arSelectFieldsGR);
while($arItem = $rsItems->GetNext(false, false)) {
$id_ = intval($arItem['GROUP_ID']);
$arEntityGroupsID[$id_] = array(
'ID' => $id_,
'NAME' => $arItem['GROUP_NAME']
);
}
unset($rsItems, $id_, $arOrderGR, $arGroupByGR, $arNavigationGR, $arSelectFieldsGR);
if(!empty($arEntityGroupsID)) {
//Определим группы, у которых блоги имеют статус «приватных» и исключим их из списка
$arExceptGroupEntity = CPTK_SocialNetwork::GetByRoleFeaturesIdArray(SONET_ENTITY_GROUP, 'blog', 'view_post', array('!ROLE' => SONET_ROLES_ALL), array('!ROLE' => SONET_ROLES_ALL));
$arTmp = array_intersect_key($arExceptGroupEntity, $arEntityGroupsID);
unset($arExceptGroupEntity);
if(!empty($arTmp)) {
foreach($arTmp as $key) {
unset($arEntityGroupsID[$key]);
}
}
unset($arTmp);
//Определим группы, в которых вообще отключены блоги и исключим их из списка
$arExceptGroupEntity = CPTK_SocialNetwork::GetByRoleFeaturesIdArray(SONET_ENTITY_GROUP, 'blog', 'view_post', array('FEATURE_ACTIVE' => 'N'), array('FEATURE_ACTIVE' => 'N'));
$arTmp = array_intersect_key($arExceptGroupEntity, $arEntityGroupsID);
unset($arExceptGroupEntity);
if(!empty($arTmp)) {
foreach($arTmp as $key) {
unset($arEntityGroupsID[$key]);
}
}
unset($arTmp);
}
}
}
Кроме того, необходимо обработать ситуацию, когда мы имеем дело с лентой для группы. Определяем "открыта ли группа для просмотра текущему пользователю" и вообще "могут ли пользователи иметь блоги".
$getMembers = false;
if($arResult['CURRENT_ACCSESS']['canViewGroup']) {
$getMembers = CPTK_SocialNetwork::IsAllowedFeature(SONET_ENTITY_USER, 'blog');
}
//Определим ID участников группы
if($getMembers) {
$arOrderGM = array();
$arFilterGM = array(
'<=ROLE' => SONET_ROLES_USER,
'GROUP_ID' => $arResult['ENTITY_ID'],
);
$arGroupByGM = false;
$arNavigationGM = false;
$arSelectFieldsGM = array(
'USER_ID'
);
$rsItems = CSocNetUserToGroup::GetList($arOrderGM, $arFilterGM, $arGroupByGM, $arNavigationGM, $arSelectFieldsGM);
while($arItem = $rsItems->Fetch()) {
$id_ = intval($arItem['USER_ID']);
$arEntityUsersID[$id_] = $id_;