Verschieben Sie mehrsprachige Inhalte mit Migrate Module

12

Ich habe eine einzelne MySQL-Tabelle mit gemischtem Englisch / Französisch-Inhalt in jeder Zeile. Ich versuche herauszufinden, wie dies in eine ordnungsgemäße i18n-konfigurierte Drupal-Site migriert werden kann.

Ich kann Migrate veranlassen, den Inhalt in eine Sprache zu importieren, aber ich möchte, dass er in beide Sprachen importiert wird. Da 901 Zeilen vorhanden sind, sollten letztendlich 1802 Knoten erstellt werden, die verknüpft sind.

Ich kann einfach nicht herausfinden, wie das Migrate-Modul so eingerichtet wird, dass es zweimal durchläuft und die Knoten miteinander verbindet.

EDIT: Ich habe dies verwendet und konnte die beiden zusammenführen:

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
quelle
1
Ich denke nicht, dass Sie den postImport verwenden sollten, um Ihre übersetzten NIDs hinzuzufügen, da dies die Migrationszuordnung durcheinander bringt (dh Sie können kein Rollback durchführen). Wenn Sie es als zwei separate Migrationsskripte innerhalb derselben Gruppe ausführen, ist dies der richtige Weg. Mit der Methode 'sourceMigration' können Sie die tnid zur zweiten Migration hinzufügen, um die Frage der Verknüpfung der Übersetzungen zu lösen.
Alan Dixon

Antworten:

2

Sie können zwei Migrationen mit derselben Zuordnung erstellen (mit Ausnahme der NIDs), wobei eine die Knoten auf Englisch und die zweite auf Französisch speichert.

eine Couch
quelle
1
Stimmt, aber wie verbinde ich die beiden? Ich habe hier einen groben Code, aber ich weiß, dass es möglich ist, alles auf einmal zu tun. pastebin.com/ap1P5DGY Ich denke, in den Dokumenten hier fehlt etwas für mich - drupal.org/node/1132582 - in prepareRow (), was zurückgegeben wird. Die Verlinkung kann mit postImport () erfolgen.
Mike Gifford
Ich muss morgen ein paar Sachen migrieren, damit ich einen Blick darauf werfen kann. Ich denke, Sie müssen sich die Zuordnung zwischen den beiden Migrationen ansehen, die eine Aufzeichnung der importierten NIDs und der ursprünglichen Inhalts-ID enthält.
Akustik
1

In prepareRow () geben Sie entweder true oder false zurück. Dies bestimmt, ob diese Zeile in dieser bestimmten Migration verarbeitet wird (und sogar gezählt wird).

Auf diese Weise können Sie die Sprache für jede Zeile erkennen und nur TRUE für Zeilen zurückgeben, die Inhalte in der für diese Migration spezifischen Sprache enthalten.

so könnten Sie etwas tun wie:

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

Eine noch leistungsfähigere Möglichkeit, dies zu tun, besteht darin, jeder Quellabfrage eine Bedingung () hinzuzufügen (wenn Sie MigrateSourceSQL verwenden), z. B. -> Bedingung ('lang', 'en', '=').

Rikki Schulte
quelle
1

(Das Folgende gilt für Drupal 7 - ich kenne Drupal 6 noch nicht.) Ich gehe
davon aus, dass Sie das Übersetzungsverhältnis zwischen englischen und französischen Knoten definieren möchten. Zu diesem Zweck sollte jeder Knoten die in den folgenden Abschnitten definierte Sprache haben prepareRow():

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

Zweitens müssen Sie irgendwie den tniddes Quellknotens als seinen eigenen nidund den tniddes Übersetzungsknotens als den niddes Quellknotens definieren. Beachten Sie, dass Sie die Zufallssprache für den Quellknoten auswählen können und es daher sogar akzeptabel ist, die Quellsprache zwischen verschiedenen Inhalten zu mischen. Die Frage ist wie.
(Beachten Sie, ich denke, das ist alles, was Sie brauchen, aber ich könnte mich irren. Ich habe die Schritte im zweiten Fall unten befolgt und war erfolgreich.)

Wenn Sie die Knotennummer (= nid) jeder Zeile in Ihrer Migration explizit angeben , ist dies sehr einfach, da Sie nidbereits vor dem Importieren dieser Knoten wissen, welche Zeile welcher entspricht . Sie können also einfach tnidjede Zeile als solche festlegen . Natürlich müssen Sie darauf achten, dass keine Konflikte zwischen den importierten nidund den nidin Drupal vorhandenen Inhalten auftreten.

Wenn Sie Drupal über die Anzahl der nidimportierten Zeilen entscheiden lassen, ist dies schwieriger. Ich habe mit den 2 Schritten gemacht. Zuerst habe ich alle Zeilen in der Quellsprache importiert und ein benutzerdefiniertes Feld hinzugefügt, um es als Quellknoten für die spätere Verwendung zu identifizieren. Zweitens habe ich die übersetzten Sprachzeilen importiert und alle tids sowohl der Quellen- als auch der übersetzten Sprachknoten eingerichtet. Diese beiden Schritte können völlig unterschiedliche Module sein, sind jedoch möglicherweise praktischer, wenn Sie diese beiden als separate Klassen in derselben (Migrations-) Gruppe in der Variablen $apiin Ihrem Modul definieren Your_ModuleName.migrate.inc.

Für den zweiten Schritt für die übersetzte Sprache schrieb ich wie folgt. Kurz gesagt, es wird der quellensprachliche Knoten mit der SQL-Abfrage basierend auf dem benutzerdefinierten Feld gefunden field_original_html_filename, das beim Import definiert wurde.

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

Das ist alles. Ich bin nicht überrascht, ob es einen einfacheren oder besseren Weg gibt, aber es hat bei mir funktioniert. Ein Vorteil beim Einrichten der Übersetzungen während der Migration ist jedoch, dass Sie jederzeit ein Rollback durchführen können. Als Referenz ist mein gesamter Migrationscode (für 2 Sprachen, aus den statischen HTML-Dateien) bei GitHub verfügbar:
https://github.com/masasakano/migrate_goo

Masa Sakano
quelle