Przenieś zawartość wielojęzyczną za pomocą Migrate Module

12

Mam jeden stół MySQL z mieszaną treścią angielski / francuski w każdym rzędzie. Próbuję wymyślić, jak przeprowadzić migrację do odpowiedniej strony Drupal skonfigurowanej w i18n.

Mogę poprosić Migrate o zaimportowanie treści do jednego języka, ale chcę, aby zaimportowała je do obu języków. Istnieje 901 wierszy, więc powinno ostatecznie utworzyć 1802 połączonych węzłów.

Po prostu nie mogę wymyślić, jak skonfigurować moduł Migrate w celu dwukrotnego przejścia przez pętlę i połączenia węzłów.

EDYCJA: Użyłem tego i udało mi się połączyć dwa:

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
źródło
1
Nie sądzę, że powinieneś używać postImport, aby dodać przetłumaczone identyfikatory, które zepsułyby mapowanie migracji (tzn. Nie będziesz w stanie go przywrócić). Wykonanie tego jako dwóch osobnych skryptów migracji w tej samej grupie byłoby dobrym sposobem, aby to zrobić, a użycie metody „sourceMigration” pozwala dodać tnid do drugiej migracji, aby rozwiązać problem połączenia tłumaczeń.
Alan Dixon

Odpowiedzi:

2

Możesz utworzyć dwie migracje, obie z tym samym odwzorowaniem (oprócz nids), ale jeden zapisuje węzły w języku angielskim, a drugi w języku francuskim.

kanapa
źródło
1
To prawda, ale jak połączyć te dwa elementy? Mam tutaj trochę zgrubnego kodu, ale wiem, że można to zrobić naraz. pastebin.com/ap1P5DGY Myślę, że w dokumentach brakuje mi czegoś - drupal.org/node/1132582 - w przygotowaniuRow () co zostało zwrócone? Łączenie można wykonać za pomocą postImport ().
Mike Gifford,
Muszę jutro wykonać migrację, więc przyjrzę się. Myślę, że musisz spojrzeć na mapowanie między dwiema migracjami, które zawiera zapis zaimportowanych identyfikatorów i oryginalny identyfikator treści.
dotknąć
1

W preparRow () zwracana jest wartość true lub false. Określa, czy ten wiersz jest przetwarzany w tej konkretnej migracji (i nawet liczony).

W ten sposób możesz wykryć język dla każdego wiersza i zwracać PRAWDA tylko dla wierszy zawierających treść w określonym języku dla tej migracji.

więc możesz zrobić coś takiego:

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

Jeszcze bardziej wydajnym sposobem, aby to zrobić, jeśli zamierzasz wykonać podwójną migrację, byłoby dodanie warunku () do każdego zapytania źródłowego (jeśli używasz MigrateSourceSQL), takiego jak -> condition ('lang', „en”, „=”).

Rikki Schulte
źródło
1

(Poniższe informacje dotyczą Drupala 7 - nie wiem o Drupalu 6 lub wcześniej.)
Zakładam, że chcesz zdefiniować relację tłumaczenia między węzłami angielskim i francuskim. Aby to zrobić, najpierw każdy węzeł powinien mieć zdefiniowany język zdefiniowany w prepareRow():

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

Po drugie, musisz w jakiś sposób zdefiniować tnidwęzeł źródłowy, który ma być własny, nida tnidwęzeł translacji, aby był nidwęzłem źródłowym. Zauważ, że możesz wybrać losowy język dla węzła źródłowego, więc nawet mieszanie języka źródłowego pomiędzy różnymi treściami jest dopuszczalne. Pytanie brzmi jak.
(Uwaga: myślę, że to wszystko, czego potrzebujesz, ale mogę się mylić. Postępowałem zgodnie z instrukcjami w drugim przypadku poniżej i udało mi się.)

Jeśli wyraźnie podasz numer węzła (= nid) każdego wiersza podczas migracji, jest to łatwe, ponieważ wiesz, który wiersz odpowiada nid, nawet przed zaimportowaniem tych węzłów. Możesz więc po prostu ustawić tnidkażdy wiersz jako taki. Oczywiście, musisz uważać, aby nie konfliktować zaimportowanego nidz żadnym z istniejących elementów nidw zawartości Drupala.

Jeśli pozwolisz Drupalowi zdecydować nido każdym zaimportowanym wierszu, będzie to trudniejsze. Zrobiłem z 2 krokami. Najpierw zaimportowałem wszystkie wiersze w języku źródłowym, dodając niestandardowe pole w celu zidentyfikowania go jako węzła źródłowego do późniejszego wykorzystania. Po drugie, zaimportowałem wiersze przetłumaczonego języka i skonfigurowałem wszystkie tidwęzły zarówno źródłowego, jak i przetłumaczonego języka. Te dwa kroki mogą być zupełnie różne moduły, ale są chyba bardziej poręczne jeśli zdefiniowanie tych dwóch postaci odrębnych zajęć w tej samej grupie (migracji) w varialbe $apiw twojej Your_ModuleName.migrate.inc.

W drugim kroku dla przetłumaczonego języka napisałem w następujący sposób. Krótko mówiąc, wyszukuje węzeł języka źródłowego z zapytaniem SQL na podstawie niestandardowego pola field_original_html_filename, które zostało zdefiniowane podczas importowania.

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

To wszystko. Nie dziwię się, czy będzie łatwiejszy czy lepszy sposób, ale zadziałało to dla mnie. W każdym razie zaletą konfigurowania tłumaczeń podczas migracji jest to, że zawsze można je wycofać. Jako odniesienie cały mój kod migracji (dla 2 języków, ze statycznych plików HTML) jest dostępny na GitHub:
https://github.com/masasakano/migrate_goo

Masa Sakano
źródło