使用迁移模块移动多语言内容


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添加翻译后的图片,这会弄乱迁移映射(即您将无法回滚)。将其作为同一组中的两个单独的迁移脚本来进行是正确的方法,并且使用“ sourceMigration”方法可以将tnid添加到第二个迁移中,以解决将翻译链接在一起的问题。
艾伦·迪克森

Answers:


2

您可以创建两个迁移,它们都具有相同的映射(nids除外),但是一个迁移用英语保存节点,第二个用法语保存节点。


1
是的,但是我该如何链接两者呢?我这里有一些粗略的代码,但我知道可以一次完成所有操作。pastebin.com/ap1P5DGY 我认为这里的文档丢失了我的东西- drupal.org/node/1132582 -在prepareRow()所返回什么?可以使用postImport()进行链接。
Mike Gifford

我明天必须做一些迁移工作,所以我来看一下。我认为您需要查看两次迁移之间的映射,该映射具有已导入的nid记录和原始内容ID的记录。
acouch 2012年

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

如果要执行双重迁移,一种更高效的方法是在每个源查询中添加一个condition()(如果使用的是MigrateSourceSQL),例如-> condition('lang', 'en','=')。


1

(以下内容适用于Drupal 7 –我不了解Drupal 6或之前的版本。)
我假设您想定义英语和法语节点之间的翻译关系。为此,首先,每个节点应具有定义的语言,如prepareRow()

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

其次,您需要以某种方式将tnid源节点的定义为它自己nidtnid,并将转换节点nid的定义为源节点的。请注意,您可以为源节点选择随机语言,因此甚至可以在不同内容之间混合源语言。问题是如何。
(请注意,我认为这是您所需要的,但我可能错了。我按照下面第二种情况的步骤操作,并成功完成了此操作。)

如果您nid在迁移中明确指定每行的节点号(= ),那么这很容易,因为nid即使在导入这些节点之前,您也知道哪一行对应于哪一行。因此,您可以这样设置tnid每一行。显然,您必须注意不要将导入的内容与Drupal内容中的nid任何现有nids 冲突。

如果让Drupal决定nid每个导入的行的标题,那将更加棘手。我做了两个步骤。首先,我导入了所有源语言行,并添加了一个自定义字段以将其标识为源节点,以供以后使用。其次,我导入了翻译语言行并设置了tid源节点和翻译语言节点的所有。这两个步骤可以是完全不同的模块,但是如果您在varialbe $api中的同一(迁移)组中将这两个类定义为单独的类,则可能会更方便Your_ModuleName.migrate.inc

对于翻译语言的第二步,我编写如下。简而言之,它基于field_original_html_filename导入时定义的custom字段,找到带有SQL查询的源语言节点。

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

就这些。如果有更简便或更好的方法,我并不感到惊讶,但是它对我有用。无论如何,在迁移过程中设置翻译的一个优势是您总是可以回滚。作为参考,我的整个迁移代码(用于两种语言,来自静态HTML文件)可在GitHub上获得:https :
//github.com/masasakano/migrate_goo

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.