El tema de la migración de datos de un archivo CSV ha sido de mucho interés para MTech y para el proceso de desarrollo, si tú aún no te has familiarizado con este tipo de migración, te invito a que eches un vistazo a nuestros blogs anteriores acerca de ello: Migrar usando CSV.
NOTA: Nuestros módulos personalizados son generados a través de Drupal Console
Ahora podemos entrar de lleno a lo que será está migración. En primer lugar previamente tenemos en existencia 2 módulos personalizados para cada tipo de migración CSV, en este caso program_migrate
con nuestro archivo yaml migrate_plus.migration.program_csv.yml
que sería este:
langcode: en
status: true
dependencies:
enforced:
module:
- program_migrate
id: program_csv
label: Program CSV file migration
migration_tags:
- CSV
source:
plugin: csv
path: 'public://csv/programs.csv'
header_row_count: 1
keys:
- "Program Name"
process:
type:
plugin: default_value
default_value: course
uid:
plugin: default_value
default_value: 1
title: Long Title
field_short_title: Short Title
body: Description
field_program_id: Program Name
field_program_status: Current Program Status
field_program_transfer_status: Transfer Status
destination:
plugin: entity:node
migration_dependencies:
required: {}
optional: {}
y el otro módulo reward_migrate
con el archivo yaml migrate_plus.migration.reward_csv.yml:
langcode: en
status: true
dependencies:
enforced:
module:
- reward_migrate
id: reward_csv
label: Award CSV file migration
migration_tags:
- CSV
source:
plugin: csv
path: 'public://csv/rewards.csv'
header_row_count: 1
keys:
- id
process:
type:
plugin: default_value
default_value: award
uid:
plugin: default_value
default_value: 1
title: name
body: description
field_award_application_deadline: applicationDeadline
field_award_id: id
field_award_category: category
field_award_value: value
field_number_awarded: numberAwarded
destination:
plugin: entity:node
migration_dependencies:
required: {}
optional: {}
Crearemos un tercer módulo personalizado prueba_import
y en nuestro archivo prueba_import.info.yml
las dependencias serán nuestros módulos anteriores: program_migrate
y reward_migrate
.
Con Drupal Console vamos a generar nuestra formulario con el comando $ drupal generate:form
<?php
namespace Drupal\prueba_import\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\prueba_import\PruebaMigrateMessage;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate\Plugin\Migration;
use Drupal\migrate\Plugin\MigrationInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\migrate\Plugin\MigrationPluginManager;
/**
* Class ImportForm.
*
* @package Drupal\prueba_import\Form
*/
class ImportForm extends FormBase {
/**
* Drupal\migrate\Plugin\MigrationPluginManager definition.
*
* @var \Drupal\migrate\Plugin\MigrationPluginManager
*/
protected $pluginManagerMigration;
/**
* Constructs a new ImportForm object.
*/
public function __construct(
MigrationPluginManager $plugin_manager_migration
) {
$this->pluginManagerMigration = $plugin_manager_migration;
}
public static function create(ContainerInterface $container) {
return new static(
$container->get('plugin.manager.migration')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'import_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['type_of_csv'] = [
'#type' => 'select',
'#title' => $this->t('Type of CSV'),
'#options' => [
'reward' => $this->t('Rewards'),
'program' => $this->t('Programs')
],
'#size' => 1,
];
$form['upload_csv'] = [
'#type' => 'file',
'#title' => $this->t('Upload CSV'),
];
$form['update_existing_records'] = [
'#type' => 'checkbox',
'#title' => $this->t('Update existing records'),
'#default_value' => 1,
];
$form['import'] = [
'#type' => 'submit',
'#value' => $this->t('Import'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$validators = ['file_validate_extensions' => ['csv']];
$file = file_save_upload('upload_csv', $validators, FALSE, 0);
if (isset($file)) {
// File upload was attempted.
if ($file) {
$form_state->setValue('csv_path', $file->getFileUri());
}
else {
// File upload failed.
$form_state->setErrorByName('upload_csv', $this->t('The CSV file could not be uploaded.'));
}
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$migration = 'reward_csv';
switch ($form_state->getValue('type_of_csv')) {
case 'reward':
$migration = 'reward_csv';
break;
case 'program':
$migration = 'program_csv';
break;
}
/** @var Migration $migrationInstance */
$definition = $this->pluginManagerMigration->getDefinition($migration);
// Alter source file path from validator above.
$definition['source']['path'] = $form_state->getValue('csv_path') ;
$migrationInstance = $this->pluginManagerMigration->createStubMigration($definition);
// Reset status.
$status = $migrationInstance->getStatus();
if ($status != MigrationInterface::STATUS_IDLE) {
$migrationInstance->setStatus(MigrationInterface::STATUS_IDLE);
drupal_set_message($this->t('Migration @id reset to Idle', ['@id' => $migration]), 'warning');
}
// Force updates or not.
if ($form_state->getValue('update_existing_records')) {
$migrationInstance->getIdMap()->prepareUpdate();
}
$executable = new MigrateExecutable($migrationInstance, new PruebaMigrateMessage());
$result = $executable->import();
if ($result == MigrationInterface::RESULT_COMPLETED) {
drupal_set_message($this->t('Import was successful'));
}
else {
drupal_set_message($this->t('The import was not successful, please review logs.'));
}
}
}
y creamos la clase personalizada PruebaMigrateMessage.php
:
<?php
namespace Drupal\prueba_import;
use Drupal\migrate\MigrateMessageInterface;
class PruebaMigrateMessage implements MigrateMessageInterface {
/**
* Output a message from the migration.
*
* @param string $message
* The message to display.
* @param string $type
* The type of message to display.
*
* @see drupal_set_message()
*/
public function display($message, $type = 'status') {
drupal_set_message($message, $type);
}
}
Siempre con el uso de Drupal Console generamos dos nuevos archivos necesarios para la migración; routing y permissions.
Puedes obtener el código completo en git!
¿Está buscando ayuda para una migración o actualización de Drupal? Independientemente de la complejidad del sitio o de los datos, MTech puede ayudarle a pasar de un CMS privado o actualizarlo a la última versión: Drupal 8.
Escríbanos sobre su proyecto y nos pondremos en contacto con usted dentro de 48 horas.