Mover contenido multilingüe con el módulo Migrate

12

Tengo una sola tabla MySQL con contenido mixto de inglés / francés en cada fila. Estoy tratando de averiguar cómo migrar esto a un sitio Drupal configurado con i18n adecuado.

Puedo hacer que Migrate importe el contenido a un idioma, pero quiero que lo importe a ambos idiomas. Hay 901 filas, por lo que en última instancia debería crear 1802 nodos que están vinculados.

Simplemente no puedo entender cómo configurar el módulo Migrate para recorrer dos veces y vincular los nodos.

EDITAR: Usé esto y pude fusionar los dos:

public function postImport() {
parent::postImport();

// $ii should really be determined by $count_query
$ii = 2000;
for ($i = 1; $i < $ii; $i++) {
  // Confirm SQL in phpMyAdmin to verify
  $query = "SELECT n.nid, tid.field_bv_transfer_id_value
    FROM {field_revision_field_bv_transfer_id} tid
    INNER JOIN node n ON tid.entity_id = n.nid
    WHERE tid.field_bv_transfer_id_value = $i;";
  $result = db_query($query);

  // Reset for each import
  $currentRowCount = $current_translateid = 0;
  foreach ($result as $record) {
    if ($currentRowCount % 2 == 0) {
      $node = node_load($record->nid);
      $node->pathauto_perform_alias = FALSE;
      $node->tnid = $record->nid;
      $current_translateid = $record->nid;
      node_save($node);
    } else {
      $node = node_load($record->nid);
      $node->pathauto_perform_alias = FALSE;
      $node->tnid = $current_translateid;
      node_save($node);
    }
    $currentRowCount++;
  }
}

}

Mike Gifford
fuente
1
No creo que deba usar postImport para agregar sus nid traducidos, eso arruinará la asignación de migración (es decir, no podrá revertirla). Hacerlo como dos scripts de migración separados dentro del mismo grupo sería la forma correcta de hacerlo, y usar el método 'sourceMigration' le permite agregar el tnid a la segunda migración para resolver la cuestión de vincular las traducciones.
Alan Dixon

Respuestas:

2

Puede crear dos migraciones, ambas con la misma asignación (excepto los nids), pero una guarda los nodos en inglés y la segunda en francés.

un entrenador
fuente
1
Es cierto, pero ¿cómo puedo vincular los dos? Tengo un código aproximado aquí, pero sé que es posible hacerlo todo de una vez. pastebin.com/ap1P5DGY Creo que los documentos aquí me faltan algo - drupal.org/node/1132582 - en prepareRow () ¿qué se devuelve? El enlace se puede hacer con postImport ().
Mike Gifford
Tengo que hacer algunas cosas de migración mañana, así que echaré un vistazo. Creo que debe mirar el mapeo entre las dos migraciones que tiene un registro de los nidos que se han importado y la identificación de contenido original.
acouch
1

En prepareRow () devuelve verdadero o falso. Esto determina si esa fila se procesa en esa migración en particular (y se cuenta incluso).

De esta manera, puede detectar el idioma para cada fila y solo devolver VERDADERO para las filas que contienen contenido en el idioma específico para esa migración.

para que puedas hacer algo como:

public function prepareRow($row){
  $return = FALSE
  if ($row->lang == "fr"){
   $return = TRUE;
  }
  // Only rows with a source 'lang' value of 'fr' are processed
  return $return;
}

Una forma aún más eficaz de hacer esto, si va a hacer las migraciones duales, sería agregar una condición () a cada consulta de origen (si está utilizando MigrateSourceSQL), como -> condition ('lang', 'en', '=').

Rikki Schulte
fuente
1

(Lo siguiente se aplica a Drupal 7: no sé sobre Drupal 6 o antes).
Supongo que desea definir la relación de traducción entre los nodos inglés y francés. Para hacer eso, primero, cada nodo debe tener el lenguaje definido, como se define en prepareRow():

$this->addFieldMapping('language', 'language_code');
$row->lang_dest = 'fr'; // or "en", depending on the row.

En segundo lugar, debe definir de alguna manera el tnidnodo de origen como propio nidy el tnidnodo de traducción como el nodo nidde origen. Tenga en cuenta que puede elegir el idioma aleatorio para el nodo de origen, por lo que incluso es aceptable mezclar el idioma de origen entre diferentes contenidos. La pregunta es cómo.
(Tenga en cuenta que creo que eso es todo lo que necesita, pero podría estar equivocado. Seguí los pasos en el segundo caso a continuación y lo logré).

Si especifica explícitamente el número de nodo (= nid) de cada fila en su migración, entonces es fácil, porque sabe qué fila corresponde a cuál nid, incluso antes de importar esos nodos. Por lo tanto, puede configurar tnidcada fila como tal. Obviamente, debe tener cuidado de no poner en conflicto lo importado nidcon ninguno de los nids existentes en el contenido de Drupal.

Si deja que Drupal decida el nidde cada fila importada, entonces es más complicado. Lo hice con los 2 pasos. Primero, importé todas las filas del idioma de origen, agregando un campo personalizado para identificarlo como el nodo de origen para el uso posterior. En segundo lugar, importé las filas del idioma traducido y configuré todos los tidnodos tanto del origen como de los nodos traducidos. Estos dos pasos pueden ser módulos completamente diferentes, pero tal vez sean más útiles si define esos dos como clases separadas en el mismo grupo (migración) en el varialbe $apien su Your_ModuleName.migrate.inc.

Para el segundo paso para el idioma traducido, escribí lo siguiente. En resumen, encuentra el nodo del idioma de origen con la consulta SQL, en función del campo personalizado field_original_html_filename, que se definió cuando se importó.

// In prepareRow()
//   Set up tnid, obtaining the nid from the node already imported.
    $this->addFieldMapping('tnid', 'row_tnid');
    //
    $field_name = 'field_original_html_filename';
    $query = sprintf("SELECT n.entity_id FROM {field_data_%s} n WHERE n.%s_value = '%s'",
                     $field_name, $field_name, $fbasename_trans);     // entity_id == nid of Node
    $result = db_query($query);
    $nid_trans = $result->fetchCol()[0];
    $row->row_tnid = $nid_trans;      // In my case, it is guaranteed there is only one candidate.

// In prepare()
//   Forcibly set up (Change) tnid of the node already imported.
  public function prepare(&$node, $row) {
    if (isset($node->tnid) && ($source = node_load($node->tnid))) {
      $node->translation_source = $source;
    }
  }

Eso es todo. No me sorprende si habría una manera más fácil o mejor, pero funcionó para mí. De todos modos, una ventaja para configurar las traducciones durante la migración es que siempre puede revertir. Como referencia, todo mi código de migración (para 2 idiomas, desde los archivos HTML estáticos) está disponible en GitHub:
https://github.com/masasakano/migrate_goo

Masa Sakano
fuente