【问题标题】:Drupal 7 hook_node_access to conditionally block node accessDrupal 7 hook_node_access 有条件地阻止节点访问
【发布时间】:2011-07-29 16:04:42
【问题描述】:

对于所有用户,我需要有条件地阻止对“消息”类型节点的访问。用户应该能够查看这些消息节点的唯一方法是成功提交表单。

我是这样开始的:

  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(+ 在大多数情况下,这将是一个匿名用户)

对实现此目的的不同方法有什么建议吗?

【问题讨论】:

    标签: drupal drupal-7 drupal-hooks


    【解决方案1】:

    您可以这样做的唯一方法是在表单提交处理程序中设置一个值,然后由hook_node_access() 进行检查;您可以使用 Drupal 变量或保存在数据库表中的值。 您需要存储访问该表单的用户的用户 ID,以及已提交该表单的每个节点的节点 ID。

    假设您使用 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 变量。

    【讨论】:

    • 感谢您的指点,我第一次在 Drupal 中使用变量。我有一个可行的解决方案(发布在下面)——不确定它是否是最优雅的解决方案,但可行!
    • 感谢您的帮助 - 我第一次尝试使用变量 for 和 node_access 时学到了很多东西。我越来越近了!
    【解决方案2】:

    修改了使用 $_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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多