Как программно дублировать узел?


11

Я пытаюсь создать копию веб-формы, которую я сделал, с новым адресом электронной почты в качестве получателя.

После того, как я загружу узел с помощью node_load, могу ли я просто сохранить его с помощью node_save? Это создаст новый узел с новыми временными метками и идентификаторами?

Как я могу получить nid нового узла, который был создан?

Ответы:


17

Просто сбросьте идентификатор узла с помощью unset($node->nid), и node_save () создаст новый узел.

Код, выполняемый из, node_save()следующий:

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

Последний аргумент drupal_write_record () не передан; это означает, что функция не будет обновлять существующую строку базы данных.

Как только объект узла был сохранен с node_save(), $node->nidсодержит идентификатор узла для вновь созданной строки базы данных.


У объекта webform узла есть много ключей nid в своих массивах, которые содержат старый nid, что мне с ними делать?
Аросборо

Друпал просто проверь $node->nid. Если ни один из этих идентификаторов узлов не является идентификатором загруженного узла, который необходимо изменить с помощью идентификатора сохраненного узла, вы можете оставить эти идентификаторы узлов такими, какие они есть.
kiamlaluno

2
Если вы используете модуль пути, вы также можете захотетьunset($node->path);
Патрик Джеймс МакДугл

6

Я должен был опубликовать это как ответ, потому что система дает вам 50 очков репутации, прежде чем вы сможете комментировать.

Во всяком случае, в ответ на @koivo и его ответ. Я просто хотел добавить это для меня, также сбросив, $node->vidсделал свое дело. Так что мой код для сброса и сохранения

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

В D7 вы должны сбросить идентификатор узла и идентификатор unset($node->nid)ревизии unset($node->vid). Я создаю форму для клонирования узлов одного определенного типа (продукта), имеющих одну определенную ссылку на термин (с заменой этого термина id). Вот заключительная отправка:

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

Вы могли бы также подумать о том, чтобы восстановить метки времени $node->uidи.


Если на исходном узле имеется какое-либо поле entityreference, то оно не сохраняет свое значение на клонированном узле, а также выдается entitymalformedexception для того, чтобы не указывать тип узла. Я тестирую в D7. какая-нибудь подсказка?
kiranking

2

Попробуйте дублировать модуль .
Мне нужно было легко клонировать и изменять вещи на сайте, который я недавно сделал, и обнаружил, что этот модуль работает хорошо.
Проверьте файл replicate.api.php, чтобы увидеть, насколько легко его использовать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.