3

Actually I can migrate nodes depending on their type, and the author comes with node import like this in d2d :

$this->addFieldMapping('uid', 'uid');

but I don't know how to do the same to keep terms attached to nodes..I believe that in Drupal6 source, terms are frequently assigned from the core system, not via the content taxonomy module that represent the Drupal7 way.

Do you think I can do that actually, or do I need to modify the source and adopt the content taxonomy way before migrating nodes or generally upgrading from Drupal 6 to Drupal 7 ?

Thanks

EDIT: my migration class code

class NodesPageInnovationsMigration extends DrupalNode6Migration {
/* ==============================================================================
* -- Pour limiter l'import aux nodes créés aprés la date indiquée --
* 
* ==============================================================================
*/    
//protected function query() {
//    $query = parent::query();
//    $query->condition('created', strtotime('28-03-2013'), '>');
//    return $query;
// }
public function __construct(array $arguments) {
    parent::__construct($arguments);
    //Le nom machine de la migration de nodes associée comme dépendances
     // $this->dependencies[] = 'D2D_RostandNodes_PageInnovations';

    //On défini la source et la cible depuis les infos de base
      $this->source = new MigrateSourceSQL($this->query(),
      $this->sourceFields,NULL, $this->sourceOptions);


// We're replacing the legacy field_published, which was a text field, with a new date field
    $this->addFieldMapping('field_publish_date', 'field_published');

    //Préservation du NID des nodes importés
     $this->addFieldMapping('field_legacy_nid', 'nid')
         ->description('We have a common field to save the D6 nid');

    /* ==============================================================================
     * -- Mappage de la taxonomie --
     * Assigned terms are represented in Drupal 6 by their vid, migrate to the new term
     * reference field, translating the tid from the legacy value.
     * ==============================================================================
     */
     //$this->addFieldMapping('field_NomduChampCible', 'VidSource')
    //La taxonomie via champs custom ou du core (D6)
   // The first param is for the D7 field name.
    // The second param is for the old site's vocab ID.
    $this->addFieldMapping('taxonomy_vocabulary_1', '1')
        // ->sourceMigration('Tags') // This is the machine name of the tags migration.
         // This tells the migration to match on the term ID instead of the default, which is the term name.
         ->arguments(array('source_type' => 'tid'));

    $this->addFieldMapping('taxonomy_vocabulary_2', '2')
        // ->sourceMigration('Tags') // This is the machine name of the tags migration.
         // This tells the migration to match on the term ID instead of the default, which is the term name.
         ->arguments(array('source_type' => 'tid'));



   //$this->addFieldMapping('field_taxo_vdl', 'field_taxo_vdl'); inutile car dans D7 taxo est un champ

    /* ==============================================================================
     * -- Mappage des champs custom CCK --
     * $this->sourceFields['NomChampSource'] = t('DescriptionChampSource');
     * ==============================================================================
     */
//   $this->sourceFields['field_fichier_joint_lycee'] = t('Joindre un fichier');
//   $this->sourceFields['field_lien_page_lycee'] = t('Liens utiles');
//   $this->sourceFields['field_video_lycee'] = t('Ajout galerie Flickr');

   $this->addFieldMapping('field_video_externe', 'field_video_externe');
   $this->addFieldMapping('field_fichier_joint_innovation', 'field_fichier_joint_innovation');
   $this->addFieldMapping('field_fiche_action_innovation', 'field_fiche_action_innovation');
   $this->addFieldMapping('field_date_evenement', 'field_date_evenement');


   //Les champs custom pour les contenus VDL
   $this->addFieldMapping('field_illus_vdl', 'field_illus_vdl');
   $this->addFieldMapping('field_video_vdl', 'field_video_vdl');
   $this->addFieldMapping('field_galerie_image_vdl', 'field_galerie_image_vdl');
   $this->addFieldMapping('field_choix_galerie_vdl', 'field_choix_galerie_vdl');
   $this->addFieldMapping('field_liens_vdl', 'field_liens_vdl');

   //Correspondance des utilisateurs
   $this->addFieldMapping('uid', 'uid');   
   //$this->addFieldMapping('tnid', 'tnid'); traduction du terme



}
/* ==============================================================================
     * -- Manipulation et mise en forme des données des champs mappés --
     * 
     * ==============================================================================
     */
public function prepareRow($row) {
// Always include this snippet, in case our parent class decides to ignore the row
if (parent::prepareRow($row) === FALSE) {
   return FALSE;
}
//ici le code pour formatter les data
}
}
  • Can you not preserve the same nid during migration? – David Thomas Jun 17 '13 at 10:32
  • no,actually nodes are imported with a new nid – webmaster pf Jun 17 '13 at 11:47
  • @DavidThomas preserving nids is one of Drupal Unicorns, I'm afraid. webmaster pf - could you link what d2d is? – Mołot Jun 17 '13 at 11:56
  • 1
    @MyPalDrupal use drupal_write_record to write the node object with the nid set, prior to save. i.e drupal_write_record('node', $node); drupal_write_record('node_revision', $node);node_save($node); - this will preserve the nid – David Thomas Aug 14 '13 at 10:27
  • 1
    @MyPalDrupal no, if you've already migrated with that module, I assume it's created the nids for you. Maybe you can reset them after that, but that would all require custom code. – David Thomas Aug 15 '13 at 7:35
