Mover conteúdo multilíngue com o módulo Migrar

12

Eu tenho uma única tabela MySQL com conteúdo misturado em inglês / francês em cada linha. Estou tentando descobrir como migrar isso para um site Drupal configurado no i18n.

Posso fazer o Migrate importar o conteúdo para um idioma, mas quero que ele seja importado para os dois idiomas. Existem 901 linhas, portanto, ele deve criar 1802 nós que estão vinculados.

Eu simplesmente não consigo descobrir como configurar o módulo Migrate para percorrer duas vezes e vincular os nós.

EDIT: Eu usei isso e foi capaz de mesclar os dois:

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
fonte
1
Não acho que você deva usar o postImport para adicionar seus nids traduzidos, o que prejudicará o mapeamento da migração (ou seja, você não poderá revertê-lo). Fazer isso como dois scripts de migração separados dentro do mesmo grupo seria a maneira certa de fazê-lo, e usar o método 'sourceMigration' permite adicionar o tnid à segunda migração para resolver a questão de vincular as traduções.
Alan Dixon

Respostas:

2

Você pode criar duas migrações, ambas com o mesmo mapeamento (exceto os nids), mas uma salva nós em inglês e a segunda em francês.

um sofá
fonte
1
É verdade, mas como faço para vincular os dois? Eu tenho um código difícil aqui, mas sei que é possível fazer tudo de uma vez. pastebin.com/ap1P5DGY Acho que os documentos aqui estão faltando alguma coisa para mim - drupal.org/node/1132582 - no prepareRow (), o que foi retornado? A vinculação pode ser feita com postImport ().
Mike Gifford
Eu tenho que fazer algumas migrações amanhã, então vou dar uma olhada. Eu acho que você precisa examinar o mapeamento entre as duas migrações, que possui um registro dos nids que foram importados e o ID do conteúdo original.
acouch
1

Em prepareRow () você retorna true ou false. Isso determina se essa linha é processada nessa migração específica (e contada mesmo).

Dessa maneira, você pode detectar o idioma de cada linha e retornar apenas TRUE para linhas que contenham conteúdo no idioma específico para a migração.

para que você possa fazer algo como:

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

Uma maneira ainda mais eficiente de fazer isso, se você fizer a migração dupla, seria adicionar uma condição () a cada consulta de origem (se você estiver usando MigrateSourceSQL), como -> condition ('lang', 'en', '=').

Rikki Schulte
fonte
1

(O seguinte se aplica ao Drupal 7 - não conheço o Drupal 6 ou anterior.)
Presumo que você queira definir a relação da tradução entre os nós inglês e francês. Para fazer isso, primeiro, cada nó deve ter o idioma definido, conforme definido em prepareRow():

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

Segundo, você precisa definir de alguma forma o tnidnó de origem como sendo seu nide o tnidnó de conversão como sendo o nidnó de origem. Observe que você pode escolher o idioma aleatório para o nó de origem e, portanto, é aceitável misturar o idioma de origem entre diferentes conteúdos. A questão é como.
(Observe que acho que é tudo o que você precisa, mas posso estar errado. Segui as etapas no segundo caso abaixo e obtive sucesso.)

Se você especificar explicitamente o número do nó (= nid) de cada linha em sua migração, será fácil, porque você sabe qual linha corresponde a qual nid, mesmo antes de importar esses nós. Portanto, você pode apenas definir tnidcada linha como tal. Obviamente, você deve tomar cuidado para não conflitar o importado nidcom nenhum dos nids existentes no conteúdo do Drupal.

Se você permitir que o Drupal decida o nidde cada linha importada, será mais complicado. Eu fiz com os 2 passos. Primeiro, importei todas as linhas do idioma de origem, adicionando um campo personalizado para identificá-lo como o nó de origem para uso posterior. Segundo, importei as linhas do idioma traduzido e configurei todos os tids dos nós de origem e do idioma traduzido. Essas duas etapas podem ser módulos completamente diferentes, mas talvez sejam mais úteis se você definir essas duas como classes separadas no mesmo grupo (migração) no varialbe $apino seu Your_ModuleName.migrate.inc.

Para o segundo passo para o idioma traduzido, escrevi da seguinte maneira. Em resumo, ele encontra o nó do idioma de origem com a consulta SQL, com base no campo personalizado field_original_html_filename, que foi definido quando foi importado.

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

Isso é tudo. Não estou surpreso se haveria uma maneira mais fácil ou melhor, mas funcionou para mim. De qualquer forma, uma vantagem de configurar as traduções durante a migração é que você sempre pode reverter. Como referência, todo o meu código de migração (para 2 idiomas, dos arquivos HTML estáticos) está disponível no GitHub:
https://github.com/masasakano/migrate_goo

Masa Sakano
fonte