Jak programowo przypisać dostęp do bloku?

10

Blok utworzyłem programowo, ale nie wiem, jak mogę programowo przypisać dostęp do niego. Jak mogę to osiągnąć?

użytkownik5013
źródło
Czy możesz rozwinąć swoje pytanie i wyświetlić kod?
Triskelion 12.04.13
W samym kodzie blokowym możesz wyszukać użytkownika (globalny użytkownik $) i sprawdzić jego rolę za pomocą metody w łączu. bywombats.com/blog/ryan/10-25-2007/…
user6614
Moduł Panele ma kilka świetnych kontroli dostępu przy użyciu regionów, a nie bloków.
Louis,

Odpowiedzi:

10

Ustawienie tablicy „role” w tablicy zwróconej z hook_block_info()nie działa, ponieważ:

  • Role, które mogą widzieć blok i które są ustawione w interfejsie użytkownika, są zapisywane z block_admin_configure_submit () w tabeli „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();
  • Kod decydujący o tym, które bloki mają być wyświetlane aktualnie zalogowanemu użytkownikowi, znajduje się w block_block_list_alter () , która jest implementacją hook_block_list_alter () i wykorzystuje tylko zawartość tej tabeli

    $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;
      }
    
      // …
    
    }
  • Nie ma innej funkcji Drupal, która sprawdza właściwość roli w danych zwróconych z hook_block_info(), ani zawartość tabeli „block_role” nie jest scalana z tym, co zwróciło z hook_block_info()implementacji.

Możesz sprawdzić, czy użytkownik ma wymaganą rolę do zobaczenia bloku hook_block_view(), ale w tym momencie Drupal już renderuje blok; oznacza to, że użytkownik nadal widziałby tytuł bloku, jeśli został już ustawiony.

Co możesz zrobić, to wdrożyć, hook_block_list_alter()aby usunąć informacje o tym bloku, gdy użytkownik nie ma wymaganej roli.
Aby uniknąć nieporozumień dla użytkowników, którzy administrują blokami, zmieniłbym również formularz użyty do edycji bloku i wyłączył pole formularza używane do określenia, które role mogą widzieć ten blok, ponieważ moduł, który go wdraża, będzie używał własnej listy ról; minimalny kod powinien przynajmniej wyświetlać komunikat o tym, że ustawienia ról nie mają żadnego efektu, ale chciałbym również wyłączyć elementy formularza dla ustawień ról.

Ponieważ moduł Blok pokazuje już pola formularza, aby wybrać role, które widzą blok, możesz również ustawić domyślną wartość dla tego bloku i pozwolić administratorowi go zmienić, jeśli to konieczne.

zrzut ekranu

Jeśli chodzi o sprawdzanie ról użytkownika w porównaniu ze sprawdzaniem uprawnień użytkownika, preferowane jest ostatnie, szczególnie gdy alternatywą byłoby na stałe zakodowanie listy ról w module.
Jak pokazano w module Blok, użycie uprawnień nie jest jedyną alternatywą: Moduł może mieć ustawienie decydujące, które role mogą coś zobaczyć.
Oczywiście nie zawsze warto mieć ustawienie, w którym role mogą coś robić. Wyobrażam sobie również, co dla administratora oznaczałoby, gdyby 10 modułów miało własne ustawienia, dla których role mogą coś robić, zamiast używać uprawnień i pozwalać administratorom na używanie jednej strony do ich ustawiania.

kiamlaluno
źródło
Cóż, oczywiście będę musiał wybrać ten, który jest najbardziej odpowiednią odpowiedzią. Dziękuję za szczegółowe wyjaśnienie, ponieważ naprawdę pomaga zrozumieć, w jaki sposób bloki Drupal działają za kulisami.
user5013
1

W swojej hook_block_info możesz spróbować czegoś takiego:

$blocks['myblock'] = array(
   ...
   'roles' => array(
      'administrator' => '3',
      'authenticated user' => '2',
   )
Triskelion
źródło
Wydaje się, że jest to najlepszy sposób na wdrożenie tego przy użyciu podejścia programowego, gdy definiujesz, które role mają dostęp, a następnie pozwalasz Drupalowi ustalić, czy użytkownik może uzyskać do niego dostęp, czy nie. Czy przegapiłem jakąś wadę tego podejścia?
user5013 12.04.13
Jeśli musisz to zrobić programowo, tak. Bez wad. Zakładam jednak, że musiałby istnieć bardzo dobry przypadek użycia, aby po prostu przejść do / admin / structure / block i przypisać role do bloku.
Triskelion
Przypadek użycia zostanie automatycznie skonfigurowany dla użytkownika, aby nie musiał. Ściśle kwestia wygody. Po ustawieniu mogą następnie zmienić go na taki, jaki chcą, jeśli nie odpowiada to ich konkretnym potrzebom.
user5013 12.04.13
1
To nie działa; zobacz moją odpowiedź, dlaczego tak nie jest.
kiamlaluno
0

Zakładając, że sam tworzysz bloki za pomocą hook_block_info (), możesz po prostu wykonać user_access () w funkcji hook_block_view (). Sprawdź dokumenty API, ponieważ mają na to przykład.

jdwfly
źródło
Tak, powinienem pomyśleć o użyciu user_access. Całkowicie wymknęło mi się z głowy - D'oh. Zastanawiam się nad użyciem dostępu do roli, ale być może lepszym rozwiązaniem może być dostęp do uprawnień.
user5013 12.04.13
0

Jest to niemożliwe w hook_block_info (), ale możesz użyć tego zapytania, aby to osiągnąć. Zmień odpowiednio MODULE_NAME, BLOCK_DELTA i RID

$query = db_insert('block_role')
  ->fields(array(
    'module' => 'MODULE_NAME', 
    'delta' => 'BLOCK_DELTA', 
    'rid' => 2, // Authenticated User
  ))
  ->execute();
Paul Bönisch
źródło
0

W hook_block_view możesz użyć, global $useraby uzyskać informacje o użytkowniku, a następnie na podstawie roli użytkownika możesz przypisać inny, block['subject']a block['content']nawet nie przypisywać żadnego przedmiotu i treści do zablokowania, jeśli będzie niewidoczna dla tej roli. Oto przykład :

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

za pomocą tego kodu uwierzytelnieni użytkownicy (nie goście) będą mieli blok dla widocznych użytkowników.

Alireza Tabatabaeian
źródło