Перемещение многоязычного контента с модулем миграции

12

У меня есть одна таблица MySQL со смешанным английским / французским контентом в каждой строке. Я пытаюсь понять, как перенести это на правильно настроенный i18n сайт Drupal.

Я могу заставить Migrate импортировать контент на один язык, но я хочу, чтобы он импортировал его на оба языка. Есть 901 рядов, поэтому в конечном итоге следует создать 1802 связанных узлов.

Я просто не могу понять, как настроить модуль Migrate, чтобы дважды проходить и связывать узлы.

РЕДАКТИРОВАТЬ: Я использовал это и смог объединить два:

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

}

Майк Гиффорд
источник
1
Я не думаю, что вы должны использовать postImport для добавления ваших переведенных nids, которые испортят отображение миграции (т.е. вы не сможете откатить его обратно). Выполнение этого в виде двух отдельных сценариев переноса в одной и той же группе было бы правильным способом, а использование метода sourceMigration позволяет добавить tnid во вторую миграцию, чтобы решить вопрос о связывании переводов.
Алан Диксон

Ответы:

2

Вы можете создать две миграции, обе с одинаковым отображением (за исключением nids), но одна сохраняет узлы на английском языке, а вторая - на французском.

Диван
источник
1
Правда, но как мне связать два? У меня здесь грубый код, но я знаю, что можно сделать все сразу. pastebin.com/ap1P5DGY Я думаю, что в моих документах чего-то не хватает - drupal.org/node/1132582 - в prepareRow () что возвращается? Связывание может быть сделано с помощью postImport ().
Майк Гиффорд
Завтра мне нужно будет что-нибудь перенести, поэтому я посмотрю. Я думаю, что вам нужно взглянуть на соответствие между двумя миграциями, в котором есть запись импортированных nids и исходный идентификатор контента.
Acouch
1

В prepareRow () вы возвращаете либо true, либо false. Это определяет, обрабатывается ли эта строка в этой конкретной миграции (и считается ли она четной).

Таким образом, вы можете определить язык для каждой строки и возвращать TRUE только для строк, содержащих контент на определенном языке для этой миграции.

так что вы можете сделать что-то вроде:

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

Еще более эффективный способ сделать это, если вы собираетесь выполнить двойную миграцию, это добавить условие () к каждому исходному запросу (если вы используете MigrateSourceSQL), например, -> условие ('lang', 'ан', '=').

Рикки Шульте
источник
1

(Следующее относится к Drupal 7 - я не знаю о Drupal 6 или ранее.)
Я предполагаю, что вы хотите определить отношение перевода между английскими и французскими узлами. Для этого, во-первых, каждый узел должен иметь определенный язык, как определено в prepareRow():

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

Во-вторых, вам нужно каким-то образом определить tnidисходный узел как собственный nidи tnidузел перевода nidкак исходный узел. Обратите внимание, что вы можете выбрать произвольный язык для исходного узла, и поэтому даже допустимо смешивать исходный язык между различным содержимым. Вопрос в том, как.
(Обратите внимание, я думаю, что это все, что вам нужно, но я могу ошибаться. Я выполнил действия во втором случае ниже и преуспел.)

Если вы явно укажете номер узла (= nid) каждой строки в своей миграции, это будет легко, поскольку вы знаете, какой строке какая строка соответствует nid, даже до импорта этих узлов. Таким образом, вы можете просто установить tnidкаждый ряд как таковой. Очевидно, вы должны быть осторожны, чтобы не вступать в конфликт импортированных nidс любым из существующих nidв содержимом Drupal.

Если вы разрешите Drupal определять nidкаждую импортированную строку, то это будет сложнее. Я сделал с 2 шага. Сначала я импортировал все строки исходного языка, добавив настраиваемое поле, чтобы идентифицировать его как узел источника для последующего использования. Во-вторых, я импортировал строки с переведенным языком и настроил все tidузлы как исходного, так и переведенного языка. Эти шаги могут быть совершенно разные модули, но, возможно , сподручнее , если вы определили эти два , как отдельные классы в одной и той же (миграция) группы в varialbe $apiв вашей Your_ModuleName.migrate.inc.

Для второго шага для переведенного языка я написал следующее. Короче говоря, он находит узел исходного языка с запросом SQL на основе настраиваемого поля field_original_html_filename, которое было определено при его импорте.

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

Это все. Я не удивлен, если бы был более легкий или лучший способ, но это сработало для меня. В любом случае, преимущество при настройке переводов во время миграции заключается в том, что вы всегда можете выполнить откат. В качестве ссылки весь мой код миграции (для 2 языков, из статических файлов HTML) доступен на GitHub:
https://github.com/masasakano/migrate_goo

Маса Сакано
источник