Clonar entidades en Drupal 8

Imagen
Clone Drupal

Crear un duplicado o clonar una entidad es muy sencillo si utilizamos la Entity API, ya que disponemos del método Entity::createDuplicate().

$nid = 5;
$entidad = \Drupal::service('entity_type.manager')->getStorage('node')->load($nid); //Usar la inyección de dependencias si se utiliza en una clase.
$duplicado = $entidad->createDuplicate();
$duplicado->save();

En el ejemplo vemos como cargar el nodo con la ID 5, y duplicarlo.

Clonar información a una entidad que ya exista.

Sin embargo, la clonación parcial o total de datos en una entidad existente es menos directa. Aún así, el poder hacerlo puede ser útil

  • En scripts de migración personalizados en los que queramos sobrescribir entidades antiguas sin crear otras nuevas.
  • En los casos en que necesitemos sobreescribir la entidad anterior ya que otros datos internos o externos pueden hacer referencia a ella y crear una nueva entidad rompería estas referencias.

El segundo caso podría ser un campo de referencia de la entidad que hace referencia a la antigua entidad (esto podría resolverse reasignando la referencia), pero también podría ser un software de terceros que haga referencia a la entidad anterior, lo que complicaría las cosas.

Mostraremos un par de formas posibles de clonar datos de entidad a otra entidad existente.

Clonar campos de una entidad a otra:

$origen_nid = 5;
$destino_nid = 6;

//Usar la inyección de dependencias si se utiliza en una clase.
$nem = \Drupal::service(‘entity_type.manager')->getStorage('node');
$origen = $nem->load($origen_nid);
$destino = $nem->load($destino_nid);

foreach ($origen->getFields() as $name => $field) {
   $destino->set($name, $field->getValue());
}

$destino->save();

Clonar unicamente nueva información:

Para importar unicamente los nuevos campos sin sobre escribir los actuales, únicamente debemos comprobar si el campo del destino esta vacío antes de copiarlo.

foreach ($origen->getFields() as $name => $field) {
  if ($destino->get($name)->isEmpty()) {
    $destino->set($name, $field->getValue());
  }
}