11

I'm looking to create a copy of a webform I've made, with a new email address as the recipient.

After I load the node with node_load, can I just save it with node_save? Will that create a new node with new timestamps and ids?

How can I get the nid of the new node that has been created?

4 Answers 4

17

Just unset the node ID with unset($node->nid), and node_save() will create a new node.

The code executed from node_save() is the following one:

// Insert a new node.
$node->is_new = empty($node->nid);
// ...
if ($node->is_new) {
  _node_save_revision($node, $user->uid);
  drupal_write_record('node', $node);
  db_query('UPDATE {node_revisions} SET nid = %d WHERE vid = %d', $node->nid, $node->vid);
  $op = 'insert';
}    

The last argument of drupal_write_record() is not passed; this means the function will not update an existing database row.

Once the node object has been saved with node_save(), $node->nid contains the node ID for the newly created database row.

3
  • The webform object of the node has a lot of nid keys in its arrays that contain the old nid, what should I do about them?
    – Arosboro
    Commented Jul 9, 2011 at 23:06
  • Drupal just check $node->nid. If none of those node IDs is the ID of the loaded node, which needs to be changed with the ID of the saved node, then you can leave those node IDs as they are.
    – avpaderno
    Commented Jul 9, 2011 at 23:08
  • 2
    If you are using the path module you might also want to unset($node->path); Commented Mar 20, 2013 at 13:18
6

I had to post this as an answer because the system makes you have 50 reputation points before you can comment.

Anyway, in response to @koivo and his answer. I just wanted to add that for me, also unsetting the $node->vid did the trick. So my code for unsetting and saving is

// Load a node
$node = node_load(1);

// unset version and node id's
unset($node->nid);
unset($node->vid);
unset($node->path);

// Save the copy
node_save($node);
2

In D7 you have to unset the node id unset($node->nid) and the revision id unset($node->vid) both. I build a form to clone nodes of one certain type (product) having one certain term reference (with replacing that term id). Here's the final submit:

function MYMODULE_form_submit($form, &$form_state) {
    $old_tid = $form_state['values']['old_tid'];
    $new_tid = $form_state['values']['new_tid'];

    $query = new EntityFieldQuery();
    $result = $query
    ->entityCondition('entity_type', 'node')
    ->entityCondition('bundle', 'product')
    ->fieldCondition('field_some_term_reference', 'tid', $old_tid)
    ->execute();

    foreach ($result['node'] as $product) {
        $node = node_load($product->nid);
        $node->field_some_term_reference[LANGUAGE_NONE][0]['tid'] = $new_tid;
        unset($node->nid);
        unset($node->vid);
        node_save($node);
    }   
}

You might consider to resave the timestamps und $node->uid as well.

1
  • 1
    If there is any entityreference field on original node then it is not retaining its value on cloned node and also entitymalformedexception is raised for not specifying node type. I am testing in D7. any clue?
    – kiranking
    Commented Mar 16, 2015 at 19:47
2

Try the replicate module.
I needed to easily clone and alter things on a site I did recently and found this module worked well.
Check out the replicate.api.php file to see how easy it is to use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.