I've just begun to tackle migrating a site from Drupal 6 to Drupal 7 via V2 of the Migrate module. It's truly an excellent module, but like most things Drupal, it has a steep learning curve. To help offset that slope, I plan to post migration snippets on this blog throughout the next few weeks. The snippets should help to serve as starting points for the many different migration scenarios that you all may encounter. Here is a short list of tentatively planned examples:
Please note that this is not a tutorial for the Migrate module. If you'd like a detailed explanation of the Migrate API, please check either the examples in the Migrate module, or read this excellent blog post on the migrate module.
<
p>It seems that the Address Field module has taken a strong lead in the realm on Drupal geolocation, so after a bit of research, I've decided to jump on the bandwagon. Here's a bare bones migration class that will query a base node table, join the necessary mapadelic location tables, and migrate them into an address field. Please note that you will require the Migrate Extras module to perform this migration.
<?php class grasmashNodeSericeProviderMigration extends Migration { public function __construct() { parent::__construct(); $this->description = t('Migrate location-based nodes.'); $this->dependencies = array('grasmashUser'); $this->map = new MigrateSQLMap($this->machineName, array( 'nid' => array( 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => 'D6 Unique Node ID', 'alias' => 'n', ) ), MigrateDestinationNode::getKeySchema() ); $query = db_select(GRASMASH_MIGRATION_DATABASE_NAME . '.node', 'n') ->fields('n', array('nid', 'vid', 'type', 'language', 'title', 'uid', 'status', 'created', 'changed', 'comment', 'promote', 'moderate', 'sticky', 'tnid', 'translate')) ->condition('n.type', 'service_provider', '='); $query->join(GRASMASH_MIGRATION_DATABASE_NAME . '.node_revisions', 'nr', 'n.vid = nr.vid'); $query->addField('nr', 'body'); $query->addField('nr', 'teaser'); $query->addField('nr', 'format'); $query->join(GRASMASH_MIGRATION_DATABASE_NAME . '.users', 'u', 'n.uid = u.uid'); $query->addField('u', 'name'); $query->leftjoin(GRASMASH_MIGRATION_DATABASE_NAME . '.location_instance', 'li', 'n.nid = li.nid AND n.vid = li.vid'); $query->addField('li', 'lid'); $query->leftjoin(GRASMASH_MIGRATION_DATABASE_NAME . '.location', 'l', 'li.lid = l.lid'); $query->addField('l', 'street'); $query->addField('l', 'additional'); $query->addField('l', 'city'); $query->addField('l', 'province'); $query->addField('l', 'postal_code'); $query->addField('l', 'country'); $query->addField('l', 'latitude'); $query->addField('l', 'longitude'); $query->orderBy('n.nid', 'ASC'); $source_fields = array( 'nid' => t('The node ID of the page'), 'uid' => t('The user ID of a user'), 'lid' => t('The location ID of a location instance'), ); $this->source = new MigrateSourceSQL($query, $source_fields); $this->destination = new MigrateDestinationNode('service_provider'); // Assign mappings TO destination fields FROM source fields. $this->addFieldMapping('is_new')->defaultValue(TRUE); $this->addFieldMapping('title', 'title'); $this->addFieldMapping('nid', 'nid'); $this->addFieldMapping('uid', 'uid'); $this->addFieldMapping('revision')->defaultValue(TRUE); $this->addFieldMapping('revision_uid', 'uid'); $this->addFieldMapping('created', 'created'); $this->addFieldMapping('changed', 'changed'); $this->addFieldMapping('status', 'status'); $this->addFieldMapping('promote', 'promote'); $this->addFieldMapping('sticky', 'sticky'); $this->addFieldMapping('comment', 'comment'); $this->addFieldMapping('path', 'url_alias'); $this->addFieldMapping('language')->defaultValue(LANGUAGE_NONE); // Map to addressfield. See addressfield.inc in migrate_extras for available argument keys. $arguments = array( 'thoroughfare' => array('source_field' => 'street'), 'premise' => array('source_field' => 'additional'), 'locality' => array('source_field' => 'city'), 'administrative_area' => array('source_field' => 'province'), 'postal_code' => array('source_field' => 'postal_code'), 'first_name' => array('source_field' => 'field_name_first'), 'last_name' => array('source_field' => 'field_name_last'), ); // Note that of the country field is NULL, none of the values will be migrated! $this->addFieldMapping('field_address', 'country')->arguments($arguments); // Since the excerpt is mapped via an argument, add a null mapping so it's not flagged as unmapped. $this->addFieldMapping(NULL, 'street'); $this->addFieldMapping(NULL, 'additional'); $this->addFieldMapping(NULL, 'city'); $this->addFieldMapping(NULL, 'province'); $this->addFieldMapping(NULL, 'postal_code'); $this->addFieldMapping(NULL, 'country'); $this->addFieldMapping(NULL, 'latitude'); $this->addFieldMapping(NULL, 'longitude'); $this->addFieldMapping(NULL, 'lid'); // The body text. $body_arguments = MigrateTextFieldHandler::arguments(array('source_field' => 'teaser'), array('source_field' => 'format')); $this->addFieldMapping('body', 'body')->arguments($body_arguments); // Unmapped source fields $this->addUnmigratedSources(array('vid', 'type', 'language', 'moderate', 'tnid', 'translate', 'teaser', 'format', 'name')); } public function prepareRow($current_row) { // Set the text format for the node. $current_row->format = 'wysiwyg_ckeditor'; return TRUE; } }
In addition to creating this migration class, I also added a quick strtoupper() wrapper to line 56 of addressfield.inc file, packaged with the migrate_extras module:
$return[$language][$delta] = array('country' => strtoupper($value)) + array_intersect_key($arguments, $field_info['columns']);
I'm fairly certain that this can be better accomplished with migrate's prepareRow() method, but I haven't had time to fool with it yet.
Good luck!

Comments
Brandonian
Mon, 02/27/2012 - 03:36
Permalink
Nice walkthrough of the
Nice walkthrough of the migration module. Technically, addressfield does not do geolocation by itself, it only holds postal addresses. A good way to actually place those addresses on a map is to use a combo of the geofield and geocoder modules. These two modules will populate your site with geocoded data which can be used to power either an Openlayers map (using the Openlayers module) or a simple google map.
Lars Olesen
Mon, 02/27/2012 - 05:25
Permalink
Why go from location to addressfield
Just curious why you choose to change the field?
madmatter23
Wed, 03/07/2012 - 20:58
Permalink
I chose to change it for a
I chose to change it for a few reasons:
There may be other reasons as well. I was primarily concerned about getting locked into using the Location module before seeing a stable, well supported release.
Ted
Fri, 12/14/2012 - 10:16
Permalink
thank you for your code drop
i was looking for some address migration code and this is very helpful
Add new comment