Выпустите 403 для определенных узлов - PullRequest
4 голосов
/ 16 сентября 2010

Как вы выдаете 403 для определенных узлов? Я пытался использовать drupal_access_denied. Когда я получил сообщение «Отказано в доступе», сторожевой таймер заполняется:

Невозможно изменить информацию заголовка - заголовки уже отправлены

Это нормально? Разве я не использую drupal_access_denied, верно?

1 Ответ

6 голосов
/ 17 сентября 2010

Использование предложенного hook_nodeapi() еще слишком поздно.

Если вы используете $op = load, вы, вероятно, исчерпаете свою память, потому что Drupal уже выполняет все обычные действия, которые он выполняет при загрузке узла (включая загрузку его несколько раз).

Если вы используете $op = view, вы можете «подделать» его, если сделаете следующее:

function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch ($op) {
    case 'view':
      drupal_access_denied();
      exit();
      break;
  }
}

Но это не настоящий 403: об этом не будет сообщено, кроме как в Watchdog, и все обычные вещи будут по-прежнему загружаться и рендериться, как если бы там был узел.

Для простого взлома вы можете использовать hook_init():

function mymodule_init() {
  $nodes_403 = array(42, 69, 187);
  if (arg(0) == 'node' && in_array(arg(1), $nodes_403))
    drupal_access_denied();
    exit();
  }
}

Но это без необходимости обходит встроенную систему разрешений Drupal. Вместо этого вы хотите воспользоваться преимуществами системы доступа к узлу Drupal , чтобы запретить доступ к узлу.

Если вы определили свой собственный тип контента в модуле, вы можете использовать hook_access():

function mymodule_access($op, $node, $account) {
  $nodes_403 = array(42, 69, 187);

  if (in_array($node->nid, $nodes_403)) {
    return FALSE;
  }
}

Но если вы не определяете свои собственные типы контента, hook_access() никогда не вызывается. Поэтому вместо этого вам нужно переопределить путь к узлу access callback своим собственным:

function mymodule_menu_alter(&$items) {
  $items['node/%node']['access callback'] = 'mymodule_access';
}

function mymodule_access($op, $node, $account = NULL) {
  $nodes_403 = array(42, 69, 187);

  if ($op == 'view' && in_array($node->nid, $nodes_403)) {
    return FALSE;
  }

  return node_access($op, $node, $account);
}

Из-за реализации hook_menu_alter() обязательно перестройте свою систему меню после реализации вышеупомянутого.

...