Déplacer du contenu multilingue avec le module Migrate

12

J'ai une seule table MySQL avec un contenu mixte anglais / français dans chaque ligne. J'essaie de comprendre comment migrer cela vers un site Drupal configuré correctement par i18n.

Je peux demander à Migrate d'importer le contenu dans une langue, mais je veux qu'il l'importe dans les deux langues. Il y a 901 lignes, il devrait donc finalement créer 1802 nœuds liés.

Je n'arrive pas à comprendre comment configurer le module Migrate pour boucler deux fois et relier les nœuds.

EDIT: J'ai utilisé cela et j'ai pu fusionner les deux:

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
la source
1
Je ne pense pas que vous devriez utiliser postImport pour ajouter vos nids traduits, cela gâchera le mappage de migration (c'est-à-dire que vous ne pourrez pas le restaurer). Le faire comme deux scripts de migration distincts dans le même groupe serait la bonne façon de le faire, et l'utilisation de la méthode 'sourceMigration' vous permet d'ajouter le tnid à la deuxième migration pour résoudre la question de la liaison des traductions entre elles.
Alan Dixon

Réponses:

2

Vous pouvez créer deux migrations, toutes deux avec le même mappage (à l'exception des nids), mais l'une enregistre les nœuds en anglais et la seconde en français.

un canapé
la source
1
Certes, mais comment lier les deux? J'ai un code approximatif ici, mais je sais qu'il est possible de tout faire en même temps. pastebin.com/ap1P5DGY Je pense que les documents manquent ici pour moi - drupal.org/node/1132582 - dans prepareRow () qu'est-ce qui est retourné? La liaison peut être effectuée avec postImport ().
Mike Gifford
Je dois faire des trucs de migration demain donc je vais y jeter un œil. Je pense que vous devez regarder le mappage entre les deux migrations qui a un enregistrement des nids qui ont été importés et l'identifiant de contenu d'origine.
acouch
1

Dans prepareRow (), vous retournez true ou false. Cela détermine si cette ligne est traitée dans cette migration particulière (et même comptée).

De cette façon, vous pouvez détecter la langue de chaque ligne et renvoyer VRAI uniquement pour les lignes qui contiennent du contenu dans la langue spécifique pour cette migration.

afin que vous puissiez faire quelque chose comme:

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;
}

Une façon encore plus performante de le faire, si vous voulez faire la double migration, serait d'ajouter une condition () à chaque requête source (si vous utilisez MigrateSourceSQL), comme -> condition ('lang', 'en', '=').

Rikki Schulte
la source
1

(Ce qui suit s'applique à Drupal 7 - je ne connais pas Drupal 6 ou avant.)
Je suppose que vous voulez définir la relation de traduction entre les nœuds anglais et français. Pour ce faire, tout d'abord, chaque nœud doit avoir le langage défini, tel que défini dans prepareRow():

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

Deuxièmement, vous devez en quelque sorte définir le tnidnœud source comme étant le sien nidet le tnidnœud de traduction être le nidnœud source. Notez que vous pouvez choisir la langue aléatoire pour le nœud source, et il est donc même acceptable de mélanger la langue source entre différents contenus. La question est de savoir comment.
(Notez que je pense que c'est tout ce dont vous avez besoin, mais je peux me tromper. J'ai suivi les étapes dans le deuxième cas ci-dessous, et j'ai réussi.)

Si vous spécifiez explicitement le numéro de nœud (= nid) de chaque ligne dans votre migration, alors c'est facile, car vous savez quelle ligne correspond à laquelle nid, avant même d'importer ces nœuds. Ainsi, vous pouvez simplement définir tnidchaque ligne comme telle. Évidemment, vous devez faire attention à ne pas entrer en conflit nidavec les nids existants dans le contenu Drupal.

Si vous laissez Drupal décider nidde chaque ligne importée, c'est plus délicat. Je l'ai fait avec les 2 étapes. Tout d'abord, j'ai importé toutes les lignes de la langue source, en ajoutant un champ personnalisé pour l'identifier comme nœud source pour une utilisation ultérieure. Deuxièmement, j'ai importé les lignes en langue traduite et configuré tous les tids des nœuds source et en langue traduite. Ces deux étapes peuvent être des modules complètement différents, mais sont peut-être plus pratiques si vous définissez ces deux en tant que classes distinctes dans le même groupe (migration) dans le varialbe $apide votre Your_ModuleName.migrate.inc.

Pour la deuxième étape de la langue traduite, j'ai écrit comme suit. En bref, il trouve le nœud de langue source avec la requête SQL, en fonction du champ personnalisé field_original_html_filename, qui a été défini lors de son importation.

// 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;
    }
  }

C'est tout. Je ne suis pas surpris s'il y aurait un moyen plus facile ou meilleur, mais cela a fonctionné pour moi. Quoi qu'il en soit, un avantage pour configurer les traductions pendant la migration est que vous pouvez toujours annuler. Comme référence, tout mon code de migration (pour 2 langues, à partir des fichiers HTML statiques) est disponible sur GitHub:
https://github.com/masasakano/migrate_goo

Masa Sakano
la source