web-dev-qa-db-ja.com

複数のノードを読み込む

Drupal 6に複数のノードをロードするにはどうすればよいですか?

node_load()は1つのレコードしか返さないようです。ユーザーが作成したすべてのノードをフェッチする必要があります。

3
hd.

Drupal 7では、 node_load_multiple() を使用してユースケースに対応し、Drupal 6のサポートはまもなく終了します、したがって、アップグレードを計画している場合は、それまでに作業を延期することを検討してください。

Drupal 6では、私が知っている唯一の方法は db_query() を使用して{users}を{node}に結合するか、またはWHEREを{node}に適用することです。 node_load() でループします。

「データベースクエリで照合する条件の配列」をnode_load()に渡すことができますが、とにかく1つのノードしか返さないため、これは解決策ではありません。

独自のnode_load_multiple()を定義して、元のnode_load()からコードを取得し、$node = db_fetch_objectを次のように置き換えることもできます。

$nodes = array();
while($node = db_fetch_object) {
  // original processing
  $nodes[$node->nid] = $node;
}

内部を集計します。私は実際にはそのようなものがコアにあることに少し驚いていますが、今それを提案するには遅すぎます。

4
Mołot

次の関数を使用できます。

_function node_load_by_user_id($uid = NULL) {
  $nodes = array();

  if (is_null($uid)) {
    $uid = $GLOBALS['user']->uid;
  }

  $fields = drupal_schema_fields_sql('node', 'n');
  $fields = array_merge($fields, drupal_schema_fields_sql('node_revisions', 'r'));
  $fields = array_merge($fields, array('u.name', 'u.picture', 'u.data'));
  $fields = array_diff($fields, array('n.vid', 'n.title', 'r.nid'));
  $fields = implode(', ', $fields);
  $fields = str_replace('r.timestamp', 'r.timestamp AS revision_timestamp', $fields);
  $fields = str_replace('r.uid', 'r.uid AS revision_uid', $fields);

  $query = db_query('SELECT ' . $fields . ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE u.uid = %d', $uid)

  while ($node = db_fetch_object($query)) {
    if ($node->nid) {
      if ($extra = node_invoke($node, 'load')) {
        foreach ($extra as $key => $value) {
          $node->$key = $value;
        }
      }

      if ($extra = node_invoke_nodeapi($node, 'load')) {
        foreach ($extra as $key => $value) {
          $node->$key = $value;
        }
      }

      $nodes[$node->nid] = drupal_clone($node);
    }
  }

  return $nodes;
}
_

node_load()で使用されるコードを取得し、同じユーザーが作成したノードの配列を返すようにコードを適合させました。

この関数は、IDが引数として渡されるユーザーによって作成されたすべてのノードをロードしているため、ユーザーが十分なノードを作成したときに、この関数はおそらくすべてのPHPメモリを使い果たします。次のようにします。一度に限られた数のノードのみをロードする関数。

_function node_load_by_user_id($uid = NULL, $from, $count) {
  $nodes = array();

  if (is_null($uid)) {
    $uid = $GLOBALS['user']->uid;
  }

  $fields = drupal_schema_fields_sql('node', 'n');
  $fields = array_merge($fields, drupal_schema_fields_sql('node_revisions', 'r'));
  $fields = array_merge($fields, array('u.name', 'u.picture', 'u.data'));
  $fields = array_diff($fields, array('n.vid', 'n.title', 'r.nid'));
  $fields = implode(', ', $fields);
  $fields = str_replace('r.timestamp', 'r.timestamp AS revision_timestamp', $fields);
  $fields = str_replace('r.uid', 'r.uid AS revision_uid', $fields);

  $query = db_query_range('SELECT ' . $fields . ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE u.uid = %d', $uid, $from, $count)

  while ($node = db_fetch_object($query)) {
    if ($node->nid) {
      if ($extra = node_invoke($node, 'load')) {
        foreach ($extra as $key => $value) {
          $node->$key = $value;
        }
      }

      if ($extra = node_invoke_nodeapi($node, 'load')) {
        foreach ($extra as $key => $value) {
          $node->$key = $value;
        }
      }

      $nodes[$node->nid] = drupal_clone($node);
    }
  }

  return $nodes;
}
_

この場合、次のノードを取得するために2番目のパラメーターを変更して関数を呼び出す必要があります。

_$from = 0;
$count = 50;
while ($nodes = node_load_by_user_id($uid, $from, $count)) {
  // Use $nodes.
  $from += $count;
}
_
1
kiamlaluno