Comment un module peut-il détecter la sortie de la page «accès refusé»?

16

Comment est-il possible pour un module de détecter quand Drupal sort la page "accès refusé"?
Je sais comment le faire avec Drupal 6; J'ai besoin de savoir comment le faire avec Drupal 7.

kiamlaluno
la source

Réponses:

13

Vous pouvez définir les pages à afficher lorsque des erreurs 403 et 404 se produisent (admin / paramètres / rapport d'erreurs).

Je suppose que vous pouvez ajouter une nouvelle page dans votre hook_menu(), puis définir cette page comme rappel d'erreur 403. Lorsque votre rappel de menu personnalisé est atteint, vous savez que vous affichez la page "accès refusé"!

opi
la source
Ce n'est pas une bonne solution pour moi car cela change la sortie, pas seulement la détection du 403.
Fabien Quatravaux
12

Je le fais dans Boost 7.x. Ce n'est pas joli, mais cela fait le travail.

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
la source
Celui-ci est un gros hack mais ça marche: ce que vous faites s'appelle le détournement. Vous branchez votre propre code à un point antérieur, puis reproduisez le code principal avec une modification minimale.
Fabien Quatravaux
10

Dans Drupal 7, la fonction qui renvoie les en-têtes HTTP déjà définis est drupal_get_http_header () , qui nécessite le nom d'en-tête HTTP comme paramètre. En regardant authorize_access_denied_page () , et drupal_fast_404 () Code précise les valeurs à transmettre à cette fonction.

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

Lorsque l'en-tête "Status" commence par 403 , Drupal génère une page d'accès refusé.

Assurez-vous que l'appel drupal_get_http_header('Status')arrive tard. Appeler pendant hook_init()est trop tôt, mais l'appeler pendant hook_page_alter()(ou tout crochet de prétraitement de thème) aura les informations d'en-tête mises à jour.

kiamlaluno
la source
Celui-ci est vraiment la bonne réponse. Un seul point à noter cependant: cela ne semble fonctionner que si la page n'est pas mise en cache. Si la page a déjà été consultée auparavant, le drupal_get_http_header('Status')retourne NULL.
Fabien Quatravaux
4

Votre module pourrait intercepter la valeur de " Default 403 (access denied) page" qui est modifiée par la page " Administer > Site configuration > Error reporting":

  1. Dans hook_enable, en utilisant variable_get/ variable_set, copiez la valeur existante dans une variable secondaire et remplacez la variable par votre propre chemin (que vous avez enregistré en utilisant hook_menu).

  2. modifier le formulaire "Rapport d'erreur" en utilisant hook_form_FORM_ID_alterpour lire / écrire dans la variable secondaire

  3. Si vous voulez être complètement invisible pour l'utilisateur, le rappel de votre page pourrait appeler drupal_goto( the_value_of_the_secondary_variable ).

  4. Dans hook_disable, restaurez la valeur de la variable secondaire.


Et c'est tout, votre module est averti de manière claire (et invisible pour l'utilisateur) lorsque "Accès refusé" est déclenché.

pics sauvages
la source
2

C'est le moyen le plus simple de détecter l'accès refusé (403) et la page non trouvée (404) dans 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
la source
-2

Vous pouvez utiliser le module Panels pour cela.

Le module Panneaux permet à un administrateur de site de créer des mises en page personnalisées pour plusieurs utilisations. À la base, il s'agit d'un gestionnaire de contenu par glisser-déposer qui vous permet de concevoir visuellement une mise en page et de placer du contenu dans cette mise en page. L'intégration avec d'autres systèmes vous permet de créer des nœuds qui l'utilisent, des pages de destination qui l'utilisent et même de remplacer les pages système telles que la taxonomie et la page de nœud afin que vous puissiez personnaliser la mise en page de votre site avec des autorisations très fines.

Umuthan Uyan
la source