Як я можу програмно призначити доступ до блоку?


10

Я створив блок програмно, але не знаю, як я можу програмно призначити доступ до нього. Як я можу цього досягти?


Чи можете ви розширити своє запитання та показати свій код?
Triskelion

У самому блоковому коді ви можете шукати користувача (глобальний $ user) і перевіряти його роль, використовуючи метод у посиланні. bywombats.com/blog/ryan/10-25-2007/…
користувач6614

Модуль Панелі має кілька чудових контролів доступу, використовуючи регіони, а не блоки.
Луї

Відповіді:


10

Налаштування масиву "ролей" у масиві, поверненому з 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 модулів матимуть власні налаштування, для яких ролям дозволено щось робити замість використання дозволів та дозволяти користувачам адміністратора використовувати одну сторінку для їх встановлення.


Що ж, я, очевидно, змушений би відповісти на це як на найбільш відповідну відповідь. Дякую за детальне пояснення, оскільки це насправді допомагає зрозуміти, як блоки Drupal працюють за кадром.
user5013

1

Ви можете спробувати щось на кшталт:

$blocks['myblock'] = array(
   ...
   'roles' => array(
      'administrator' => '3',
      'authenticated user' => '2',
   )

Це виглядає як найкращий спосіб здійснити це за допомогою програмного підходу, коли ви визначаєте, до яких ролей є доступ, а потім дозволяєте Drupal визначати, чи може користувач отримати доступ до нього чи ні. Чи пропустив я якийсь недолік у цьому підході?
user5013

Якщо це потрібно робити програмно, так. Немає недоліків. Однак я б припустив, що повинен був бути дуже хороший випадок використання проти простого переходу до / адміністратора / структури / блоку та присвоєння йому ролей.
Triskelion

Випадок використання автоматично виконає налаштування для користувача, щоб вони не мали цього робити. Суворо питання зручності. Після встановлення вони можуть змінити його на те, що вони хочуть, якщо це не відповідає їхнім конкретним потребам.
user5013

1
Це не працює; дивіться мою відповідь, чому це не так.
kiamlaluno

0

Якщо припустити, що ви створюєте блоки самостійно за допомогою ho_block_info (), то ви можете просто зробити user_access () у вашій функції_ук_блок_перегляд (). Ознайомтеся з документами api, оскільки у них є приклад цього.


Так, я мав би подумати про використання user_access. Тотально прослизнув мій погляд - D'oh. Я думаю про використання рольового доступу, але, можливо, дозвіл на доступ може бути кращим способом.
user5013

0

Це неможливо в кук_блок_інфо (), але ви можете використовувати цей запит, щоб досягти цього. Змініть MODULE_NAME, BLOCK_DELTA та RID відповідно

$query = db_insert('block_role')
  ->fields(array(
    'module' => 'MODULE_NAME', 
    'delta' => 'BLOCK_DELTA', 
    'rid' => 2, // Authenticated User
  ))
  ->execute();

0

У гачку_блок_вью ви можете використовувати 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;
}

користуючись цим кодом аутентифіковані користувачі (не гості), блок стане видимим для аутентифікованих користувачів

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.