4

Check out all the examples for migrations in the migrate d2d handbook.

There is documentation on taxonomy term migrations and node migrations.

Put these together with the documentation for migrate.

Also, the migrate, migrate extras, and migrate d2d modules all have example modules in them, which have very useful example code. Specifically check out the example module in migrate_d2d, it has an example of this.

There is a lot of documentation there but that is because migration is a complicated task. The more you read and the better understanding you have the easier it is and the better the result.

After you have done a couple of migrations it gets much easier.

For nodes and their taxonomies, you migrate the terms first, then the nodes. The migrate module will keep track of the mapping of the old term id to the new term id, then when it comes to the nodes it will use that mapping for the terms attached to the nodes.

This is how you map a taxonomy field:

When you register your hooks:

// Each migration being registered takes an array of arguments, some required
// and some optional. Start with the common arguments required by all - the
// source_connection (connection key, set up in settings.php, pointing to
// the Drupal 6 database) and source_version (major version of Drupal).
$common_arguments = array(
  'source_connection' => 'legacy', // This is the name of a connection in your settings.php file.
  'source_version' => 6, // This is the source drupal version.
);

// Other migration registration here, like users & files.

// For vocabulary migrations, source_vocabulary and destination_vocabulary are
// required arguments. Note that in Drupal 6 vocabularies did not have machine
// names, so we use the vocabulary ID to uniquely identify them.
$vocabulary_arguments = array(
  array(
    'description' => t('Migration of Tags terms from Drupal 6'), // Description for this migration
    'machine_name' => 'Tags', // Migration machine name
    'source_vocabulary' => '5',  // Source vocabulary ID
    'destination_vocabulary' => 'tags', // Destination vocab machine name.
  ),
  array(
    'description' => t('Migration of Category terms from Drupal 6'), // Description for this migration
    'machine_name' => 'Category', // Migration machine name
    'source_vocabulary' => '6',  // Source vocabulary ID
    'destination_vocabulary' => 'category', // Destination vocab machine name.
  ),
  // More migrations for other vocabs.
);

// We're using the migrate_d2d class directly for all of the above.
// You can put other common params here.
$common_vocabulary_arguments = $common_arguments + array(
  'class_name' => 'DrupalTerm6Migration',
);
foreach ($vocabulary_arguments as $arguments) {
  $arguments += $common_vocabulary_arguments;
  // Register the migrations.
  Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
}


