Como um módulo pode detectar quando a página "acesso negado" é emitida?

16

Como é possível um módulo detectar quando o Drupal está exibindo a página "acesso negado"?
Eu sei como fazer isso com o Drupal 6; Eu preciso saber como fazer isso com o Drupal 7.

kiamlaluno
fonte

Respostas:

13

Você pode definir quais páginas serão exibidas quando ocorrerem erros 403 e 404 (administrador / configurações / relatório de erros).

Eu acho que você pode adicionar uma nova página na sua e hook_menu(), em seguida, definir essa página como o retorno de chamada de erro 403. Quando o retorno de chamada do menu personalizado é atingido, você sabe que está exibindo a página "acesso negado"!

opi
fonte
Esta não é uma boa solução para mim como isso está mudando a saída, não só detectar a 403.
Fabien Quatravaux
12

Eu faço isso no Boost 7.x. Não é bonito, mas faz o trabalho.

function boost_page_delivery_callback_alter(&$callback, $set = FALSE) {
  if ($callback == 'drupal_deliver_html_page') {
    $callback = 'boost_deliver_html_page';
  }
}

function boost_deliver_html_page($page_callback_result) {
  global $_boost;

  // Menu status constants are integers; page content is a string or array.
  if (is_int($page_callback_result)) {
    // @todo: Break these up into separate functions?
    switch ($page_callback_result) {

      // …

      case MENU_ACCESS_DENIED:
        // 403 page.
        $_boost['menu_item']['status'] = 403;
        break;

      // …

    }
    // …
  }
  // …   
}
mikeytown2
fonte
Este é um grande truque, mas funciona: o que você está fazendo é chamado de seqüestro. Você conecta seu próprio código em um ponto anterior e, em seguida, reproduz o código principal com uma modificação mínima.
Fabien Quatravaux
10

No Drupal 7, a função que retorna os cabeçalhos HTTP já definidos é drupal_get_http_header () , que requer o nome do cabeçalho HTTP como parâmetro. Olhando para authorize_access_denied_page () , e drupal_fast_404 () código deixa claro que valoriza a passar para essa função.

  // authorize_access_denied_page()
  drupal_add_http_header('Status', '403 Forbidden');
  watchdog('access denied', 'authorize.php', NULL, WATCHDOG_WARNING);
  drupal_set_title('Access denied');
  return t('You are not allowed to access this page.');
// drupal_fast_404()
if ($fast_paths && preg_match($fast_paths, $_GET['q'])) {
  drupal_add_http_header('Status', '404 Not Found');
  $fast_404_html = variable_get('404_fast_html', '<html xmlns="http://www.w3.org/1999/xhtml"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>');
  // Replace @path in the variable with the page path.
  print strtr($fast_404_html, array('@path' => check_plain(request_uri())));
  exit;
}

Quando o cabeçalho "Status" começa com 403 , o Drupal gera uma página de acesso negado.

Verifique se a ligação drupal_get_http_header('Status')acontece tarde. A chamada durante hook_init()é muito cedo, mas a chamada durante hook_page_alter()(ou qualquer gancho de pré-processo de tema) terá as informações atualizadas do cabeçalho.

kiamlaluno
fonte
Esta é realmente a boa resposta. Apenas um ponto a ser observado: parece funcionar apenas se a página não estiver em cache. Se a página já tiver sido acessada antes, os drupal_get_http_header('Status')retornos NULL.
Fabien Quatravaux
4

Seu módulo pode interceptar o valor " Default 403 (access denied) page" modificado pela página "Administer > Site configuration > Error reporting ":

  1. Em hook_enable, usando variable_get/ variable_set, copie o valor existente para uma variável secundária e substitua a variável pelo seu próprio caminho (que você registrou usando hook_menu).

  2. altere o formulário "Relatório de erros" usandohook_form_FORM_ID_alter para ler / gravar na variável secundária

  3. Se você deseja ser completamente invisível para o usuário, o retorno de chamada da sua página pode chamar drupal_goto( the_value_of_the_secondary_variable ) .

  4. Em hook_disable, restaure o valor da variável secundária.


E é isso, seu módulo é notificado de maneira limpa (e invisível para o usuário) quando o "Acesso negado" é acionado.

picos selvagens
fonte
2

Essa é a maneira mais simples de detectar acesso negado (403) e página não encontrada (404) no Drupal 7.

// get the menu router item for the current page
$router_item = menu_get_item();

// if there is no router item, this page is not found
$is_page_not_found_404 = empty($router_item);

// if 'access' is empty for the router item, access is denied
$is_access_denied_403 = empty($router_item['access']);
Lindsay
fonte
-2

Você pode usar o módulo Painéis para isso.

O módulo Painéis permite que um administrador do site crie layouts personalizados para vários usos. Na sua essência, é um gerenciador de conteúdo de arrastar e soltar que permite projetar visualmente um layout e colocar conteúdo dentro desse layout. A integração com outros sistemas permite criar nós que usam isso, páginas de destino que usam isso e até substituir páginas do sistema, como taxonomia e página do nó, para que você possa personalizar o layout do seu site com permissões refinadas.

Umuthan Uyan
fonte