партнер компании 1с-битрикс
сайт фрилансера Сергея Эстрина
Войти как пользователь
Вы можете войти на сайт, если вы зарегистрированы на одном из этих сервисов:
Универсальная галерея - модуль для битрикс
Штатно распределения прав доступа по отдельным форумам в модуле grain.forum (Простой адаптивный форум) нет. На мой взгляд, это избыточный функционал для большинства сайтов, и это было бы излишним усложнением интерфейса. Если же вам нужно просто скрыть форумы, для этого существует галочка активности. Однако, если вам необходимо управлять правами доступа (видимостью) отдельных форумов, это можно сделать без вмешательства в программный код модуля или компонентов, используя события.
[spoiler]
Суть решения:

У каждого форума (и раздела) при создании заполняется поле привязки к сайту (SITE_ID). По умолчанию, туда записывается ID текущего сайта из константы SITE_ID, но само поле у форума называется так условно, туда можно записывать не только идентификатор сайта, но и любую другую строку, по которой можно осуществлять привязку форумов. Для этого можно использовать константу GRAIN_FORUM_SITE_ID, которая будет содержать нужный идентификатор, либо событие OnGlobalsGetForumFilter (добавлено в версии 2.5 модуля), в котором можно изменить исходный фильтр для форумов, который используется во всех компонентах. Т.к. в нашем примере будет использоваться массив для фильтрации по нескольким значениям поля SITE_ID, а константа содержать массив не может, то мы выбираем событие. После добавления форума, по событию \Grain\Forum\Forum::onAfterAdd мы создаем отдельную для форума группу пользователей, при включении в которую, они смогут видеть форум и сообщения в нем.

Функционал будет работать в отдельном разделе и будет включаться с помощью установки свойства страницы FORUM_ACCESS_EDITOR_GROUP_ID, значение которого должно будет содержать идентификатор группы пользователей - редакторов данного раздела. Редакторы, входящие в данную группу (а также администраторы), смогут видеть все форумы данного раздела (форумы, созданные не в данном разделе, в нем отображаться не будут).

На странице, где размещен комплексный компонент форума, установим свойство FORUM_ACCESS_EDITOR_GROUP_ID (саму группу редакторов сначала необходимо создать).

$APPLICATION->SetPageProperty("FORUM_ACCESS_EDITOR_GROUP_ID",ID_группы_пользователей);


Подключим следующий код в файле /local/php_interface/init.php или /bitrix/php_interface/init.php, например, с помощью include (сам код необходимо разместить в отдельном файле).

<?php

    
namespace Grain\ForumAccess;

\Bitrix\Main\EventManager::getInstance()->addEventHandler
    
'grain.forum'
    
'\Grain\Forum\Forum::onAfterAdd'
    
'\Grain\ForumAccess\AfterForumAdd'
); 
 
function 
AfterForumAdd(\Bitrix\Main\Entity\Event $event)
{    
    
$EDITOR_GROUP_ID intval($GLOBALS["APPLICATION"]->GetPageProperty("FORUM_ACCESS_EDITOR_GROUP_ID"));
    
// если группа редакторов не указана, ничего не делаем, сохраняем обычное поведение
    
if(!$EDITOR_GROUP_ID)
        return;
        
    
$id $event->getParameter("id");
    if(
is_array($id))
        
$id=$id['ID'];
    
$fields $event->getParameter("fields");

    
// меняем поле SITE_ID у форума на наш идентификатор и сохраняем его в символьный код группы
    
$site_id 'fm'.$id

    
$result \Grain\Forum\ForumTable::update($id,array('SITE_ID'=>$site_id));
    if (
$result->isSuccess()) 
    {
        
$arGroupFields = array(
            
'NAME' => "Доступ к форуму: ".$fields["NAME"],
            
'STRING_ID' => $site_id,
            
'C_SORT' => '1000',
        );
        
\Bitrix\Main\GroupTable::add($arGroupFields);
    }    
}

