Combo: Importar y sincronizar productos con Migrate + Drupal commerce + product display desde CSV/XML/JSON
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
/** * 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:
1 |
drush mi product-from-csv |
Y recién ahora podemos invocar al migrator que crea los product display:
1 |
drush mi product-display-from-csv |
That’s all.
Chau!