Como atribuir programaticamente o acesso a um bloco?


10

Criei um bloco programaticamente, mas não sei como atribuir programaticamente o acesso a ele. Como posso conseguir isso?


Você poderia expandir sua pergunta e mostrar seu código?
Triskelion

No próprio código de bloco, você pode procurar o usuário (global $ user) e verificar sua função usando o método no link. bywombats.com/blog/ryan/10-25-2007/...
user6614

O módulo Panels possui ótimos controles de acesso usando regiões, não blocos.
Louis

Respostas:


10

A configuração da matriz "functions" na matriz retornada hook_block_info()não funciona porque:

  • As funções que têm permissão para ver um bloco e são definidas na interface com o usuário são salvas em block_admin_configure_submit () na tabela "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();
  • O código que decide quais blocos devem ser mostrados para o usuário conectado no momento está contido em block_block_list_alter () , que é uma implementação de hook_block_list_alter () e usa apenas o conteúdo dessa tabela

    $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;
      }
    
      // …
    
    }
  • Não há outra função Drupal que verifique a propriedade de funções nos dados retornados hook_block_info(), nem o conteúdo da tabela "block_role" é mesclado com o que retornou das hook_block_info()implementações.

Você pode verificar se o usuário tem a função necessária para ver o bloco hook_block_view(), mas nesse momento o Drupal já está renderizando o bloco; isso significa que o usuário ainda verá o título do bloco, se já tiver sido definido.

O que você pode fazer é implementar hook_block_list_alter()para remover as informações sobre esse bloco quando o usuário não tiver a função necessária.
Para evitar confusão com os usuários que administram os blocos, eu também alteraria o formulário usado para editar um bloco e desabilitaria o campo do formulário usado para definir quais funções podem ver esse bloco, pois o módulo que o implementa utilizará sua própria lista. de papéis; o código mínimo deve mostrar pelo menos uma mensagem sobre as configurações de função que não têm efeito, mas eu também desabilitaria os elementos do formulário para as configurações de função.

Como o módulo Bloco já mostra campos de formulário para selecionar quais funções vêem um bloco, você também pode simplesmente definir um padrão para o seu bloco e permitir que os usuários administradores o alterem, se necessário.

captura de tela

De acordo com a verificação das funções que um usuário possui versus as permissões que ele possui, o último é preferido, especialmente quando a alternativa seria codificar uma lista de funções em um módulo.
Conforme mostrado no módulo Bloquear, o uso de permissão não é a única alternativa: um módulo pode ter uma configuração para decidir quais funções têm permissão para ver alguma coisa.
Claramente, nem sempre vale a pena ter uma configuração para a qual as funções podem fazer alguma coisa. Imagino também o que significaria para os usuários administradores se 10 módulos tivessem suas próprias configurações para as quais as funções podem fazer algo, em vez de usar permissões, e permitir que os usuários administradores usassem uma única página para defini-las.


Bem, obviamente terei que concordar com esta como a resposta mais apropriada. Obrigado pela explicação detalhada, pois realmente ajuda a entender como os blocos Drupal funcionam nos bastidores.
user5013

1

No seu hook_block_info, você pode tentar algo como:

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

Essa parece ser a melhor maneira de implementar isso usando uma abordagem programática ao definir quais funções têm acesso e permitir que o Drupal determine se um usuário pode acessá-lo ou não. Perdi alguma desvantagem dessa abordagem?
user5013

Se você deve fazer isso programaticamente, sim. Nenhuma desvantagem. No entanto, eu presumiria que haveria um caso de uso muito bom contra simplesmente acessar / admin / structure / block e atribuir funções ao bloco.
Triskelion

O caso de uso seria configurar automaticamente o usuário para que ele não precisasse. Estritamente uma questão de conveniência. Depois de configurados, eles poderiam alterá-lo para o que desejam, se não atender às suas necessidades particulares.
user5013

1
Isso não funciona; veja minha resposta para saber por que não.
kiamlaluno

0

Supondo que você mesmo esteja criando os blocos com hook_block_info (), você pode simplesmente fazer user_access () na sua função hook_block_view (). Confira os documentos da API, pois eles têm um exemplo disso.


Sim, eu deveria ter pensado em usar o user_access. Deslizei totalmente minha mente - D'oh. Estou pensando em usar o acesso à função, mas talvez o acesso à permissão possa ser o melhor caminho a percorrer.
user5013

0

É impossível em hook_block_info (), mas você pode usar esta consulta para obter isso. Altere MODULE_NAME, BLOCK_DELTA e RID de acordo

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

0

No hook_block_view, você pode usar global $userpara obter informações sobre o usuário e, com base na função do usuário, pode atribuir diferentes block['subject']e block['content']até mesmo não atribuir nenhum assunto e conteúdo para bloquear, se for invisível para essa função. aqui está um exemplo :

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

usando esse código, usuários autenticados (não convidados) terão o bloco visível para os usuários autenticados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.