Please leave this field empty.

Thanks! We'll send you Awesome Tips.
X

Learn

from our mind to yours

How to Migrate database content to Drupal 7

May 29, 2014Payman Taei

Migration to Drupal
This post is based on some of our experience on a few recent projects that entailed migration from both third party CMS systems and older versions of Drupal (Drupal 6 or earlier).

 
We often write about business tips and importance of design. In this article we’re going to touch on a back-end topic that may seem a bit boring to most but a goldmine for new developers making a transition to Drupal and migrating data to it.

 
Migrating content from one Content Management System (CMS) to Drupal can be prove to be a challenging task. In some cases the migration is simple when there is a small and simple batch of data but in presence of large loads of data or migration from an old version of Drupal or other CMS systems with variation in data formatting can prove more daunting.

 
At our Web Consulting company HindSite Interactive, where website redesigns count for a noticeable portion of our work load, we have faced the data migration issue a number of times. As a result we wanted to write a post to provide an example of migration and the challenges we faced and perhaps it will help you through on similar projects in the future.

 
Most of our migrations are performed with a Drupal module called Migrate which provides a flexible and powerful framework for migrating content.

 

The goal is to give you some easy explanations/example on how to use the Migrate Module.
We recently worked on a fairly large non-profit organization’s web presence where we fully revamped and migrated the 10 year old site to Drupal 7.

In this article, we will show you how to migrate from a popular CMS called TypePad to Drupal 7.

 

Although there are a few different ways of achieving this, we decided to use the Migrate module. Once you get the hang of it it can prove to be the the easiest way to achieve future migrations to Drupal.


Note:
There is also another module on Drupal 6 called “Import TypePad / Moveable Type” that lets you import data from TypePad. This is a good choice if the data you want to move is not complex. In our case Migrate module was the more feasible option.

The Migrate module documentation is available here. Additionally when you install Migrate module on your website, there is an example migration module included in the documentation but it is nonetheless quite confusing.

Let’s get started:

I. Installation Module

First thing you need to do is to install the Migrate module on your website as a regular module. This module provides you with an API that we are going to use, but it also provides a set of drush commands for running migration processes and a user interface module that provides visual status and details on defined migrations. Althought it is not recommended, throughout this tutorial we will utilize the user interface module; We believe it’s easier to start.

II. Create Your Own Module

Once you are done with the installation, you have to create your own module. You can name it to for example: migrate_typepad.
Here is the code for your info file:

[code language=”php”]
name = “Migrate from TypePad”
description = “Module to migrate my old site content to Drupal 7”
package = “Development”
core = 7.x
dependencies[] = migrate
# include the files that contain your Migrate classes
files[] = migrate_typepad.migrate.inc
files[] = entry.inc
files[] = user.inc
files[] = category.inc
files[] = comment.inc
[/code]
As you can see, we have 5 files declared in the info file. It is possible to do everything in the .module file but it’s a common practice to create separate .inc files for different migrations.
For this tutorial, we will only migrate users from typepad. If you are interested on how to migrate the others entity. look for upcoming articles that cover this in more detail.migrate_typepad.migrate.inc : This will be the migration loader
entry.inc: Migration class to export entities (page on typepad)
user.inc: Migration class to export users
category.inc: Migration class to export taxonomies
comment.inc: Migration class to export comments
Don’t forget, if you modify the info file, you have to clear your cache on drupal to apply the modifications.

III. Declaration of Migration Classes

In order to migrate module recognize your Migration Classes defined in your own module, you would need to implement hook_migrate_api() in your loader (migrate_typepad.migrate.inc).
[code language=”php”]
function migrate_typepad_migrate_api() {
$api = array(
‘api’ => 2,
‘migrations’ => array(
‘Entry’ => array(‘class_name’ => ‘EntryMigration’),
‘User’ => array(‘class_name’ => ‘UserMigration’),
‘Category’ => array(‘class_name’ => ‘CategoryMigration’),
‘Comment’ => array(‘class_name’ => ‘CommentMigration’)
),
);
return $api;
}
[/code]

As you can see above, we need to return an associative array that describes our migration. You can find more information about parameters in the documentation.
API: the version of migrate that we are using

