Я створив блок програмно, але не знаю, як я можу програмно призначити доступ до нього. Як я можу цього досягти?
Я створив блок програмно, але не знаю, як я можу програмно призначити доступ до нього. Як я можу цього досягти?
Відповіді:
Налаштування масиву "ролей" у масиві, поверненому з 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 () , який є реалізацією moll_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 модулів матимуть власні налаштування, для яких ролям дозволено щось робити замість використання дозволів та дозволяти користувачам адміністратора використовувати одну сторінку для їх встановлення.
Ви можете спробувати щось на кшталт:
$blocks['myblock'] = array(
...
'roles' => array(
'administrator' => '3',
'authenticated user' => '2',
)
Якщо припустити, що ви створюєте блоки самостійно за допомогою ho_block_info (), то ви можете просто зробити user_access () у вашій функції_ук_блок_перегляд (). Ознайомтеся з документами api, оскільки у них є приклад цього.
Це неможливо в кук_блок_інфо (), але ви можете використовувати цей запит, щоб досягти цього. Змініть MODULE_NAME, BLOCK_DELTA та RID відповідно
$query = db_insert('block_role')
->fields(array(
'module' => 'MODULE_NAME',
'delta' => 'BLOCK_DELTA',
'rid' => 2, // Authenticated User
))
->execute();
У гачку_блок_вью ви можете використовувати 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;
}
користуючись цим кодом аутентифіковані користувачі (не гості), блок стане видимим для аутентифікованих користувачів