Я создал блок программно, но я не знаю, как я могу программно назначить доступ к нему. Как мне этого добиться?
Я создал блок программно, но я не знаю, как я могу программно назначить доступ к нему. Как мне этого добиться?
Ответы:
Установка массива "role" в массиве, возвращаемом из hook_block_info()
, не работает, потому что:
Роли, которым разрешено видеть блок и которые установлены в пользовательском интерфейсе, сохраняются из block_admin_configure_submit () в таблице "block_role"
$query = db_insert('block_role')->fields(array('rid', 'module', 'delta'));
foreach (array_filter($form_state['values']['roles']) as $rid) {
$query->values(array(
'rid' => $rid,
'module' => $form_state['values']['module'],
'delta' => $form_state['values']['delta'],
));
}
$query->execute();
Код, который решает, какие блоки следует показать текущему вошедшему в систему пользователю, содержится в block_block_list_alter () , который является реализацией hook_block_list_alter () , и использует только содержимое этой таблицы.
$result = db_query('SELECT module, delta, rid FROM {block_role}');
foreach ($result as $record) {
$block_roles[$record->module][$record->delta][] = $record->rid;
}
foreach ($blocks as $key => $block) {
if (!isset($block->theme) || !isset($block->status) || $block->theme != $theme_key || $block->status != 1) {
// This block was added by a contrib module, leave it in the list.
continue;
}
// If a block has no roles associated, it is displayed for every role.
// For blocks with roles associated, if none of the user's roles matches
// the settings from this block, remove it from the block list.
if (isset($block_roles[$block->module][$block->delta]) && !array_intersect($block_roles[$block->module][$block->delta], array_keys($user->roles))) {
// No match.
unset($blocks[$key]);
continue;
}
// …
}
Существует не другой Drupal функция , которая проверяет роли собственности в данных , возвращаемых hook_block_info()
, ни содержание «block_role» таблицы объединены с тем, что возвращаемые из hook_block_info()
реализаций.
Вы можете убедиться, что у пользователя есть требуемая роль, чтобы видеть блок hook_block_view()
, но в этот момент Drupal уже рендерит блок; это означает, что пользователь все равно будет видеть заголовок блока, если он уже был установлен.
Что вы можете сделать, так это реализовать hook_block_list_alter()
удаление информации об этом блоке, когда у пользователя нет требуемой роли.
Чтобы избежать путаницы с пользователями, которые управляют блоками, я также изменил бы форму, используемую для редактирования блока, и отключил бы поле формы, используемое для определения того, какие роли могут видеть этот блок, поскольку модуль, реализующий его, будет использовать свой собственный список. ролей; минимальный код должен по крайней мере показывать сообщение о том, что параметры роли не имеют никакого эффекта, но я бы также отключил элементы формы для параметров роли.
Поскольку модуль «Блок» уже отображает поля формы для выбора ролей, которые видят блок, вы также можете просто установить значение по умолчанию для своего блока и позволить администраторам изменять его при необходимости.
В соответствии с проверкой ролей пользователя по сравнению с проверкой полномочий пользователя, последняя является предпочтительной, особенно когда альтернативой будет жесткое кодирование списка ролей в модуле.
Как показано в модуле «Блок», использование разрешения - не единственная альтернатива: модуль может иметь настройку для решения, каким ролям разрешено что-либо видеть.
Понятно, что не всегда стоит иметь настройки, для которых ролям разрешено что-то делать. Я также представляю, что для пользователей с администратором означало бы, если бы у 10 модулей были свои собственные настройки, для которых ролям разрешено что-то делать, вместо того, чтобы использовать разрешения и разрешать пользователям-администраторам использовать одну страницу для их установки.
В вашем hook_block_info вы можете попробовать что-то вроде:
$blocks['myblock'] = array(
...
'roles' => array(
'administrator' => '3',
'authenticated user' => '2',
)
Предполагая, что вы делаете блоки самостоятельно с помощью hook_block_info (), вы можете просто выполнить user_access () в своей функции hook_block_view (). Проверьте API документы, так как у них есть пример этого.
Это невозможно в hook_block_info (), но вы можете использовать этот запрос для достижения этой цели. Измените MODULE_NAME, BLOCK_DELTA и RID соответственно
$query = db_insert('block_role')
->fields(array(
'module' => 'MODULE_NAME',
'delta' => 'BLOCK_DELTA',
'rid' => 2, // Authenticated User
))
->execute();
В hook_block_view вы можете использовать, global $user
чтобы получить информацию о пользователе, затем, в зависимости от роли пользователя, вы можете назначить другой block['subject']
и block['content']
даже не назначать какой-либо предмет и контент для блокировки, если он будет невидимым для этой роли. вот пример:
function ModuleNAME_block_view($delta = '') {
switch ($delta) {
case 'Your_BLOCK' :
Global $user;
if($user->uid != '0') {
$block['subject'] = 'SUBJECT';
$block['content'] = 'SOME CONTENT OR A FUNCTION FOR BLOCK';
}
break;
}
return $block;
}
при использовании этого кода аутентифицированные пользователи (не гости) получат блокировку для аутентифицированных пользователей.