Migrations: declare the machine names of the object that we want to use with the name of the corresponding Migration Classes.

Now you may ask, where is the .module file ?

Usually this file will be empty unless you want to define some drupal hooks for example to create an entry in the drupal menu. So let’s create a migrate_typepad.module empty.

 

IV. Define the Migration Classes

Let’s define the UserMigration class:
Below is a sample of the code: (user.inc):

[php]
class UserMigration extends Migration {
public function __construct() {
//entry is the name of a group.
parent::__construct(MigrateGroup::getInstance(‘entry’));
$this->description = ‘Migration User’;
/*************SOURCE DATA*************/
$query = db_select(‘mt_author’, ‘ma’)
->fields(‘ma’, array(‘author_id’, ‘author_nickname’, ‘author_password’, ‘author_email’));
$this->source = new MigrateSourceSQL($query);
/*************DESTINATION DATA*************/
$this->destination = new MigrateDestinationUser();
/*************MAPPING*************/
$this->addFieldMapping(‘is_new’)
->defaultValue(TRUE);
$this->addFieldMapping(‘pass’, ‘author_password’);
$this->addFieldMapping(‘name’, ‘author_nickname’);
$this->addFieldMapping(‘mail’, ‘author_email’);
$this->addFieldMapping(‘roles’)
->defaultValue(DRUPAL_AUTHENTICATED_RID);
$this->addFieldMapping(‘status’)
->defaultValue(1);
$this->map = new MigrateSQLMap($this->machineName,
array(
‘author_id’ => array(‘type’ => ‘int’,
‘unsigned’ => TRUE,
‘not null’ => TRUE,
)
),
MigrateDestinationNode::getKeySchema()
);
$this->addUnmigratedDestinations(array(‘created’,’access’,’login’,’role_names’,
‘picture’,’signature’,’signature_format’,’timezone’,’language’,
‘theme’,’init’,’data’,’field_migrate_example_gender’,’path’));
}
}
[/php]

As you can see, our class implemented the Migration Class and overload the constructor that lets us initialize each attribute.

Description: this description will appear on our UI module or on your command line with drush.

 

How to migrate to Drupal 7 from other CMS

Source: data that we want to export. In our case, we use a query on a Mysql Table called ‘mt_author’
WARNING: You need to have previously imported your table in your drupal database or perform a remote connexion to a database where there is the data that you want to export.

Destination: define the destination object. You can see all the available destination classes here.
Since we want to exports user so we will use MigrateDestination User class.
Map: this attribute tell to Migrate module how source and destination are related.

 
To clarify: When we export an entry from typepad, it is obvious that we can’t keep the same entity id (the uid (Drupal) id as it will be different as the author_id (Typepad)). You can’t have a duplicated id in your table. So when entries (TypePad) will be exported to create nodes (Drupal), how will remember what is the correspondence between the uid and author_id to assign to nodes?

 
To do that Migrate and create a database table which map source and destinations keys and needs to know what data types the keys are for. That’s the goal of the attribute “map”.

 
The first parameter when you instantiate a MigrateSQLMap class is the suffix of tables that will be created. The second parameter defines the key of the source data. you can see author_id is an unsigned int which can’t be null. And the third parameter is the key of the destination data. Since we use the class MigrateDestinationUser, it knows what is the data type of the key , and provide it through the static method getKeySchema().
And to finish we have to define data mappings. it tells the migration from each row processed from the result of your query, where you want to assign each column.

Note: the first parameter of addFieldMapping function is the destination field and the second parameter is the source field.
If you don’t have data for some destination fields, you can apply default values with the defaultValue function.
And that’s it, you are ready at this point to export your users from TypePad to Drupal 7.
Enjoy!

Payman Taei
Payman Taei is the Founder of HindSite Interactive (he doesn't like using the word "CEO" it's way too Formal), an award winning web design and web development company. He's also the Founder of Easy WebContent, Do It Yourself platform allowing everyone to easily create, manage professional websites, presentations & infographics.

Leave a Reply

Your email address will not be published. Required fields are marked *

Since 2001 we have helped 500+ companies
build a better online presence.

We can do the same for you. Get a free consult.