// Node migrations.
$node_arguments = array(
  array(
    'class_name' => 'PageMigrationClassName', //  The class name for this migration as we are extending a built in one.
    'description' => t('Migration of page nodes from Drupal 6'), // Description for this migration.
    'machine_name' => 'Page', // Machine name of this migration.
    'source_type' => 'page', // The node type in the old site.
    'destination_type' => 'page', // The node type in the new site.
    // Dependencies. This means this won't run until after the Tags & Category migrations have run.
    'dependencies' => array('Tags', 'Category'),
  ),
  // Other nnode migrations here.
);
foreach ($node_arguments as $arguments) {
  $arguments += $common_arguments;
  // Register the migrations.
  Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
}

Now in your page node migration code you would do:

class PageMigrationClassName extends DrupalNode6Migration{
  public function __construct(array $arguments) {
    parent::__construct($arguments);

    // Note that we map migrated terms by the vocabulary ID.
    // This is for the Tags vocab.
    // The first param is for the D7 field name.
    // The second param is for the old site's vocab ID.
    // This is how it is stored on the row, eg. $row->5
    $this->addFieldMapping('field_tags', '5')
         ->sourceMigration('Tags') // This is the machine name of the tags migration.
         // This tells the migration to match on the term ID instead of the default, which is the term name.
         ->arguments(array('source_type' => 'tid'));

    // And for the category vocab.
    $this->addFieldMapping('field_category', '6')
         ->sourceMigration('Category')
         ->arguments(array('source_type' => 'tid'));
  }
}

If you want to map the data to data that is already in the new system and wasn't migrated with the migrate module, there is probably a bunch of ways to do it. One way is to use the migrate API methods.

You can implement prepareRow() in your node migration class and do this:

public function prepareRow($row) {
  // Always include this fragment at the beginning of every prepareRow()
  // implementation, so parent classes can ignore rows.
  if (parent::prepareRow($row) === FALSE) {
    return FALSE;
  }

  // The node's terms are in an array under their vocab ID.
  if (!empty($row->{5})) {
    foreach ($row->{5} as &$tid) {
      // Code here to map term IDs from old to new.
      // Set $tid to the corresponding new site tid.
      // You could call a separate mapping function to do this if you have
      // a lot of terms or complex mapping requirements or something.
    }
  }
  return TRUE;
}

Alternatively, you can put the new tids somewhere else on the $row, like:

$row->mapped_tids_tags = array(3, 7, 4, 8, 6);

Then for your field mapper you have:

$this->addFieldMapping('field_tags', 'mapped_tids_tags')

Instead of:

$this->addFieldMapping('field_tags', '5')
| improve this answer | |
  • great explanation, but i did upgrade before import nodes via migrate d2d.so terms and vocabulary are already in the db.your second code could help me i guess,and i'm reading about examples include into the module folder.but actually i met troubles after updating modules (2.6 for migrate and 2.1 for d2d). – webmaster pf Jun 17 '13 at 13:26
  • i get this error : Migration failed with source plugin exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column f.field_fichier_joint_innovation_description' in 'field list' – webmaster pf Jun 17 '13 at 13:34
  • this error come from after updating the d2d module,it's a known issue – webmaster pf Jun 18 '13 at 7:57
  • I have added a part about manually mapping tids. – rooby Jun 18 '13 at 11:28
  • ok;i'm reading about the utility of prepareRow in my case and appear it's something needed to achieve nodes migration .But for now the error disallow me to run test so i run test onto my files migration – webmaster pf Jun 18 '13 at 13:26
0

achieve it with this code for d2d 2.1 and migrate 2.6 :

 $this->addFieldMapping('taxonomy_vocabulary_1', '1');
    // This tells the migration to match on the term ID instead of the default, which is the term name.
      $this->addFieldMapping('taxonomy_vocabulary_1:source_type')
     ->defaultValue('tid');

then terms already existing and created during core upgrade keep their node assignation.

| improve this answer | |
  • I also imported everything fine but without preserving the term association with migrated nodes. My question is can this be done after the migration ? If yes any pointers ? – MyPalDrupal Aug 12 '13 at 14:25
  • My previous answer before this one was posted already said this – rooby Oct 19 '13 at 0:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.