Blok utworzyłem programowo, ale nie wiem, jak mogę programowo przypisać dostęp do niego. Jak mogę to osiągnąć?
Blok utworzyłem programowo, ale nie wiem, jak mogę programowo przypisać dostęp do niego. Jak mogę to osiągnąć?
Odpowiedzi:
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.
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.
W swojej hook_block_info możesz spróbować czegoś takiego:
$blocks['myblock'] = array(
...
'roles' => array(
'administrator' => '3',
'authenticated user' => '2',
)
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.
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();
W hook_block_view możesz użyć, global $user
aby 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.