Hola!. Todos los post que escribí hasta ahora sobre Migrate se debieron a que quería hacer esto.
Hoy les presento una clase basada en Migrate para importar productos a Drupal Commerce y crear al mismo tiempo un product display.
NOTA: los múltiples productos para un solo product display lo dejamos para otro día
Un poco de intro
- Necesitamos el modulo Commerce Migrate para poder crear productos con Migrate.
- El machine name del tipo de producto que vamos a importar se llama “gorras“
- El machine name del product display que vamos a importar se llama “display_gorra“
- Indistintamente del formato a importar (xml, json, csv) existen dos clases linkeadas: la que crea el producto y la que crea el porduct display y asigna el producto creado.
- La fuente de información para cada una de las clases es la misma siempre, solo que cada clase toma lo que necesita.
- El linkeo entre clases se hace referenciando el machine name que usaste para registrar la clase (machine-name != class name). Si no lo tenés claro lee este post
Bueno vamos a hacer una cosa, en lugar de repetir las dos clases necesarias para la importación por cada tipo de source, voy a dejar aqui solo la que importa CSV, porque el resto de las clases funcionan practicamente igual, y seria repetir en vano.
LAS CLASES
<?php
/**
* Class ProductFromCSV
* Crea el producto
* machine-name: product-from-csv
*/
class ProductFromCSV extends Migration {
public function __construct($arguments) {
parent::__construct($arguments);
$csv_path = "/path/hasta/el/csv/exported.csv";
$columns = array(
0 => array('identificador', 'Identificador'),
1 => array('titulo', 'Post date'),
2 => array('precio', 'Precio'),
3 => array('moneda', 'Moneda'),
4 => array('categoria', 'Categoría'),
);
$this->source = new MigrateSourceCSV($csv_path, $columns, array('embedded_newlines' => TRUE, "track_changes" => TRUE));
$this->destination = new MigrateDestinationEntityAPI('commerce_product', 'gorras');
$this->map = new MigrateSQLMap($this->machineName,
array(
'identificador' => array(
'type' => 'varchar',
'length' => 20,
'not null' => TRUE,
),
),
$this->destination->getKeySchema()
);
global $user;
$this->addFieldMapping('title', 'titulo');
$this->addFieldMapping('commerce_price', 'precio')->defaultValue(0);
$this->addFieldMapping('commerce_price:currency_code', 'moneda')->defaultValue(commerce_default_currency());
$this->addFieldMapping('sku', 'identificador');
$this->addFieldMapping('status')->defaultValue(1);
$this->addFieldMapping('uid')->defaultValue($user->uid);
$this->addFieldMapping('field_categoria', 'categoria')->defaultValue("General");
}
}
/**
* Class ProductDisplayFromCSV
* Crea product displays (de momento solo pueden crear relaciones 1-1)
* machine-name: product-display-from-csv
*/
class ProductDisplayFromCSV extends Migration {
public function __construct($arguments) {
parent::__construct($arguments);
$csv_path = "/path/hasta/el/csv/exported.csv";
//Suponiendo que la clase la has registrado bajo este nombre :D
$product_machine_name = 'product-from-csv';
$columns = array(
0 => array('identificador', 'Identificador'),
1 => array('titulo', 'Post date'),
);
$this->source = new MigrateSourceCSV($csv_path, $columns, array('embedded_newlines' => TRUE, "track_changes" => TRUE));
$this->dependencies = array($product_machine_name);
$this->destination = new MigrateDestinationNode('display_gorra');
$this->map = new MigrateSQLMap($this->machineName,
array(
'identificador' => array(
'type' => 'varchar',
'length' => 20,
'not null' => TRUE,
),
),
$this->destination->getKeySchema()
);
global $user;
$this->addFieldMapping('uid')->defaultValue($user->uid);
$this->addFieldMapping('title', 'titulo');
$this->addFieldMapping('field_product', "identificador")->sourceMigration($product_machine_name);
}
}
Lo importante aquí es notar que la segunda clase “dice” que depende de la primera al indicar $this->dependencies = array($product_machine_name);. De esta forma, Migrate sabe que la segunda clase no se puede poner a importar hasta que el primer migrador haya sido procesado.
Y para establecer la relación con el producto creado asociamos el field “field_product” al identificador que a su vez lo obtiene de la relación que Migrate estableció en una tabla en la DB (relación identificador del CSV < -> commerce product ID) por medio de ->sourceMigration()
Uso:
La verdad que fui un iluso cuando pensé que por estar linkeadas, las clases se iban a ejecutar en cadena :S La realidad es que siguen siendo migrators independientes con la salvedad de que hay que ejecutarlos en orden:
drush mi product-from-csv
Y recién ahora podemos invocar al migrator que crea los product display:
drush mi product-display-from-csv
That’s all.
Chau!