Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Drupal 7钩住节点访问以有条件地阻止节点访问_Drupal_Drupal 7_Drupal Hooks - Fatal编程技术网

Drupal 7钩住节点访问以有条件地阻止节点访问

Drupal 7钩住节点访问以有条件地阻止节点访问,drupal,drupal-7,drupal-hooks,Drupal,Drupal 7,Drupal Hooks,对于所有用户,我需要有条件地阻止对“message”类型节点的访问。用户能够查看这些消息节点的唯一方法是成功提交表单 我是这样开始的: function mymodule_node_access($node, $op, $account) { if ($op == 'view' && $node->type == 'message') { return NODE_ACCESS_DENY; } } 但是,我希望在成功提交表单后允许查看此类

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

我是这样开始的:

  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属于“message”类型,我想“解除”这个特定节点和这个用户的节点访问拒绝(+在大多数情况下,这将是一个匿名用户)


关于实现这一点的不同方法有什么建议吗?

唯一的方法是在表单提交处理程序中设置一个值,然后由
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变量。

修改了使用$\u会话的解决方案,因为我主要与匿名用户合作:

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

谢谢你的指针,这是我第一次在Drupal中使用变量。我有一个有效的解决方案(贴在下面)-不确定它是否是最优雅的解决方案,但有效!感谢您的帮助-我第一次尝试使用varaibles和node_访问时学到了很多东西。我越来越近了!