¿Cómo asigno programáticamente el acceso a un bloque?

10

He creado un bloque mediante programación, pero no sé cómo puedo asignarle el acceso mediante programación. ¿Cómo puedo lograrlo?

usuario5013
fuente
¿Podría ampliar su pregunta y mostrar su código?
Triskelion
En el código de bloque en sí, puede buscar el usuario ($ global user) y verificar su función utilizando el método en el enlace. bywombats.com/blog/ryan/10-25-2007/…
user6614
El módulo Paneles tiene algunos controles de acceso excelentes que utilizan regiones, no bloques.
Louis

Respuestas:

10

Establecer la matriz "roles" en la matriz devuelta desde hook_block_info()no funciona porque:

  • Los roles que pueden ver un bloque, y que se establecen en la interfaz de usuario, se guardan desde block_admin_configure_submit () en la tabla "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();
  • El código que decide qué bloques deben mostrarse al usuario actualmente conectado está contenido en block_block_list_alter () , que es una implementación de hook_block_list_alter () , y usa solo el contenido de esa tabla

    $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;
      }
    
      // …
    
    }
  • No hay otra función de Drupal que verifique la propiedad de roles en los datos devueltos hook_block_info(), ni el contenido de la tabla "block_role" se fusionó con lo que regresó de las hook_block_info()implementaciones.

Puede verificar que el usuario tenga el rol requerido para ver el bloque hook_block_view(), pero en ese momento Drupal ya está representando el bloque; eso significa que el usuario aún vería el título del bloque, si ya se ha configurado uno.

Lo que puede hacer es implementar hook_block_list_alter()para eliminar la información sobre ese bloque cuando el usuario no tiene el rol requerido.
Para evitar confusiones a los usuarios que administran los bloques, también alteraría el formulario utilizado para editar un bloque y deshabilitaría el campo de formulario utilizado para establecer qué roles pueden ver ese bloque, ya que el módulo que lo implementa usará su propia lista de roles; el código mínimo al menos debería mostrar un mensaje sobre la configuración de roles que no tiene ningún efecto, pero también deshabilitaría los elementos de formulario para la configuración de roles.

Dado que el módulo Bloque ya muestra campos de formulario para seleccionar qué roles ven un bloque, también puede simplemente establecer un valor predeterminado para su bloque y dejar que los usuarios administradores lo cambien si es necesario.

captura de pantalla

Según la verificación de los roles que tiene un usuario frente a la verificación de los permisos que tiene un usuario, se prefiere el último, especialmente cuando la alternativa sería codificar una lista de roles en un módulo.
Como se muestra en el módulo Bloque, el uso de permisos no es la única alternativa: un módulo podría tener una configuración para decidir qué roles pueden ver algo.
Claramente, no siempre vale la pena tener un entorno para el cual los roles pueden hacer algo. Me imagino también lo que significaría para los usuarios administradores si 10 módulos tuvieran sus propias configuraciones para qué roles se les permite hacer algo, en lugar de usar permisos, y permitir que los usuarios administradores usen una sola página para configurarlos.

kiamlaluno
fuente
Bueno, obviamente tendré que ir con esta como la respuesta más adecuada. Gracias por la explicación detallada, ya que realmente ayuda a comprender cómo funcionan los bloques Drupal detrás de escena.
user5013
1

En tu hook_block_info puedes probar algo como:

$blocks['myblock'] = array(
   ...
   'roles' => array(
      'administrator' => '3',
      'authenticated user' => '2',
   )
Triskelion
fuente
Esta parece ser la mejor manera de implementar esto utilizando un enfoque programático a medida que define qué roles tienen acceso y luego deja que Drupal determine si un usuario puede acceder a él o no. ¿Me perdí alguna desventaja de este enfoque?
user5013
Si debe hacerlo programáticamente, sí. Sin inconvenientes. Sin embargo, supondría que tendría que haber un muy buen caso de uso en lugar de simplemente ir a / admin / structure / block y asignar roles al bloque.
Triskelion
El caso de uso se configurará automáticamente para el usuario para que no tenga que hacerlo. Estrictamente un problema de conveniencia. Una vez configurados, podrían cambiarlo a lo que quieren que sea si no se ajusta a sus necesidades particulares.
user5013
1
Esto no funciona mira mi respuesta de por qué no.
kiamlaluno
0

Suponiendo que está haciendo los bloques usted mismo con hook_block_info (), entonces podría hacer user_access () en su función hook_block_view (). Echa un vistazo a los documentos de la API, ya que tienen un ejemplo de esto.

jdwfly
fuente
Sí, debería haber pensado en usar user_access. Se me pasó por la cabeza totalmente - D'oh. Estoy pensando en usar el acceso a roles, pero tal vez el acceso con permiso podría ser una mejor manera de hacerlo.
user5013
0

Es imposible en hook_block_info (), pero puede usar esta consulta para lograr esto. Cambiar MODULE_NAME, BLOCK_DELTA y RID en consecuencia

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

En hook_block_view, se puede utilizar global $userpara obtener información sobre el usuario, a continuación, según la función del usuario puede asignar diferentes block['subject']y block['content']ni siquiera no asigna ningún tema y el contenido de bloque de si va a ser invisible para ese papel. Aquí hay un ejemplo :

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

Al usar este código, los usuarios autenticados (no los invitados) tendrán bloqueado visible para los usuarios autenticados.

Alireza Tabatabaeian
fuente