PC Magazine/RE - Журнал PC Magazine/RE №09/2009 стр 25.

Шрифт
Фон

{

$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);

}

Код исключения «закрытых» пользователей вынесен в конец модуля (он общий для двух типов лент). Схема довольно проста: добавим ID владельца в массив $arEntityUsersID, если включен режим вывода сообщений из блога владельца ленты. Здесь же важно заполнить записью массив $arEntityUsersID на случай, если пользователь запретил смотреть своих друзей (листинг 5).

Листинг 5

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

}

}

Кроме того, необходимо обработать ситуацию, когда мы имеем дело с лентой для группы. Определяем, открыта ли группа для просмотра текущему пользователю, и вообще могут ли пользователи иметь блоги (листинг 6).

Листинг 6

$getMembers = false;

if($arResult['CURRENT_ACCESS']['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_;

}

unset($rsItems, $id_, $arOrderGM, $arGroupByGM,

$arNavigationGM, $arSelectFieldsGM);

// код исключения "закрытых" пользователей вынесен в конец

// модуля (он общий для двух типов лент)

}

// Добавим ID группы в $arEntityGroupsID, если включен вывод

// сообщений из блога группы

if($arParams['INC_SELF_MESSAGES'] &&

$arResult['CURRENT_ACCESS']['canViewGroup'] &&

$arResult['CURRENT_ACCESS']['canViewGroupSelfMessages']) {

//если блоги в группе не отключены

if(CSocNetFeatures::IsActiveFeature(SONET_ENTITY_GROUP,

$arResult['ENTITY_ID'], 'blog')) {

$arEntityGroupsID[$arResult['ENTITY_ID']] = array(

'ID' => $arResult['ENTITY_ID'],

'NAME' => $arResult['GROUP_INFO']['NAME']

);

}

}

Чуть выше мы отметили, что код исключения «закрытых» пользователей вынесен в конец компонента. Теперь пришло время определить пользователей, которые запретили просмотр блогов. Уберем их из списка (раз уж они сами этого хотят; листинг 7).

Листинг 7

if(!empty($arEntityUsersID)) {

$arExceptUserEntity = CPTK_SocialNetwork::

GetByRoleFeaturesIdArray(SONET_ENTITY_USER, 'blog',

'view_post', array('!ROLE' => SONET_RELATIONS_TYPE_ALL),

array('!ROLE' => SONET_RELATIONS_TYPE_ALL));

$arTmp = array_intersect_key($arExceptUserEntity,

$arEntityUsersID);

unset($arExceptUserEntity);

if(!empty($arTmp)) {

foreach($arTmp as $key)

{

unset($arEntityUsersID[$key]);

}

}

unset($arTmp);

// Если активный пользователь – владелец ленты, повторно

// включим его ID, даже если он закрыл свой блог – ему

// заведомо можно просматривать свои записи

if($arParams['INC_SELF_MESSAGES'] && $arResult

['CURRENT_ACCESS']['canViewUserSelfMessages']) {

$arEntityUsersID[$arResult['ENTITY_ID']] =

$arResult['ENTITY_ID'];

}

// Определим пользователей, которые вообще отключили свои

// блоги, и исключим их из списка

$arExceptUserEntity = CPTK_SocialNetwork::

GetByRoleFeaturesIdArray(SONET_ENTITY_USER, 'blog',

'view_post', array('FEATURE_ACTIVE' => 'N'),

array('FEATURE_ACTIVE' => 'N'));

$arTmp = array_intersect_key($arExceptUserEntity,

$arEntityUsersID);

unset($arExceptUserEntity);

if(!empty($arTmp)) {

foreach($arTmp as $key) {

unset($arEntityUsersID[$key]);

}

}

unset($arTmp);

}

Здесь надо обратить внимание на две дополнительные функции, которые не входят в стандартный API ядра «1С-Битрикс: Управление сайтом»: CPTK_SocialNetwork::

GetByRoleFeaturesIdArray() и CPTK_SocialNetwork::IsAllowedFeature(). Они представляют собой часть библиотеки автора, их текст здесь не приводится (при желании библиотеку можно запросить у автора статьи). Первая, CPTK_SocialNetwork::GetByRoleFeaturesIdArray(), возвращает массив идентификаторов объектов по типу объекта, сигнатуре, функциональности и операциям (с возможностью установки дополнительного фильтра). Функция имеет внутреннее кэширование результатов, в ее основе лежит метод CSocNetFeaturesPerms::GetList(). Вторая, CPTK_SocialNetwork::IsAllowedFeature(), проверяет, доступна ли для заданного объекта затребованная возможность (это небольшая оптимизация часто выполняемой операции, опытному разработчику не составит труда реализовать ее самостоятельно).

