Noviembre 17, 2016
langelhc
En el artículo anterior explicamos que Drupal 8 (D8) trae en el núcleo (core) un sistema de migración automatizada que permite migrar tanto la configuración como el contenido desde Drupal 6/7, en éste articulo explicaremos como migrar sólo el contenido creando un modulo personalizado y un plugin de migración.
Asumiremos que el sitio de D8 ya ha sido desarrollado, es decir que ya tenemos creado los tipos de contenido y sus respectivos campos, pero todavía no se ha creado contenido.
Para este ejemplo tenemos como objetivo migrar el contenido del tipo page que tiene dos campos tipo imagen y enlace desde un sitio desarrollado en D7.
Creación de un módulo personalizado:
Utilizando la Drupal Console creamos un módulo llamado Custom migration:
$ drupal generate:module
Creación de la Plantilla de migración:
Dentro del modulo Custom migration, creamos la carpeta migration_templates, donde ubicaremos el archivo YAML:
Aquí definimos entre otras cosas lo siguiente:
-
El identificador de la migración será: custom_migration_node_page.
-
El source plugin que se utilizara para ésta migración.
-
En process, definimos el mapeo de propiedades y los valores que asumirán:
- La propiedad type para hacer referencia al nombre del tipo de contenido destino.
- La propiedad field_image_d8 que asumirá el valor de field_image.
- La propiedad field_link_d8 que asumirá el valor asignado a field_link.
-
En migration_dependencies, definimos como dependencia obligatoria al Id ‘d7_file’, que se encarga de la migración de archivos, esto para el campo tipo imagen del tipo de contenido page.
id: custom_migration_node_page
label: Page Nodes
migration_tags:
- Drupal 7
source:
plugin: custom_migration_node_page
process:
nid: nid
vid: vid
langcode:
plugin: default_value
source: language
default_value: "und"
title: title
uid: node_uid
type: type
status: status
created: created
changed: changed
promote: promote
sticky: sticky
revision_uid: revision_uid
revision_log: log
revision_timestamp: timestamp
field_image_d8: field_image
field_link_d8: field_link
destination:
plugin: entity:node
migration_dependencies:
required:
- d7_file
Ruta: modules/custom/custom_migration/migration_templates/custom_migration_node_page.yml
Creación del Plugin de Migración:
Este archivo debe llevar el mismo nombre que la clase que se define ahi dentro, y debe estar ubicado dentro de la siguiente estructura: /custom_migration/src/Plugin/migrate/source.
Es importante definir el identificador de la migracion en la Anotación @MigrateSource.
En la función query, agregamos una condición para obtener solo el contenido de tipo page, aquí tambien podríamos agregar una condición para que se migre solo el contenido que esta publicado en el sitio de D7.
Ruta: modules/custom/custom_migration/src/Plugin/migrate/source/custom_migration_node_page.php
<?php
namespace Drupal\custom_migration\Plugin\migrate\source;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
/**
* Drupal 7 node source from database.
*
* @MigrateSource(
* id = "custom_migration_node_page",
* source_provider = "node"
* )
*/
class custom_migration_node_page extends FieldableEntity {
/**
* The join options between the node and the node_revisions table.
*/
const JOIN = 'n.vid = nr.vid';
/**
* {@inheritdoc}
*/
public function query() {
// Select node in its last revision.
$query = $this->select('node_revision', 'nr')
->fields('n', array(
'nid',
'type',
'language',
'status',
'created',
'changed',
'comment',
'promote',
'sticky',
'tnid',
'translate',
))
->fields('nr', array(
'vid',
'title',
'log',
'timestamp',
));
$query->addField('n', 'uid', 'node_uid');
$query->addField('nr', 'uid', 'revision_uid');
$query->innerJoin('node', 'n', static::JOIN);
$query->condition('n.type', 'page');
return $query;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
$nid = $row->getSourceProperty('nid');
$vid = $row->getSourceProperty('vid');
$row->setSourceProperty('type', 'page');
$image_d7 = $this->getFieldValues('node', 'field_image', $nid, $vid);
if (!empty($image_d7)) {
$value_image[] = [
'target_id' => $image_d7[0]['fid'],
'alt' => $image_d7[0]['alt'],
'title' => $image_d7[0]['title'],
'width' => $image_d7[0]['width'],
'height' => $image_d7[0]['height'],
];
$row->setSourceProperty('field_image', $value_image);
}
$link_d7 = $this->getFieldValues('node', 'field_link', $nid, $vid);
if (!empty($link_d7)) {
$link_value[0]['uri'] = $link_d7[0]['url'];
$link_value[0]['title'] = $link_d7[0]['title'];
$row->setSourceProperty('field_link', $link_value);
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function fields() {
$fields = array(
'nid' => $this->t('Node ID'),
'type' => $this->t('Type'),
'title' => $this->t('Title'),
'node_uid' => $this->t('Node authored by (uid)'),
'revision_uid' => $this->t('Revision authored by (uid)'),
'created' => $this->t('Created timestamp'),
'changed' => $this->t('Modified timestamp'),
'status' => $this->t('Published'),
'promote' => $this->t('Promoted to front page'),
'sticky' => $this->t('Sticky at top of lists'),
'revision' => $this->t('Create new revision'),
'language' => $this->t('Language (fr, en, ...)'),
'tnid' => $this->t('The translation set id for this node'),
'timestamp' => $this->t('The timestamp the latest revision of this node was created.'),
);
return $fields;
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['nid']['type'] = 'integer';
$ids['nid']['alias'] = 'n';
return $ids;
}
}
Repasando el código anterior, debemos tener en cuenta que para campos de tipo imagen en D7 se usa el atributo ‘fid’ para hacer referencia al id del archivo, en D8 el atributo es ‘target_id’.
Para campos tipo enlace en D7 se usaba el atributo ‘url’ ahora en Drupal 8 el atributo es ‘uri’, es por esto que volvemos a definir la estructura el arreglo.
Procedimientos para ejecutar la migración:
Habilitamos el módulo ‘custom_migration’ y sus dependencias:
$ drupal module:install migrate migrate_drupal custom_migration
Cargando migraciones:
$ drupal migrate:setup
Ejecutando la migración:
$ drupal migrate:execute
Luego de ingresar las credenciales de acceso a la base de datos de D7, especificamos los Ids de migración, en este caso debemos ejecutar la migración de archivos ‘d7_file’ y luego ‘custom_migration_node_page’.
Espero les sea útil este artículo. Si buscan más informacion de como ejecutar migraciones con la Drupal Console pueden ver éste artículo (inglés).