¿Cómo duplicar programáticamente un nodo?

11

Estoy buscando crear una copia de un formulario web que hice, con una nueva dirección de correo electrónico como destinatario.

Después de cargar el nodo con node_load, ¿puedo guardarlo con node_save? ¿Creará eso un nuevo nodo con nuevas marcas de tiempo e identificadores?

¿Cómo puedo obtener el nid del nuevo nodo que se ha creado?

Arosboro
fuente

Respuestas:

17

Simplemente desactive la ID de nodo con unset($node->nid), y node_save () creará un nuevo nodo.

El código ejecutado desde node_save()es el siguiente:

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

El último argumento de drupal_write_record () no se pasa; Esto significa que la función no actualizará una fila de base de datos existente.

Una vez que el objeto de nodo se ha guardado con node_save(), $node->nidcontiene la ID de nodo para la fila de base de datos recién creada.

kiamlaluno
fuente
El objeto de formulario web del nodo tiene muchas claves nid en sus matrices que contienen el nid anterior, ¿qué debo hacer al respecto?
Arosboro
Drupal solo verifica $node->nid. Si ninguna de esas ID de nodo es la ID del nodo cargado, que debe cambiarse con la ID del nodo guardado, puede dejar esas ID de nodo tal como están.
kiamlaluno
2
Si está utilizando el módulo de ruta, es posible que también deseeunset($node->path);
Patrick James McDougle el
6

Tuve que publicar esto como respuesta porque el sistema te hace tener 50 puntos de reputación antes de que puedas comentar.

De todos modos, en respuesta a @koivo y su respuesta. Solo quería agregar eso para mí, también desestabilizar el $node->vidhecho. Entonces mi código para desarmar y guardar es

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

En D7, debe desarmar el id del nodo unset($node->nid)y el id de revisión unset($node->vid). Construyo un formulario para clonar nodos de un determinado tipo (producto) que tiene un cierto término de referencia (con el reemplazo de ese término id). Aquí está el envío 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);
    }   
}

Puede considerar volver a guardar las marcas de tiempo y $node->uidtambién.

leymannx
fuente
Si hay algún campo de referencia de entidad en el nodo original, entonces no retiene su valor en el nodo clonado y también se genera una excepción de informe de entidad por no especificar el tipo de nodo. Estoy probando en D7. ¿Cualquier pista?
kiranking
2

Prueba el módulo de réplica .
Necesitaba clonar y modificar cosas fácilmente en un sitio que hice recientemente y descubrí que este módulo funcionaba bien.
Consulte el archivo replicate.api.php para ver lo fácil que es usarlo.

2pha
fuente