web-dev-qa-db-ja.com

ノードタイプのインスタンスを1つだけ作成するようにユーザーを制限するにはどうすればよいですか?

Node Limit モジュールがあることは知っていますが、かなり長い間アルファ段階であるため、追加のモジュールを必要としない、よりエレガントな方法があるかどうか疑問に思っています。

5
alfish

FWIW私はNode開発サイトの制限を数週間使用していますが、十分なテストが行​​われており、完全に機能しているようです。「ノード制限タイプ」と「ノード役割のユーザーの制限」サブモジュール。

自分で実装する場合は、Node Limitモジュール自体の内部よりも優れた場所を実際に見つけることはできません。 hook_node_prepare() を実装しますさまざまなルールに基づいて、ユーザーが最大ノード数を超えた場合、ノード追加フォームへのアクセスを拒否します。

非常に単純なカスタム実装は次のようになります。

_function MYMODULE_node_prepare($node) {
  if (empty($node->nid) && $node->type == 'the_content_type') {
    // Grab the number of nodes of this type the user has already created.
    $args = array(':type' => 'the_content_type', ':uid' => $GLOBALS['user']->uid);
    $node_count = db_query('SELECT COUNT(nid) FROM {node} WHERE type = :type AND uid = :uid', $args)->fetchField();

    // Get the max allowed number of nodes
    $limit = function_to_get_limit();

    // If the user is at/has exceeded the limit, set a message and send the user
    // off somewhere else.
    if ($limit >= $node_count) {
      drupal_set_message(t('Node limit exceeded'));

      drupal_goto('somewhere');
    }
  }
}
_

そこにさらにチェックを追加して、ユーザーが特定の役割などを持っていることを確認することもできます。Node Limitモジュールのコードをフリックして、上記の方法を確認することをお勧めします改善される。

上記は、チェックを実行するための「フレンドリーな」方法です(つまり、403ページをスローしないだけの方法)。より好戦的になりたい場合は、代わりにほぼ同じコードを hook_node_access() 実装に追加できます。

_function MYMODULE_node_access($node, $op, $account) {
  if ($op == 'create' && $node->type == 'the_content_type') {
    // Grab the number of nodes of this type the user has already created.
    $args = array(':type' => 'the_content_type', ':uid' => $account->uid);
    $node_count = db_query('SELECT COUNT(nid) FROM {node} WHERE type = :type AND uid = :uid', $args)->fetchField();

    // Get the max allowed number of nodes
    $limit = function_to_get_limit();

    // If the user us at/has exceeded the limit, set a message and send the user
    // off somewhere else.
    if ($limit >= $node_count) {
      return NODE_ACCESS_DENY;
    }

    return NODE_ACCESS_ALLOW;
  }

  return NODE_ACCESS_IGNORE;
}
_
6
Clive

ユーザーがコンテンツタイプの単一ノードを自分のサイトに作成できるようにしたいと思っていました。私の使用例では、すべてのユーザーがノードを持っている必要があり(基本的にはノードをプロファイルとして使用している)、 Rules モジュールを使用してノードとユーザーへの関係(Relationモジュールを使用)を自動的に作成しましたアカウントの検証時(ただし、関係が必要ない場合もあります)。

次に、コンテンツタイプの独自のノードを編集する権限をユーザーに付与しましたが、作成は許可しませんでした。

3
Patrick Kenny

必要な場合は、 Only One モジュールのコードを調べて、これを実現する簡単な方法を確認できます。

Only Oneモジュールでは、この構成で選択されたコンテンツタイプの言語ごとにOnly Oneノードを作成できます。

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function onlyone_form_node_form_alter(&$form, &$form_state, $form_id) {
  $onlyone_content_types = variable_get('onlyone_node_types');
  // Getting the name of the node type.
  $node_type = $form['type']['#value'];
  // Verifying if the new node should by onlyone.
  if (isset($onlyone_content_types) && in_array($node_type, $onlyone_content_types, TRUE)) {
    $node = $form_state['node'];
    // If we are trying to create a new node.
    if (!isset($node->nid) || isset($node->is_new)) {
      $query = new EntityFieldQuery();
      $query->entityCondition('entity_type', 'node')
        ->entityCondition('bundle', $node_type);
      // The site is multilingual?
      if (drupal_multilingual()) {
        global $language;
        $query->propertyCondition('language', $language->language);
      }
      // Executing the query.
      $result = $query->execute();
      // If we have one node, then redirect to the edit page.
      if (isset($result['node'])) {
        $nid = array_keys($result['node']);
        $nid = $nid[0];
        drupal_goto('node/' . $nid . '/edit');
      }
    }
  }
}

開示:私はモジュールのメンテナーです Only One

1