Jak programowo powielić węzeł?

11

Chcę utworzyć kopię formularza internetowego, który wykonałem, z nowym adresem e-mail jako odbiorcą.

Czy po załadowaniu węzła z node_load mogę po prostu zapisać go z node_save? Czy stworzy to nowy węzeł z nowymi znacznikami czasu i identyfikatorami?

Jak mogę uzyskać identyfikator nowego utworzonego węzła?

Arosboro
źródło

Odpowiedzi:

17

Po prostu usuń identyfikator węzła unset($node->nid), a node_save () utworzy nowy węzeł.

Wykonany kod node_save()jest następujący:

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

Ostatni argument drupal_write_record () nie został przekazany; oznacza to, że funkcja nie zaktualizuje istniejącego wiersza bazy danych.

Gdy obiekt węzeł został zapisany z node_save(), $node->nidzawiera identyfikator węzła dla nowo utworzonego rzędu bazy danych.

kiamlaluno
źródło
Obiekt WWW węzła ma wiele kluczy nid w swoich tablicach, które zawierają stary identyfikator nid. Co mam z nimi zrobić?
Arosboro,
Drupal tylko sprawdź $node->nid. Jeśli żaden z tych identyfikatorów węzłów nie jest identyfikatorem załadowanego węzła, który należy zmienić za pomocą identyfikatora zapisanego węzła, możesz pozostawić te identyfikatory węzłów bez zmian.
kiamlaluno
2
Jeśli korzystasz z modułu ścieżki, możesz także chciećunset($node->path);
Patrick James McDougle
6

Musiałem opublikować to jako odpowiedź, ponieważ system sprawia, że ​​masz 50 punktów reputacji, zanim będziesz mógł komentować.

W każdym razie w odpowiedzi na @koivo i jego odpowiedź. Chciałem tylko dodać to dla mnie, również zaburzając to, co $node->vidzrobiłem. Więc mój kod do rozbrajania i zapisywania to

// 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
źródło
2

W D7 musisz rozbroić zarówno identyfikator węzła, jak unset($node->nid)i identyfikator unset($node->vid)wersji. Buduję formularz do klonowania węzłów jednego określonego typu (produktu) posiadającego jedno określone odniesienie do terminu (z zastąpieniem tego terminu id). Oto końcowe przesłanie:

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

Możesz również rozważyć ponowne zapisanie znaczników czasu $node->uid.

leymannx
źródło
Jeśli w oryginalnym węźle znajduje się pole odwołania do encji, wówczas nie zachowuje ono swojej wartości w sklonowanym węźle, a także zgłaszany jest wyjątek uprawniający do nieokreślenia typu węzła. Testuję w D7. jakaś wskazówka?
Kiringing
2

Wypróbuj moduł replikacji .
Musiałem łatwo sklonować i zmienić rzeczy na stronie, którą ostatnio zrobiłem i stwierdziłem, że ten moduł działa dobrze.
Sprawdź plik replicate.api.php , aby zobaczyć, jak łatwo jest go używać.

2pha
źródło