На этом этапе возникает проблема: при организации группы социальной сети система не создает соответствующие записи в таблицах БД, где хранятся настройки прав доступа к заданным функциям. Эти записи автоматически создаются только после первого изменения прав доступа, до того они определяются системой, средствами PHP. Причем по умолчанию используется режим не «разрешено всем», а «разрешено только участникам». Следовательно, попытка выбрать все записи, у которых в поле ROLE не установлено значение константы SONET_RELATIONS_TYPE_ALL («разрешено всем»; в нашем случае это и будет вызов CPTK_SocialNetwork::GetByRoleFeaturesIdArray() с установленным дополнительным фильтром array('!ROLE' => SONET_RELATIONS_TYPE_ALL), приведет к получению неверного результата. Этот нюанс можно считать досадной ошибкой в архитектуре модуля, но, к счастью, дело поправимо без вмешательства в ядро системы. В нашем случае оказалось достаточно добавить обработчик события OnSocNetGroupAdd, где и выполняются необходимые для корректной записи в БД структуры прав операции. В группах, которые были созданы ранее, эта ошибка была исправлена с помощью «Мастера».

Двигаемся дальше – получаем массив блогов, из которых будут выбираться новые записи (листинг 8).

Листинг 8

$arBlogID = array(); // массив блогов

if(!empty($arEntityUsersID)) { // по владельцу блога

$arOrderBlog = array();

$arFilterBlog = array(

'OWNER_ID' => array_keys($arEntityUsersID),

'GROUP_ID' => $arParams['BLOG_GROUP_ID'],

'GROUP_SITE_ID' => SITE_ID,

'ACTIVE' => 'Y'

);

unset($arEntityUsersID);

$arGroupByBlog = false; $arNavigationBlog = false;

$arSelectFieldsBlog = array('ID', 'SONET_GROUP_ID');

$rsItems = CBlog::GetList($arOrderBlog, $arFilterBlog,

$arGroupByBlog, $arNavigationBlog, $arSelectFieldsBlog);

while($arItem = $rsItems->Fetch()) {

if(intval($arItem['SONET_GROUP_ID']) <= 0) {

$id_ = intval($arItem['ID']);

$arBlogID[$id_] = $id_;

}

}

unset($rsItems, $id_, $arOrderBlog, $arGroupByBlog,

$arNavigationBlog, $arSelectFieldsBlog);

}

if(!empty($arEntityGroupsID)) { // по группе блога в соцсети

$arOrderBlog = array();

$arFilterBlog = array(

'SOCNET_GROUP_ID' => array_keys($arEntityGroupsID),

'GROUP_ID' => $arParams['BLOG_GROUP_ID'],

'GROUP_SITE_ID' => SITE_ID,

'ACTIVE' => 'Y'

);

$arGroupByBlog = false; $arNavigationBlog = false;

$arSelectFieldsBlog = array('ID', 'OWNER_ID');

$rsItems = CBlog::GetList($arOrderBlog, $arFilterBlog,

$arGroupByBlog, $arNavigationBlog, $arSelectFieldsBlog);

while($arItem = $rsItems->Fetch()) {

if(intval($arItem['OWNER_ID']) <= 0) {

$id_ = intval($arItem['ID']);

$arBlogID[$id_] = $id_;

}

}

unset($rsItems, $id_, $arOrderBlog, $arGroupByBlog,

$arNavigationBlog, $arSelectFieldsBlog);

}

Здесь все вполне прозрачно, комментарии не требуются. И наконец, выбираем записи из блогов, которые и станут основой для формирования конечного результата – «Ленты друзей» (листинг 9).

Листинг 9

if(!empty($arBlogID)) {

$arFilter = array(

'BLOG_ACTIVE' => 'Y',

'BLOG_GROUP_SITE_ID' => SITE_ID,

'PUBLISH_STATUS' => BLOG_PUBLISH_STATUS_PUBLISH,

'BLOG_ID' => array_keys($arBlogID),

'ACTIVE' => 'Y'

);

unset($arBlogID);

if($arParams['MAX_DAYS_COUNT'] > 0) {

// задан промежуток времени для выборки сообщений 86400 —

// кэшируем на сутки

$from = intval(time() – $arParams['MAX_DAYS_COUNT']*86400);

$arFilter['>=DATE_PUBLISH'] = ConvertTimeStamp($from,

'FULL');

}

$arGroupBy = false;

$arSelectFields = array(

'ID',

'BLOG_ID',

'TITLE',

'DATE_PUBLISH',

'AUTHOR_ID',

'DETAIL_TEXT',

'BLOG_ACTIVE',

'BLOG_URL',

'BLOG_GROUP_ID',

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке

Скачать книгу

Если нет возможности читать онлайн, скачайте книгу файлом для электронной книжки и читайте офлайн.

fb2.zip txt txt.zip rtf.zip a4.pdf a6.pdf mobi.prc epub ios.epub fb3

Похожие книги