\Bitrix\Main\EventManager::getInstance()->addEventHandler
    
'grain.forum'
    
'OnGlobalsGetForumFilter'
    
'\Grain\ForumAccess\OnGlobalsGetForumFilter'
); 

function 
OnGlobalsGetForumFilter(\Bitrix\Main\Event $event
{
    
$EDITOR_GROUP_ID intval($GLOBALS["APPLICATION"]->GetPageProperty("FORUM_ACCESS_EDITOR_GROUP_ID"));
    
// если группа редакторов не указана, ничего не делаем, сохраняем обычное поведение
    
if(!$EDITOR_GROUP_ID)
        return;

    
$arFilter $event->getParameter(0);
        
    if(
$GLOBALS["USER"]->IsAuthorized())
    {        
        
// выбираем все группы, в которые входит пользователь
        
$rsUserGroup \Bitrix\Main\UserGroupTable::getList(array(
            
'filter' => array('USER_ID'=>$GLOBALS["USER"]->GetID(),'GROUP.ACTIVE'=>'Y'),
            
'select' => array('GROUP_ID','GROUP_CODE'=>'GROUP.STRING_ID'),
            
'order' => array('GROUP.C_SORT'=>'ASC'),
        ));
        
$isEditor $GLOBALS["USER"]->IsAdmin(); // администратор всегда является редактором
        
$arSiteID = array();
        while(
$arUserGroup=$rsUserGroup->fetch())
        {
            if(
$arUserGroup["GROUP_ID"]==$EDITOR_GROUP_ID)
                
$isEditor true;
            
// если симв. код группы начинается с fm, добавляем в массив
            
elseif(substr($arUserGroup["GROUP_CODE"],0,2)=='fm')
                
$arSiteID[] = $arUserGroup["GROUP_CODE"];
        }
        
// модифицируем исходный фильтр для форумов
        
if($isEditor)
            
$arFilter["SITE_ID"] = "fm%"// редакторы видят все форумы в данном разделе
        
elseif($arSiteID)
            
$arFilter["SITE_ID"] = $arSiteID// обычные пользователи - только если принадлежат к группам
        
else
            
$arFilter["SITE_ID"] = false// остальные в данном разделе не видят ничего
    

    else
    {
        
//$GLOBALS["APPLICATION"]->RestartWorkarea();
        //$GLOBALS["APPLICATION"]->AuthForm(); // можно добавить форму авторизации    
        
$arFilter["SITE_ID"] = false// неавторизованные в данном разделе не видят ничего
    
}
    
    
$result = new \Bitrix\Main\EventResult($event->getEventType(), $arFilter);
    return 
$result;
}


\Bitrix\Main\EventManager::getInstance()->addEventHandler
    
'grain.forum'
    
'\Grain\Forum\Forum::onAfterDelete'
    
'\Grain\ForumAccess\AfterForumDelete'
); 
 
function 
AfterForumDelete(\Bitrix\Main\Entity\Event $event)
{    
    
$EDITOR_GROUP_ID intval($GLOBALS["APPLICATION"]->GetPageProperty("FORUM_ACCESS_EDITOR_GROUP_ID"));
    
// если группа редакторов не указана, ничего не делаем, сохраняем обычное поведение
    
if(!$EDITOR_GROUP_ID)
        return;
        
    
$id $event->getParameter("id");
    if(
is_array($id))
        
$id=$id['ID'];

    
// при удалении форума, удаляем также связанную группу пользователей
    
$result \Bitrix\Main\GroupTable::getList(array(
        
'select'  => array('ID'),
        
'filter'  => array('=STRING_ID'=>'fm'.$id),
        
'limit' => 1
    
));
    if(
$row $result->fetch())
        
\Bitrix\Main\GroupTable::delete(intval($row['ID']));    
}

См. также сниппеты "События ORM/хайлоадблоков" на сайте estrin.pw

Чтобы оставить сообщение, авторизуйтесь, или войдите с помощью: