3

すべてのユーザーに対して、「メッセージ」タイプのノードへのアクセスを条件付きでブロックする必要があります。ユーザーがこれらのメッセージ ノードを表示できる唯一の方法は、フォームを正常に送信することです。

私はこのように始めました:

  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 を「持ち上げる」必要があります (+ ほとんどの場合、これは匿名ユーザーになります)

これを達成するためのさまざまな方法に関する提案はありますか?

4

2 に答える 2

4

これを行う唯一の方法は、フォーム送信ハンドラーに値を設定し、それを によってチェックすること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;
}

このコードでは、ユーザーがノードに 1 回だけアクセスできることに注意してください。ユーザーが同じノードに 2 回アクセスしようとすると、「アクセスが拒否されました」というエラーが表示されます。それが望ましくない場合は、2 番目の関数を次のように書き直す必要があります。

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 変数を使用しないでください。

于 2011-07-29T17:39:06.007 に答える
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;
}
于 2011-07-31T11:43:51.260 に答える