Como duplicar programaticamente um nó?

11

Estou procurando criar uma cópia de um formulário da web que fiz, com um novo endereço de email como destinatário.

Depois de carregar o nó com node_load, posso apenas salvá-lo com node_save? Isso criará um novo nó com novos carimbos de data e hora?

Como posso obter o nid do novo nó que foi criado?

Arosboro
fonte

Respostas:

17

Apenas desative o ID do nó com unset($node->nid), e node_save () criará um novo nó.

O código executado a partir de node_save()é o seguinte:

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

O último argumento de drupal_write_record () não é passado; isso significa que a função não atualizará uma linha de banco de dados existente.

Depois que o objeto do nó foi salvo node_save(), ele $node->nidcontém o ID do nó da linha do banco de dados recém-criada.

kiamlaluno
fonte
O objeto de formulário da web do nó possui muitas chaves nid em suas matrizes que contêm o nid antigo, o que devo fazer sobre elas?
Arosboro
Drupal apenas verifique $node->nid. Se nenhum desses IDs de nó for o ID do nó carregado, que precisa ser alterado com o ID do nó salvo, você poderá deixá-los como estão.
kiamlaluno
2
Se você estiver usando o módulo caminho que você pode também quererunset($node->path);
Patrick James McDougle
6

Eu tive que postar isso como resposta, porque o sistema faz com que você tenha 50 pontos de reputação antes de poder comentar.

De qualquer forma, em resposta ao @koivo e sua resposta. Eu só queria acrescentar isso para mim, também desabilitando $node->vido truque. Portanto, meu código para desarmar e salvar é

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

No D7, é necessário desconfigurar o ID do nó unset($node->nid)e o ID da revisão unset($node->vid). Crio um formulário para clonar nós de um determinado tipo (produto) com um determinado termo de referência (com a substituição desse termo id). Aqui está o envio final:

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

Você também pode salvar novamente os carimbos de data e hora $node->uid.

leymannx
fonte
Se houver algum campo de referência da entidade no nó original, ele não manterá seu valor no nó clonado e também a exceção entitymalformed será gerada para não especificar o tipo de nó. Estou testando em D7. qualquer pista?
kiranking
2

Experimente o módulo de replicação .
Eu precisava clonar e alterar facilmente as coisas em um site que fiz recentemente e achei que este módulo funcionava bem.
Confira o arquivo replicate.api.php para ver como é fácil usar.

2pha
fonte