Wie ordne ich den Zugriff programmgesteuert einem Block zu?

10

Ich habe einen Block programmgesteuert erstellt, weiß aber nicht, wie ich den Zugriff programmgesteuert zuweisen kann. Wie kann ich das erreichen?

user5013
quelle
Könnten Sie Ihre Frage erweitern und Ihren Code anzeigen?
Triskelion
Im Blockcode selbst können Sie den Benutzer (global $ user) suchen und seine Rolle mithilfe der Methode im Link überprüfen. bywombats.com/blog/ryan/10-25-2007/…
user6614
Das Panels-Modul verfügt über einige hervorragende Zugriffskontrollen, bei denen Regionen und keine Blöcke verwendet werden.
Louis

Antworten:

10

Das Festlegen des Arrays "Rollen" in dem von zurückgegebenen Array hook_block_info()funktioniert nicht, weil:

  • Die Rollen, die einen Block sehen dürfen und die in der Benutzeroberfläche festgelegt sind, werden aus block_admin_configure_submit () in der Tabelle "block_role" gespeichert

    $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();
  • Der Code, der entscheidet, welche Blöcke dem aktuell angemeldeten Benutzer angezeigt werden sollen, ist in block_block_list_alter () enthalten , einer Implementierung von hook_block_list_alter () , und verwendet nur den Inhalt dieser Tabelle

    $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;
      }
    
      // …
    
    }
  • Es gibt keine andere Drupal - Funktion , dass die Kontrollen die Rollen Eigenschaft in den zurückgegebenen Daten aus hook_block_info(), noch ist der Inhalt der „block_role“ Tabelle zusammengefasst mit dem, was von den zurück hook_block_info()Implementierungen.

Sie können überprüfen, ob der Benutzer die erforderliche Rolle hat, um den Block zu sehen hook_block_view(), aber zu diesem Zeitpunkt rendert Drupal den Block bereits. Das bedeutet, dass der Benutzer den Blocktitel weiterhin sehen würde, wenn bereits einer festgelegt wurde.

Sie können implementieren hook_block_list_alter(), um die Informationen zu diesem Block zu entfernen, wenn der Benutzer nicht über die erforderliche Rolle verfügt.
Um Verwirrung bei den Benutzern zu vermeiden, die die Blöcke verwalten, würde ich auch das zum Bearbeiten eines Blocks verwendete Formular ändern und das Formularfeld deaktivieren, mit dem festgelegt wird, welche Rollen diesen Block sehen können, da das Modul, das ihn implementiert, eine eigene Liste verwenden wird von Rollen; Der minimale Code sollte mindestens eine Meldung enthalten, dass die Rolleneinstellungen keine Auswirkungen haben, aber ich würde auch die Formularelemente für die Rolleneinstellungen deaktivieren.

Da im Blockmodul bereits Formularfelder angezeigt werden, um auszuwählen, welche Rollen einen Block anzeigen, können Sie auch einfach einen Standard für Ihren Block festlegen und ihn bei Bedarf von den Administratorbenutzern ändern lassen.

Bildschirmfoto

Bei der Überprüfung der Rollen eines Benutzers gegenüber der Überprüfung der Berechtigungen eines Benutzers wird die letzte bevorzugt, insbesondere wenn die Alternative darin besteht, eine Liste der Rollen in einem Modul fest zu codieren.
Wie aus dem Block-Modul hervorgeht, ist die Verwendung von Berechtigungen nicht die einzige Alternative: Ein Modul kann über Einstellungen verfügen, mit denen entschieden werden kann, welche Rollen etwas sehen dürfen.
Es lohnt sich natürlich nicht immer, eine Einstellung zu haben, für die Rollen etwas tun dürfen. Ich stelle mir auch vor, was für die Administratorbenutzer bedeuten würde, wenn 10 Module ihre eigenen Einstellungen hätten, für die Rollen etwas tun dürfen, anstatt Berechtigungen zu verwenden, und den Administratorbenutzern erlauben würden, sie auf einer einzigen Seite festzulegen.

kiamlaluno
quelle
Nun, ich werde natürlich mit dieser als die am besten geeignete Antwort gehen müssen. Vielen Dank für die ausführliche Erklärung, da es wirklich hilfreich ist zu verstehen, wie Drupal-Blöcke hinter den Kulissen funktionieren.
user5013
1

In Ihrer hook_block_info können Sie Folgendes ausprobieren:

$blocks['myblock'] = array(
   ...
   'roles' => array(
      'administrator' => '3',
      'authenticated user' => '2',
   )
Triskelion
quelle
Dies scheint der beste Weg zu sein, dies mithilfe eines programmatischen Ansatzes zu implementieren, indem Sie definieren, welche Rollen Zugriff haben, und Drupal dann bestimmen lassen, ob ein Benutzer darauf zugreifen kann oder nicht. Habe ich einen Nachteil bei diesem Ansatz verpasst?
user5013
Wenn Sie es programmatisch tun müssen, ja. Kein Nachteil. Ich würde jedoch annehmen, dass es einen sehr guten Anwendungsfall geben müsste, wenn man nicht einfach zu / admin / structure / block geht und dem Block Rollen zuweist.
Triskelion
Der Anwendungsfall wäre automatisch die Einrichtung für den Benutzer, damit er dies nicht tun muss. Streng genommen ein Problem der Bequemlichkeit. Einmal eingestellt, können sie es dann so ändern, wie sie es möchten, wenn es nicht ihren speziellen Bedürfnissen entspricht.
user5013
1
Das funktioniert nicht; siehe meine Antwort, warum es nicht so ist.
Kiamlaluno
0

Angenommen, Sie erstellen die Blöcke selbst mit hook_block_info (), dann können Sie einfach user_access () in Ihrer Funktion hook_block_view () ausführen. Schauen Sie sich die API-Dokumente an, da sie ein Beispiel dafür haben.

jdwfly
quelle
Ja, ich hätte darüber nachdenken sollen, user_access zu verwenden. Ich bin total durchgedreht - D'oh. Ich denke über die Verwendung des Rollenzugriffs nach, aber vielleicht ist der Berechtigungszugriff ein besserer Weg.
user5013
0

In hook_block_info () ist dies nicht möglich, aber Sie können diese Abfrage verwenden, um dies zu erreichen. Ändern Sie MODULE_NAME, BLOCK_DELTA und RID entsprechend

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

In hook_block_view können Sie global $userInformationen über den Benutzer abrufen. Abhängig von der Rolle des Benutzers können Sie verschiedene Themen zuweisen block['subject']und / block['content']oder sogar keine zu blockierenden Themen und Inhalte zuweisen, wenn diese für diese Rolle unsichtbar sind. Hier ist ein Beispiel :

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

Bei Verwendung dieses Codes werden authentifizierte Benutzer (keine Gäste) für authentifizierte Benutzer blockiert.

Alireza Tabatabaeian
quelle