i have the following data row :

ID, Name (English), Name(French)

how can i import into Drupal 7 node using Migrate in proper way so that if i rollback it rollback from all language etc etc.

if its not the right forum for this request please guide me in that case.

Thanks in advance.

Comments

rob_johnston’s picture

I would make 2 migrations, one for English and one for French. I would also set the French to be dependent on the English and then write a postImport() function on the French that makes translation sets. If anybody follows another pattern then I'd love to hear of it.

mikeryan’s picture

Status: Active » Postponed (maintainer needs more info)
Issue tags: -multilanguage migrate +multilingual migration

What would you like the result of the migration to be? If you want two nodes, an English node and a French node related in a translation set, then @rob_johnston's approach would be correct. If instead you want one node where the name field has an English value and a French value, it's a little trickier - you need to do some manipulation in prepareRow(), like:

$this->addFieldMapping('field_name', 'name');
$this->addFieldMapping('field_name:language', 'name_language');

public function prepareRow($row) {
  if (parent::prepareRow($row) === FALSE) {
    return FALSE;
  }
  // Assumes the source columns are english_name and french_name.
  $row->name = array($row->english_name, $row->french_name);
  $row->name_language = array('en', 'fr');

  return TRUE;
  }

I haven't done multilingual migration like this myself, so let me know if that doesn't work.

mikeryan’s picture

Status: Postponed (maintainer needs more info) » Closed (works as designed)
rob_johnston’s picture

Well as a last word, I can confirm that works, but you'll need something like this too:

  function complete($entity, stdClass $row) {

    // Add a translation into the system only if it exists.
    if (!is_null($entity->title_field['fr'][0]['value'])) {

      // Create a record for the french translation in the entity translation table.
      $nid = db_insert('entity_translation')
             ->fields(array(
                      'entity_type' => 'node',
                      'entity_id' => $entity->nid,
                      'language' => 'fr',
                      'source' => $entity->language,
                      'uid' => $entity->uid,
                      'status' => $entity->status,
                      'translate' => $entity->translate,
                      'created' => $entity->created,
                      'changed' => $entity->changed,
                     ))
             ->execute();
    }
  }
digitaldonkey’s picture

@mikeryanIs this the way it should work in D8 too?

digitaldonkey’s picture

In Drupal 8 it seems the multilingual import is not really working yet as designed.
I ended up implementing the MigrateEvents::POST_ROW_SAVE Event.
Maybe someone will find a way to multilingual migrations using the following:

donkeymedia_migrate/donkeymedia_migrate.services.yml

services:
  donkeymedia_migrate.donkeymedia_migrate_post_save:
    class: Drupal\donkeymedia_migrate\EventSubscriber\DonkeymediaMigratePostSave
    tags:
      - { name: event_subscriber }

donkeymedia_migrate/src/EventSubscriber/DonkeymediaMigratePostSave.php

<?php
/**
 * Migrate post row save event subscriber and handler.
 */

namespace Drupal\donkeymedia_migrate\EventSubscriber;

// This is the interface we are going to implement.
use \Symfony\Component\EventDispatcher\EventSubscriberInterface;
use \Drupal\migrate\Event\MigrateEvents;
// This class contains the event we want to subscribe to.
use \Symfony\Component\HttpKernel\Event\GetResponseEvent;

/**
 * Subscribe to MigrateEvents::POST_ROW_SAVE events.
 */
class DonkeymediaMigratePostSave implements EventSubscriberInterface {

  /**
   * {@inheritdoc}
   *
   * Publish the Event.
   */
  public static function getSubscribedEvents() {
    $events[MigrateEvents::POST_ROW_SAVE][] = array('updateTranslations');
    return $events;
  }

  /**
   * MigrateEvents::POST_ROW_SAVE event handler.
   *
   * @param GetResponseEvent $event
   *   Instance of Symfony\Component\HttpKernel\Event\GetResponseEvent.
   */
  public function updateTranslations(GetResponseEvent $event) {

    module_load_include('inc', 'donkeymedia_migrate', 'qtranslate_parser');

    $row =  $event->getRow();

    // These are defined in migration.yml.
    $available_languages = $row->getSource()['constants']['available_languages'];
    $default_language = $row->getDestination()['langcode'];

    // Unset default language from available langguages.
    if (($key = array_search($default_language, $available_languages)) !== false) {
      unset($available_languages[$key]);
    }

    $migrate_src_values = $row->getSource();
    $migrate_dest_values = $row->getDestination();

    $migrated_node = $event->destinationIdValues[0];
    $entity = node_load($migrated_node);

    // Get multilingual fields in all languages.
    $titles = qtrans_split($migrate_src_values['title'], $available_languages);
    $body_values = qtrans_split($migrate_src_values['content:encoded'], $available_languages);

    foreach ($available_languages as $lang) {

      $values = array(
        // Non multilingual.
        'created' => $migrate_dest_values['created'],
        'uid' => $migrate_dest_values['uid'],
        'sticky' => $migrate_dest_values['sticky'],
        'status' => $migrate_dest_values['status'],

        // Multilingual.
        'title' => $titles[$lang],
        'body' => array(
          'value' => $body_values[$lang],
          'format' => $migrate_dest_values['body']['format'],
        ),
      );
      $translated_entity = $entity->addTranslation($lang, $values);
      $translated_entity->setChangedTime($migrate_dest_values['changed']);
      $translated_entity->save();
    }

    $map = $event->getMigration()->getIdMap();

    $map->saveIdMapping($event->getRow(), array($migrated_node));
  }

}

I know this is the kind of the wrong place to publish this, but repeatedly ended up here searching for solutions.

digitaldonkey’s picture

Issue tags: -multilingual migration +multilingual migration drupal8
star-szr’s picture

Issue tags: -multilingual migration drupal8
Related issues: +#929402: Add support for migrate module
mpp’s picture

@digitaldonkey have you found a better way of doing it for Drupal 8?

edit: This is how core handles multilingual migrations for Drupal 8: https://www.drupal.org/node/2225775

caspervoogt’s picture

@digitaldonkey what version of Drupal core did your code work with? I tried it on 8.1.7-dev and it caused some fatal errors, so then I tried with 8.0.0 and 8.0.1 and also no luck.