Wie dupliziere ich einen Knoten programmgesteuert?

11

Ich möchte eine Kopie eines von mir erstellten Webformulars mit einer neuen E-Mail-Adresse als Empfänger erstellen.

Kann ich den Knoten nach dem Laden mit node_load einfach mit node_save speichern? Wird dadurch ein neuer Knoten mit neuen Zeitstempeln und IDs erstellt?

Wie kann ich die NID des neuen Knotens abrufen, der erstellt wurde?

Arosboro
quelle

Antworten:

17

Deaktivieren Sie einfach die Knoten-ID mit unset($node->nid), und node_save () erstellt einen neuen Knoten.

Der Code, von node_save()dem ausgeführt wird, ist der folgende:

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

Das letzte Argument von drupal_write_record () wird nicht übergeben. Dies bedeutet, dass die Funktion eine vorhandene Datenbankzeile nicht aktualisiert.

Sobald der Knoten Objekt mit gespeichert wurde node_save(), $node->nidenthält die ID - Knoten für die neu Datenbank Zeile erstellt.

kiamlaluno
quelle
Das Webform-Objekt des Knotens enthält viele NID-Schlüssel in seinen Arrays, die die alte NID enthalten. Was soll ich dagegen tun?
Arosboro
Drupal nur überprüfen $node->nid. Wenn keine dieser Knoten-IDs die ID des geladenen Knotens ist, die mit der ID des gespeicherten Knotens geändert werden muss, können Sie diese Knoten-IDs unverändert lassen.
Kiamlaluno
2
Wenn Sie das Pfadmodul verwenden, möchten Sie vielleicht auchunset($node->path);
Patrick James McDougle
6

Ich musste dies als Antwort posten, da das System Ihnen 50 Reputationspunkte einbringt, bevor Sie einen Kommentar abgeben können.

Wie auch immer, als Antwort auf @koivo und seine Antwort. Ich wollte das nur für mich hinzufügen und auch $node->vidden Trick deaktivieren . Mein Code zum Deaktivieren und Speichern lautet also

// 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
quelle
2

In D7 müssen Sie sowohl die Knoten-ID unset($node->nid)als auch die Revisions-ID unset($node->vid)deaktivieren. Ich erstelle ein Formular zum Klonen von Knoten eines bestimmten Typs (Produkts) mit einer bestimmten Begriffsreferenz (durch Ersetzen dieser Begriffs-ID). Hier ist die endgültige Einreichung:

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

Sie können auch die Zeitstempel und erneut speichern $node->uid.

Leymannx
quelle
Wenn auf dem ursprünglichen Knoten ein Entityreference-Feld vorhanden ist, behält es seinen Wert auf dem geklonten Knoten nicht bei, und es wird auch eine Entitymalformedexception ausgelöst, wenn kein Knotentyp angegeben wird. Ich teste in D7. irgendeine Ahnung?
Kiranking
2

Probieren Sie das Replikationsmodul aus .
Ich musste einfach Dinge auf einer Site klonen und ändern, die ich kürzlich gemacht hatte, und fand, dass dieses Modul gut funktionierte. Sehen
Sie sich die Datei replicate.api.php an, um zu sehen, wie einfach die Verwendung ist.

2pha
quelle