Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.805 diff -u -p -r1.805 common.inc --- includes/common.inc 11 Oct 2008 21:53:36 -0000 1.805 +++ includes/common.inc 12 Oct 2008 00:48:18 -0000 @@ -3295,8 +3295,6 @@ function drupal_write_record($table, &$o // Track serial fields so we can helpfully populate them after the query. if ($info['type'] == 'serial') { $serials[] = $field; - // Ignore values for serials when inserting data. Unsupported. - unset($object->$field); } // Build arrays for the fields, placeholders, and values in our query. Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.984 diff -u -p -r1.984 node.module --- modules/node/node.module 11 Oct 2008 21:11:00 -0000 1.984 +++ modules/node/node.module 12 Oct 2008 00:48:22 -0000 @@ -896,20 +896,23 @@ function node_submit($node) { } /** - * Save a node object into the database. + * Save changes to a node or add a new node. + * + * @param $node + * The $node object to be saved. If $node->nid is + * omitted (or $node->is_new is TRUE) a new node will be added. */ function node_save(&$node) { // Let modules modify the node before it is saved to the database. node_invoke_nodeapi($node, 'presave'); global $user; - $node->is_new = FALSE; + if (!isset($node->is_new)) { + $node->is_new = empty($node->nid); + } // Apply filters to some default node fields: - if (empty($node->nid)) { - // Insert a new node. - $node->is_new = TRUE; - + if ($node->is_new) { // When inserting a node, $node->log must be set because // {node_revisions}.log does not (and cannot) have a default // value. If the user does not have permission to create @@ -931,6 +934,7 @@ function node_save(&$node) { } elseif (!empty($node->revision)) { $node->old_vid = $node->vid; + unset($node->vid); } else { // When updating a node, avoid clobberring an existing log entry with an empty one. @@ -975,9 +979,12 @@ function node_save(&$node) { // node_invoke($node, 'update'). node_invoke($node, $op); node_invoke_nodeapi($node, $op); - + // Update the node access table for this node. node_access_acquire_grants($node); + + // Clear internal properties. + unset($node->is_new); // Clear the page and block caches. cache_clear_all(); @@ -986,7 +993,7 @@ function node_save(&$node) { /** * Helper function to save a revision with the uid of the current user. * - * Node is taken by reference, becuse drupal_write_record() updates the + * Node is taken by reference, because drupal_write_record() updates the * $node with the revision id, and we need to pass that back to the caller. */ function _node_save_revision(&$node, $uid, $update = NULL) { Index: modules/node/node.test =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.test,v retrieving revision 1.7 diff -u -p -r1.7 node.test --- modules/node/node.test 11 Oct 2008 18:29:20 -0000 1.7 +++ modules/node/node.test 12 Oct 2008 00:48:22 -0000 @@ -460,3 +460,52 @@ class NodeTitleXSSTestCase extends Drupa $this->assertNoRaw($xss, t('Harmful tags are escaped when editing a node.')); } } + +class NodeImportTestCase extends DrupalWebTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('Import test'), + 'description' => t('Test node_save for importing content.'), + 'group' => t('Node'), + ); + } + + /** + * Implementation of setUp(). + */ + function setUp() { + parent::setUp(); + // create a user that is allowed to post, we'll use this to test the submission + $web_user = $this->drupalCreateUser(array('create article content')); + $this->drupalLogin($web_user); + $this->web_user = $web_user; + } + + /** + * First create a piece of content, then do the import and check for + * imported values. + */ + function testImport() { + $test_nid = 99999; + $title = 'Import test title'; + $node = new StdClass; + $node->title = $title; + $node->body ='test body'; + $node->uid = $this->web_user->uid; + $node->nid = $test_nid; + $node->is_new = TRUE; + $node->status = 1; + $node->type = 'article'; // notice if not provided + $node->vid = 1; // notice if not provided + node_save($node); + // now lets test this import + $node_test = node_load(array('nid' => $test_nid)); + $this->assertTrue($node_test, t('Node load based on nid failed')); + + $node_test2 = node_load(array('title' => $title)); + $this->assertTrue($node_test2, t('Node load based on title failed')); + } +} Index: modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.927 diff -u -p -r1.927 user.module --- modules/user/user.module 9 Oct 2008 15:15:55 -0000 1.927 +++ modules/user/user.module 12 Oct 2008 00:48:23 -0000 @@ -201,7 +201,7 @@ function user_load($array = array()) { * * @param $account * The $user object for the user to modify or add. If $user->uid is - * omitted, a new user will be added. + * omitted (or $user->is_new == TRUE), a new user will be added. * * @param $edit * An array of fields and values to save. For example array('name' @@ -234,7 +234,10 @@ function user_save($account, $edit = arr unset($edit['pass']); } - if (is_object($account) && $account->uid) { + if (!isset($account->is_new)) { + $account->is_new = empty($account->uid); + } + if (is_object($account) && !$account->is_new) { user_module_invoke('update', $edit, $account, $category); $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid))); // Consider users edited by an administrator as logged in, if they haven't @@ -245,7 +248,7 @@ function user_save($account, $edit = arr foreach ($edit as $key => $value) { // Fields that don't pertain to the users or user_roles // automatically serialized into the users.data column. - if ($key != 'roles' && empty($user_fields[$key])) { + if (!in_array($key, array('roles', 'is_new')) && empty($user_fields[$key])) { if ($value === NULL) { unset($data[$key]); } @@ -326,7 +329,7 @@ function user_save($account, $edit = arr // fields from being saved there. $data = array(); foreach ($edit as $key => $value) { - if (($key != 'roles') && (empty($user_fields[$key])) && ($value !== NULL)) { + if (!in_array($key, array('roles', 'is_new')) && empty($user_fields[$key]) && $value !== NULL) { $data[$key] = $value; } } Index: modules/user/user.test =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.test,v retrieving revision 1.17 diff -u -p -r1.17 user.test --- modules/user/user.test 10 Oct 2008 07:49:49 -0000 1.17 +++ modules/user/user.test 12 Oct 2008 00:48:23 -0000 @@ -570,3 +570,34 @@ class UserAutocompleteTestCase extends D $this->assertRaw($this->unprivileged_user->name, t('User name found in autocompletion results.')); } } + +class UserImportTestCase extends DrupalWebTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('User import test'), + 'description' => t('Test creating user with arbitrary uid'), + 'group' => t('User'), + ); + } + + /** + * Test creating a user with arbitrary uid + */ + function testUserImport() { + $test_uid = 99999; + $user = array( + 'uid' => $test_uid, + 'is_new' => TRUE, + 'status' => 1, + 'mail' => '99999@example.com', + 'name' => 'al', + 'pass' => 'secret', + ); + user_save(NULL, $user); + $test_user = user_load(array('uid' => $test_uid)); + $this->assertTrue($test_user, t('User creation failed')); + } +}