Commit 58b0235a authored by Dries's avatar Dries

- Patch #324313 by catch et al: load multiple nodes and terms at once.

parent 0b06c68b
......@@ -32,6 +32,9 @@ Drupal 7.0, xxxx-xx-xx (development version)
* Redesigned password strength validator.
* Redesigned the add content type screen.
* Highlight duplicate URL aliases.
- Performance:
* Improved performance on uncached page views by loading multiple core
objects in a single database query.
- Documentation:
* Hook API documentation now included in Drupal core.
- News aggregator:
......
......@@ -705,18 +705,13 @@ function book_build_active_trail($book_link) {
/**
* Implementation of hook_nodeapi_load().
*/
function book_nodeapi_load(&$node, $teaser, $page) {
// Note - we cannot use book_link_load() because it will call node_load().
$info['book'] = db_query('SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid = :nid', array(
':nid' => $node->nid
))->fetchAssoc();
if ($info['book']) {
$info['book']['href'] = $info['book']['link_path'];
$info['book']['title'] = $info['book']['link_title'];
$info['book']['options'] = unserialize($info['book']['options']);
return $info;
function book_nodeapi_load($nodes, $types) {
$result = db_query("SELECT * FROM {book} b INNER JOIN {menu_links} ml ON b.mlid = ml.mlid WHERE b.nid IN (" . db_placeholders(array_keys($nodes)) . ")", array_keys($nodes), array('fetch' => PDO::FETCH_ASSOC));
foreach ($result as $record) {
$nodes[$record['nid']]->book = $record;
$nodes[$record['nid']]->book['href'] = $record['link_path'];
$nodes[$record['nid']]->book['title'] = $record['link_title'];
$nodes[$record['nid']]->book['options'] = unserialize($record['options']);
}
}
......
......@@ -146,7 +146,7 @@ class BookTestCase extends DrupalWebTestCase {
}
// Check to make sure the book node was created.
$node = node_load(array('title' => $edit['title']));
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->assertNotNull(($node === FALSE ? NULL : $node), t('Book node found in database.'));
$number++;
......
......@@ -579,11 +579,32 @@ function comment_form_alter(&$form, $form_state, $form_id) {
/**
* Implementation of hook_nodeapi_load().
*/
function comment_nodeapi_load(&$node, $arg = 0) {
if ($node->comment != COMMENT_NODE_DISABLED) {
return db_query('SELECT last_comment_timestamp, last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->nid))->fetchAssoc();
function comment_nodeapi_load($nodes, $types) {
$comments_enabled = array();
// Check if comments are enabled for each node. If comments are disabled,
// assign values without hitting the database.
foreach ($nodes as $node) {
// Store whether comments are enabled for this node.
if ($node->comment != COMMENT_NODE_DISABLED) {
$comments_enabled[] = $node->nid;
}
else {
$node->last_comment_timestamp = $node->created;
$node->last_comment_name = '';
$node->comment_count = 0;
}
}
// For nodes with comments enabled, fetch information from the database.
if (!empty($comments_enabled)) {
$result = db_query('SELECT nid, last_comment_timestamp, last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid IN(' . db_placeholders($comments_enabled) . ')', $comments_enabled);
foreach ($result as $record) {
$nodes[$record->nid]->last_comment_timestamp = $record->last_comment_timestamp;
$nodes[$record->nid]->last_comment_name = $record->last_comment_name;
$nodes[$record->nid]->comment_count = $record->comment_count;
}
}
return array('last_comment_timestamp' => $node->created, 'last_comment_name' => '', 'comment_count' => 0);
}
/**
......
......@@ -262,7 +262,7 @@ class DBLogTestCase extends DrupalWebTestCase {
$this->drupalPost('node/add/' . $type, $edit, t('Save'));
$this->assertResponse(200);
// Retrieve node object.
$node = node_load(array('title' => $title));
$node = $this->drupalGetNodeByTitle($title);
$this->assertTrue($node != null, t('Node @title was loaded', array('@title' => $title)));
// Edit node.
$edit = $this->getContentUpdate($type);
......
......@@ -114,7 +114,7 @@ class FilterAdminTestCase extends DrupalWebTestCase {
$this->drupalPost('node/add/page', $edit, t('Save'));
$this->assertRaw(t('Page %title has been created.', array('%title' => $edit['title'])), t('Filtered node created.'));
$node = node_load(array('title' => $edit['title']));
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->assertTrue($node, t('Node found in database.'));
$this->drupalGet('node/' . $node->nid);
......
......@@ -341,11 +341,25 @@ function forum_nodeapi_delete(&$node, $teaser, $page) {
/**
* Implementation of hook_nodeapi_load().
*/
function forum_nodeapi_load(&$node, $teaser, $page) {
function forum_nodeapi_load($nodes, $types) {
$vid = variable_get('forum_nav_vocabulary', '');
// If no forum vocabulary is set up, return.
if ($vid == '') {
return;
}
$vocabulary = taxonomy_vocabulary_load($vid);
if (_forum_nodeapi_check_node_type($node, $vocabulary)) {
return db_fetch_array(db_query('SELECT tid AS forum_tid FROM {forum} WHERE vid = %d', $node->vid));
$node_vids = array();
foreach ($nodes as $node) {
if (isset($vocabulary->nodes[$node->type])) {
$node_vids[] = $node->vid;
}
}
if (!empty($node_vids)) {
$result = db_query('SELECT nid, tid FROM {forum} WHERE vid IN(' . db_placeholders($node_vids) . ')', $node_vids);
foreach ($result as $record) {
$nodes[$record->nid]->forum_tid = $record->tid;
}
}
}
......@@ -451,15 +465,6 @@ function forum_form_alter(&$form, $form_state, $form_id) {
}
}
/**
* Implementation of hook_load().
*/
function forum_load($node) {
$forum = db_fetch_object(db_query('SELECT * FROM {term_node} WHERE vid = %d', $node->vid));
return $forum;
}
/**
* Implementation of hook_block().
*
......
......@@ -236,7 +236,7 @@ class ForumTestCase extends DrupalWebTestCase {
}
// Retrieve node object.
$node = node_load(array('title' => $title), null, true); // Are these last two parameters necessary?
$node = $this->drupalGetNodeByTitle($title);
$this->assertTrue($node != null, t('Node @title was loaded', array('@title' => $title)));
// View forum topic.
......
......@@ -154,6 +154,39 @@ function hook_node_operations() {
return $operations;
}
/**
* Act on node objects when loaded.
*
* This hook allows you to add information to node objects when loaded from
* the database. It takes an array of nodes indexed by nid as its first
* parameter. For performance reasons, information for all available nodes
* should be loaded in a single query where possible.
*
* The types of all nodes being passed in are also available in the $types
* parameter. If your module keeps track of the node types it supports, this
* allows for an early return if nothing needs to be done.
*
* Due to the internal cache in node_load_multiple(), you should not use this
* hook to modify information returned from the {node} table itself, since
* this may affect the way nodes are returned from the cache in subsequent
* calls to the function.
*
* @see comment_nodeapi_load()
* @see taxonomy_nodeapi_load()
* @see forum_nodeapi_load()
*
* @param $nodes
* An array of node objects indexed by nid.
* @param $types
* An array containing the types of the nodes.
*/
function hook_nodeapi_load($nodes, $types) {
$result = db_query('SELECT nid, foo FROM {mytable} WHERE nid IN(' . db_placeholders(array_keys($nodes)) . ')', array_keys($nodes));
foreach ($result as $record) {
$nodes[$record->nid]->foo = $record->foo;
}
}
/**
* Act on nodes defined by other modules.
*
......@@ -521,25 +554,22 @@ function hook_insert($node) {
* Load node-type-specific information.
*
* This is a hook used by node modules. It is called to allow the module
* a chance to load extra information that it stores about a node, or
* possibly replace already loaded information - which can be dangerous.
* a chance to load extra information that it stores about a node. The hook
* should not be used to replace information from the core {node} table since
* this may interfere with the way nodes are fetched from cache.
*
* @param $node
* The node being loaded. At call time, node.module has already loaded
* the basic information about the node, such as its node ID (nid),
* title, and body.
* @return
* An object containing properties of the node being loaded. This will
* be merged with the passed-in $node to result in an object containing
* a set of properties resulting from adding the extra properties to
* the passed-in ones, and overwriting the passed-in ones with the
* extra properties if they have the same name as passed-in properties.
* @param $nodes
* An array of the nodes being loaded, keyed by nid. At call time,
* node.module has already loaded the basic information about the nodes, such
* as node ID (nid), title, and body.
*
* For a detailed usage example, see node_example.module.
*/
function hook_load($node) {
$additions = db_fetch_object(db_query('SELECT * FROM {mytable} WHERE vid = %d', $node->vid));
return $additions;
function hook_load($nodes) {
$result = db_fetch_object(db_query('SELECT nid, foo FROM {mytable} WHERE nid IN (' . db_placeholders(array_keys($nodes)) . ')', array_keys($nodes)));
foreach ($result as $record) {
$nodes[$record->nid]->foo = $record->foo;
}
}
/**
......
......@@ -730,93 +730,177 @@ function node_invoke_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
}
/**
* Load a node object from the database.
* Load node objects from the database.
*
* This function should be used whenever you need to load more than one node
* from the database. Nodes are loaded into memory and will not require
* database access if loaded again during the same page request.
*
* @param $param
* Either the nid of the node or an array of conditions to match against in the database query
* @param $revision
* Which numbered revision to load. Defaults to the current version.
* @param $nids
* An array of node IDs.
* @param $conditions
* An array of conditions on the {node} table in the form 'field' => $value.
* @param $reset
* Whether to reset the internal node_load cache.
*
* @return
* A fully-populated node object.
* An array of node objects indexed by nid.
*/
function node_load($param = array(), $revision = NULL, $reset = NULL) {
static $nodes = array();
function node_load_multiple($nids = array(), $conditions = array(), $reset = FALSE) {
static $node_cache = array();
if ($reset) {
$nodes = array();
}
$cachable = ($revision == NULL);
$arguments = array();
if (is_numeric($param)) {
if ($cachable) {
// Is the node statically cached?
if (isset($nodes[$param])) {
return is_object($nodes[$param]) ? clone $nodes[$param] : $nodes[$param];
$node_cache = array();
}
$nodes = array();
// Create a new variable which is either a prepared version of the $nids
// array for later comparison with the node cache, or FALSE if no $nids were
// passed. The $nids array is reduced as items are loaded from cache, and we
// need to know if it's empty for this reason to avoid querying the database
// when all requested nodes are loaded from cache.
$passed_nids = !empty($nids) ? array_flip($nids) : FALSE;
// Revisions are not statically cached, and require a different query to
// other conditions, so separate vid into its own variable.
$vid = isset($conditions['vid']) ? $conditions['vid'] : FALSE;
unset($conditions['vid']);
// Load any available nodes from the internal cache.
if ($node_cache && !$vid) {
if ($nids) {
$nodes += array_intersect_key($node_cache, $passed_nids);
// If any nodes were loaded, remove them from the $nids still to load.
$nids = array_keys(array_diff_key($passed_nids, $nodes));
}
// If loading nodes only by conditions, fetch all available nodes from
// the cache. Nodes which don't match are removed later.
elseif ($conditions) {
$nodes = $node_cache;
}
}
// Exclude any nodes loaded from cache if they don't match $conditions.
// This ensures the same behaviour whether loading from memory or database.
if ($conditions) {
foreach ($nodes as $node) {
$node_values = (array) $node;
if (array_diff_assoc($conditions, $node_values)) {
unset($nodes[$node->nid]);
}
}
$cond = 'n.nid = %d';
$arguments[] = $param;
}
elseif (is_array($param)) {
// Turn the conditions into a query.
foreach ($param as $key => $value) {
$cond[] = 'n.' . db_escape_table($key) . " = '%s'";
$arguments[] = $value;
// Load any remaining nodes from the database. This is the case if there are
// any $nids left to load, if loading a revision, or if $conditions was
// passed without $nids.
if ($nids || $vid || ($conditions && !$passed_nids)) {
$query = db_select('node', 'n');
if ($vid) {
$query->join('node_revision', 'r', 'r.nid = n.nid AND r.vid = :vid', array(':vid' => $vid));
}
$cond = implode(' AND ', $cond);
}
else {
return FALSE;
}
else {
$query->join('node_revision', 'r', 'r.vid = n.vid');
}
$query->join('users', 'u', 'u.uid = n.uid');
// Retrieve a field list based on the site's schema.
$fields = drupal_schema_fields_sql('node', 'n');
$fields = array_merge($fields, drupal_schema_fields_sql('node_revision', 'r'));
$fields = array_merge($fields, array('u.name', 'u.picture', 'u.data'));
// Remove fields not needed in the query: n.vid and r.nid are redundant,
// n.title is unnecessary because the node title comes from the
// node_revisions table. We'll keep r.vid, r.title, and n.nid.
$fields = array_diff($fields, array('n.vid', 'n.title', 'r.nid'));
$fields = implode(', ', $fields);
// Rename timestamp field for clarity.
$fields = str_replace('r.timestamp', 'r.timestamp AS revision_timestamp', $fields);
// Change name of revision uid so it doesn't conflict with n.uid.
$fields = str_replace('r.uid', 'r.uid AS revision_uid', $fields);
// Retrieve the node.
// No db_rewrite_sql is applied so as to get complete indexing for search.
if ($revision) {
array_unshift($arguments, $revision);
$node = db_fetch_object(db_query('SELECT ' . $fields . ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revision} r ON r.nid = n.nid AND r.vid = %d WHERE ' . $cond, $arguments));
}
else {
$node = db_fetch_object(db_query('SELECT ' . $fields . ' FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revision} r ON r.vid = n.vid WHERE ' . $cond, $arguments));
}
// Add fields from the {node} table.
$node_fields = drupal_schema_fields_sql('node');
// vid and title are provided by node_revision, so remove them.
unset($node_fields['vid']);
unset($node_fields['title']);
$query->fields('n', $node_fields);
// Add all fields from the {node_revision} table.
$node_revision_fields = drupal_schema_fields_sql('node_revision');
// nid is provided by node, so remove it.
unset($node_revision_fields['nid']);
if ($node && $node->nid) {
// Call the node specific callback (if any) and piggy-back the
// results to the node or overwrite some values.
if ($extra = node_invoke($node, 'load')) {
foreach ($extra as $key => $value) {
$node->$key = $value;
// Change timestamp to revision_timestamp before adding it to the query.
unset($node_revision_fields['timestamp']);
$query->addField('r', 'timestamp', 'revision_timestamp');
$query->fields('r', $node_revision_fields);
// Add fields from the {users} table.
$user_fields = array('name', 'picture', 'data');
$query->fields('u', $user_fields);
if ($nids) {
$query->condition('n.nid', $nids, 'IN');
}
if ($conditions) {
foreach ($conditions as $field => $value) {
$query->condition('n.' . $field, $value);
}
}
$queried_nodes = $query->execute()->fetchAllAssoc('nid');
}
// Pass all nodes loaded from the database through the node type specific
// callbacks and hook_nodeapi_load(), then add them to the internal cache.
if (!empty($queried_nodes)) {
// Create an array of nodes for each content type and pass this to the
// node type specific callback.
$typed_nodes = array();
foreach ($queried_nodes as $nid => $node) {
$typed_nodes[$node->type][$nid] = $node;
}
if ($extra = node_invoke_nodeapi($node, 'load')) {
foreach ($extra as $key => $value) {
$node->$key = $value;
// Call node type specific callbacks on each typed array of nodes.
foreach ($typed_nodes as $type => $nodes_of_type) {
if (node_hook($type, 'load')) {
$function = node_get_types('base', $type) . '_load';
$function($nodes_of_type);
}
}
if ($cachable) {
$nodes[$node->nid] = is_object($node) ? clone $node : $node;
// Call hook_nodeapi_load(), pass the node types so modules can return early
// if not acting on types in the array.
foreach (module_implements('nodeapi_load') as $module) {
$function = $module . '_nodeapi_load';
$function($queried_nodes, array_keys($typed_nodes));
}
$nodes += $queried_nodes;
// Add nodes to the cache if we're not loading a revision.
if (!$vid) {
$node_cache += $queried_nodes;
}
}
return $node;
// Ensure that the returned array is ordered the same as the original $nids
// array if this was passed in and remove any invalid nids.
if ($passed_nids) {
// Remove any invalid nids from the array.
$passed_nids = array_intersect_key($passed_nids, $nodes);
foreach ($nodes as $node) {
$passed_nids[$node->nid] = $node;
}
$nodes = $passed_nids;
}
return $nodes;
}
/**
* Load a node object from the database.
*
* @param $nid
* The node ID.
* @param $vid
* The revision ID.
* @param $reset
* Whether to reset the internal node_load cache.
*
* @return
* A fully-populated node object.
*/
function node_load($nid, $vid = array(), $reset = FALSE) {
$vid = isset($vid) ? array('vid' => $vid) : NULL;
$node = node_load_multiple(array($nid), $vid, $reset);
return $node ? $node[$nid] : FALSE;
}
/**
......@@ -1740,22 +1824,18 @@ function node_feed($nids = FALSE, $channel = array()) {
global $base_url, $language;
if ($nids === FALSE) {
$nids = array();
$result = db_query_range(db_rewrite_sql('SELECT n.nid, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, variable_get('feed_default_items', 10));
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
}
$nids = db_query_range(db_rewrite_sql('SELECT n.nid, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, variable_get('feed_default_items', 10))->fetchCol();
}
$item_length = variable_get('feed_item_length', 'teaser');
$namespaces = array('xmlns:dc' => 'http://purl.org/dc/elements/1.1/');
// Load all nodes to be rendered.
$nodes = node_load_multiple($nids);
$items = '';
foreach ($nids as $nid) {
// Load the specified node:
$item = node_load($nid);
foreach ($nodes as $item) {
$item->build_mode = NODE_BUILD_RSS;
$item->link = url("node/$nid", array('absolute' => TRUE));
$item->link = url("node/$item->nid", array('absolute' => TRUE));
if ($item_length != 'title') {
$teaser = ($item_length == 'teaser');
......@@ -1822,16 +1902,14 @@ function node_feed($nids = FALSE, $channel = array()) {
* Menu callback; Generate a listing of promoted nodes.
*/
function node_page_default() {
$result = pager_query(db_rewrite_sql('SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10));
$output = '';
$num_rows = FALSE;
while ($node = db_fetch_object($result)) {
$output .= node_view(node_load($node->nid), 1);
$num_rows = TRUE;
}
$nids = pager_query(db_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10))->fetchCol();
if (!empty($nids)) {
$nodes = node_load_multiple($nids);
$output = '';
foreach ($nodes as $node) {
$output .= node_view($node, TRUE);
}
if ($num_rows) {
$feed_url = url('rss.xml', array('absolute' => TRUE));
drupal_add_feed($feed_url, variable_get('site_name', 'Drupal') . ' ' . t('RSS'));
$output .= theme('pager', NULL, variable_get('default_nodes_main', 10));
......
<?php
// $Id$
/**
* Test the node_load_multiple() function.
*/
class NodeLoadMultipleUnitTest extends DrupalWebTestCase {
function getInfo() {
return array(
'name' => t('Load multiple nodes'),
'description' => t('Test the loading of multiple nodes.'),
'group' => t('Node'),
);
}
function setUp() {
parent::setUp();
$web_user = $this->drupalCreateUser(array('create article content', 'create page content'));
$this->drupalLogin($web_user);
}
/**
* Create four nodes and ensure they're loaded correctly.
*/
function testNodeMultipleLoad() {
$node1 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
$node2 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1));
$node3 = $this->drupalCreateNode(array('type' => 'article', 'promote' => 0));
$node4 = $this->drupalCreateNode(array('type' => 'page', 'promote' => 0));
// Confirm that promoted nodes appear in the default node listing.
$this->drupalGet('node');
$this->assertText($node1->title, t('Node title appears on the default listing.'));
$this->assertText($node2->title, t('Node title appears on the default listing.'));
$this->assertNoText($node3->title, t('Node title does not appear in the default listing.'));
$this->assertNoText($node4->title, t('Node title does not appear in the default listing.'));
// Load nodes with only a condition. Nodes 3 and 4 will be loaded.
$nodes = node_load_multiple(NULL, array('promote' => 0));
$this->assertEqual($node3->title, $nodes[$node3->nid]->title, t('Node was loaded.'));
$this->assertEqual($node4->title, $nodes[$node4->nid]->title, t('Node was loaded.'));
$count = count($nodes);
$this->assertTrue($count == 2, t('@count nodes loaded.', array('@count' => $count)));
// Load nodes by nid. Nodes 1, 2 and 4 will be loaded.
$nodes = node_load_multiple(array(1, 2, 4));
$count = count($nodes);
$this->assertTrue(count($nodes) == 3, t('@count nodes loaded', array('@count' => $count)));
$this->assertTrue(isset($nodes[$node1->nid]), t('Node is correctly keyed in the array'));
$this->assertTrue(isset($nodes[$node2->nid]), t('Node is correctly keyed in the array'));
$this->assertTrue(isset($nodes[$node4->nid]), t('Node is correctly keyed in the array'));
foreach ($nodes as $node) {
$this->assertTrue(is_object($node), t('Node is an object'));
}
// Load nodes by nid, where type = article. Nodes 1, 2 and 3 will be loaded.
$nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article'));
$count = count($nodes);
$this->assertTrue($count == 3, t('@count nodes loaded', array('@count' => $count)));
$this->assertEqual($nodes[$node1->nid]->title, $node1->title, t('Node successfully loaded.'));
$this->assertEqual($nodes[$node2->nid]->title, $node2->title, t('Node successfully loaded.'));
$this->assertEqual($nodes[$node3->nid]->title, $node3->title, t('Node successfully loaded.'));
$this->assertFalse(isset($nodes[$node4->nid]));
// Now that all nodes have been loaded into the static cache, ensure that
// they are loaded correctly again when a condition is passed.
$nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article'));
$count = count($nodes);
$this->assertTrue($count == 3, t('@count nodes loaded.', array('@count' => $count)));
$this->assertEqual($nodes[$node1->nid]->title, $node1->title, t('Node successfully loaded'));
$this->assertEqual($nodes[$node2->nid]->title, $node2->title, t('Node successfully loaded'));
$this->assertEqual($nodes[$node3->nid]->title, $node3->title, t('Node successfully loaded'));
$this->assertFalse(isset($nodes[$node4->nid]), t('Node was not loaded'));
// Load nodes by nid, where type = article and promote = 0.
$nodes = node_load_multiple(array(1, 2, 3, 4), array('type' => 'article', 'promote' => 0));
$count = count($nodes);
$this->assertTrue($count == 1, t('@count node loaded', array('@count' => $count)));
$this->assertEqual($nodes[$node3->nid]->title, $node3->title, t('Node successfully loaded.'));
}
}
class NodeRevisionsTestCase extends DrupalWebTestCase {
protected $nodes;
protected $logs;
......@@ -258,7 +338,7 @@ class PageEditTestCase extends DrupalWebTestCase {
$this->drupalPost('node/add/page', $edit, t('Save'));
// Check that the node exists in the database.
$node = node_load(array('title' => $edit['title']));
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->assertTrue($node, t('Node found in database.'));
// Check that "edit" link points to correct page.
......@@ -352,7 +432,7 @@ class PageCreationTestCase extends DrupalWebTestCase {
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Page', '%title' => $edit['title'])), t('Page created.'));
// Check that the node exists in the database.
$node = node_load(array('title' => $edit['title']));
$node = $this->drupalGetNodeByTitle($edit['title']);
$this->assertTrue($node, t('Node found in database.'));
}
}
......
......@@ -135,12 +135,14 @@ function path_nodeapi_validate(&$node, $arg) {
/**
* Implementation of hook_nodeapi_load().
*/
function path_nodeapi_load(&$node, $arg) {
$language = isset($node->language) ? $node->language : '';
$path = 'node/' . $node->nid;
$alias = drupal_get_path_alias($path, $language);
if ($path != $alias) {
$node->path = $alias;
function path_nodeapi_load($nodes, $types) {
foreach ($nodes as $node) {
$language = isset($node->language) ? $node->language : '';
$path = 'node/' . $node->nid;
$alias = drupal_get_path_alias($path, $language);
if ($path != $alias) {
$node->path = $alias;
}
}
}
......
......@@ -131,7 +131,7 @@ class PathTestCase extends DrupalWebTestCase {
$this->drupalPost('node/add/page', $edit, t('Save'));
// Check to make sure the node was created.
$node = node_load(array('title' => $edit['title']));