Drupal 7 hook_node_access для условного блокирования доступа к узлу - PullRequest
3 голосов
/ 29 июля 2011

Для всех пользователей мне нужно условно заблокировать доступ к узлам типа «сообщение».Единственный способ, которым пользователи должны иметь возможность просматривать эти узлы сообщений, - это успешно отправить форму.

Я начал так:

  function mymodule_node_access($node, $op, $account) {
    if ($op == 'view' && $node->type == 'message') {
      return NODE_ACCESS_DENY;
    }
  }

Однако я хочу разрешить доступ к просмотру дляотдельные узлы этого типа при успешной отправке формы:

function form_submit($form, &$form_state) {
  // some logic here  
  $form_state['redirect'] = 'node/255';
}

, поэтому узел 255 имеет тип «сообщение», и я хочу «поднять» NODE_ACCESS_DENY для этого конкретного узла и этого пользователя (+ в большинствев случаях, когда это будет анонимный пользователь)

Есть предложения о том, как это сделать?

Ответы [ 2 ]

4 голосов
/ 29 июля 2011

Единственный способ сделать это - установить значение в обработчике отправки формы, которое затем проверяется hook_node_access();Вы можете использовать переменную Drupal или значение, сохраненное в таблице базы данных.Вам необходимо сохранить идентификатор пользователя, который получил доступ к форме, и идентификатор узла каждого узла, для которого была отправлена ​​такая форма.

Предположим, вы используете переменную Drupal, вы можете использовать код, подобныйследующий:

function mymodule_form_submit($form, &$form_state) {
  global $user;
  $message_nid = 255;
  $values = variable_get('access_nid', array());

  if (isset($values[$user->uid])) {
    if (!isset($values[$user->uid][$message_nid])) {
      $values[$user->uid][$message_nid] = $message_nid;
    }
  }
  else {
    $values[$user->uid] = array($message_nid => $message_nid);
  }

  variable_set('access_nid', $values);
  $form_state['redirect'] = 'node/' . $message_nid;
}

function mymodule_node_access($node, $op, $account) {
  $result = NODE_ACCESS_IGNORE;

  if ($op == 'view' && $node->type == 'message') {
    $values = variable_get('access_nid', array());
    if (!empty($values[$account->uid]) {
      if (isset($values[$account->uid][$node->nid])) {
        unset($values[$account->uid][$node->nid]);
        $result = NODE_ACCESS_ALLOW;
      }
      else {
        $result = NODE_ACCESS_DENY;
      }
    }
    else {
      $result = NODE_ACCESS_DENY;
    }
  }
  variable_set('access_nid', $values);

  return $result;
}

Чтобы заметить, что этот код позволяет пользователю получить доступ к узлу только один раз;если пользователь попытается получить доступ к тому же узлу во второй раз, он получит ошибку «отказано в доступе».Если это нежелательно, то вторая функция должна быть переписана следующим образом:

function mymodule_node_access($node, $op, $account) {
  if ($op == 'view' && $node->type == 'message') {
    $values = variable_get('access_nid', array());
    if (!empty($values[$account->uid]) {
      if (isset($values[$account->uid][$node->nid])) {
        return NODE_ACCESS_ALLOW;
      }

      return NODE_ACCESS_DENY;
      }
    }
    else {
      $result = NODE_ACCESS_DENY;
    }
  }

  return NODE_ACCESS_IGNORE;
}

Я использовал переменную Drupal для написания простого кода;в этом случае следует использовать переменную Drupal, если пользователей, которые могут создавать узлы этого типа контента, немного;если есть много пользователей, которые могут создавать эти узлы, то лучше использовать таблицу базы данных.
Также при использовании переменных Drupal Drupal использует таблицу базы данных;Разница в том, что содержимое этой таблицы базы данных всегда загружается в память.Если вам нужно хранить много данных, вы не должны использовать переменные Drupal.

2 голосов
/ 31 июля 2011

Модифицированное решение для использования $ _SESSION, так как я работаю в основном с анонимными пользователями:

function mymodule_form_submit($form, &$form_state) {
  $message_nid = 255;
  if (!isset($_SESSION['node_access'])) {
    $_SESSION['node_access'] = array();
  }
  if (!isset($_SESSION['node_access']['nid'])) {
    $_SESSION['node_access']['nid'] = $message_nid;
  }
  $form_state['redirect'] = 'node/' . $message_nid;
}

function mymodule_node_access($node, $op, $account) {
  $node_access = NODE_ACCESS_IGNORE;
  if ($op == 'view' && $node->type == 'message') {
    if (isset($_SESSION['node_access'] && !empty($_SESSION['node_access'])) {
      if ($node->nid == $_SESSION['node_access']['nid']) {
        unset($_SESSION['node_access']['nid']);
        $node_access = NODE_ACCESS_ALLOW ;
      } else {
        unset($_SESSION['node_access']['nid']);
        $node_access = NODE_ACCESS_DENY;
      }
    } else {
      $node_access = NODE_ACCESS_DENY;
    }
  }
  return $node_access;
}
...