Comment dupliquer par programmation un nœud?

11

Je cherche à créer une copie d'un formulaire Web que j'ai créé, avec une nouvelle adresse e-mail en tant que destinataire.

Après avoir chargé le nœud avec node_load, puis-je simplement l'enregistrer avec node_save? Cela créera-t-il un nouveau nœud avec de nouveaux horodatages et identifiants?

Comment puis-je obtenir le nid du nouveau nœud qui a été créé?

Arosboro
la source

Réponses:

17

Décochez simplement l'ID de nœud avec unset($node->nid), et node_save () créera un nouveau nœud.

Le code exécuté à partir de node_save()est le suivant:

// 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';
}    

Le dernier argument de drupal_write_record () n'est pas passé; cela signifie que la fonction ne mettra pas à jour une ligne de base de données existante.

Une fois que l'objet nœud a été enregistré avec node_save(), $node->nidcontient l'ID de nœud pour la ligne de base de données nouvellement créée.

kiamlaluno
la source
L'objet webform du nœud a beaucoup de clés nid dans ses tableaux qui contiennent l'ancien nid, que dois-je faire à leur sujet?
Arosboro
Drupal vérifie juste $node->nid. Si aucun de ces ID de nœud n'est l'ID du nœud chargé, qui doit être modifié avec l'ID du nœud enregistré, vous pouvez laisser ces ID de nœud tels quels.
kiamlaluno
2
Si vous utilisez le module de chemin, vous voudrez peut-être aussiunset($node->path);
Patrick James McDougle
6

J'ai dû poster ceci comme réponse car le système vous fait avoir 50 points de réputation avant de pouvoir commenter.

Quoi qu'il en soit, en réponse à @koivo et sa réponse. Je voulais juste ajouter cela pour moi, ce qui a également effacé $node->vidle truc. Donc, mon code de suppression et d'enregistrement est

// 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);
Jorge Calderon
la source
2

Dans D7, vous devez désactiver l'ID de nœud unset($node->nid)et l'ID de révision unset($node->vid)tous les deux. Je crée un formulaire pour cloner des nœuds d'un certain type (produit) ayant une certaine référence de terme (en remplaçant ce terme id). Voici la soumission finale:

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);
    }   
}

Vous pourriez également envisager de réenregistrer les horodatages $node->uid.

leymannx
la source
S'il existe un champ de référence d'entité sur le nœud d'origine, il ne conserve pas sa valeur sur le nœud cloné et une exception entitymalformedexception est déclenchée pour ne pas spécifier le type de nœud. Je teste en D7. un indice?
kiranking
2

Essayez le module de réplication .
J'avais besoin de cloner et de modifier facilement des choses sur un site que j'ai fait récemment et j'ai trouvé que ce module fonctionnait bien.
Consultez le fichier replicate.api.php pour voir à quel point il est facile à utiliser.

2pha
la source