My First Experience with Codeignitor

After 10 years of PHP development, I got a chance to develop something with codeignitor. I fount it awesome experience, the simplest framework ever developed. I had to revamp a legacy application developed long back in php 4 and the application had a good user base. I had to stick with the working database schema and reuse the same, because migrating schema was almost impossible at this stage. Codeignitor fits my requirement and I found it best PHP framework I ever worked with.

Thanks to all contributors!

Advertisements

My Investigation on Drupal Recipe Module

I did not find the Beloved link “Read Documentation” on the project page of  D DOT O, so I start to investigate the module and jot down the module features as:

Recipe is a module for sharing cooking recipes. It includes optional extra modules for Recipe Import and Export. The extra modules include:

  1. Recipe Collect and display recipes.
  2. Recipe MasterCook4 Enables importing and exporting of the MasterCook4(.mxp) text format.
  3. Recipe plaintext Enables importing of plain text recipes into recipe nodes.
  4. Recipe Print View Enables exporting of 8-1/2″x11″, 3″x5″, and 5″x7″ recipes for index cards.
  5. Recipe recipeML Enables importing and exporting of recipeML format recipes.

Content Type:

The recipe module adds a new content type as ‘Recipe’. (admin/structure/content types)
Content Type :: Recipe
Fields:

  1. Title
  2. Description
  3. Yield units
  4. Yield
  5. Ingredients
  6. Source
  7. Instructions
  8. Additional notes
  9. Cooking time
  10. Preparation time
  11. URL redirects.

The Description of each field is defined below in add content test recipe.

Menus:
Adds the following links in Management Menu admin/content/:

  1. Recipes
    1. Bulk Export
    2. Bulk Import

Adds the following links in Navigation Menu.

  1. Add Content admin/content/add content/recipe
  2. Recipe

In Menus, enable a link to Recipes so users may access the module. The link is enabled by default.

Permissions:

  1. Adds standard node permission as new content type is added as “Recipe”.
  2. Adds permissions to export and import recipes.

Blocks:
This module adds two blocks as: (admin/structure/blocks)

  1. Newest Recipes
  2. Recipe Summary

Configure these two blocks in sidebar second and these will be displayed on Recipe pages. Newest Recipe will display the latest added Recipe items in a list and Recipe Summary Block will show brief details of latest added recipe.

Test Content:
Navigate to admin/content and add new content.
Select the content type as Recipe.
Add a test Recipe.
Recipe Field Description.

  1. Title                          The title of the recipe (Tandoori Chicken)
  2. Description              A short description or “teaser” for the recipe. (Full Chicken Grilled/Roasted in Hot Tandoor in Indian style)
  3. Yield                          units The units for the yield field(ie servings, people, cans, cookies, etc).
  4. Yield                          The number of servings the recipe will make (whole number integer, ie 5 or 6).
  5. Ingredients
    1. Quantity
    2. Unit                        (select from a long list of predefined units like cup, pinch, spoon, KG, can, carton, bunch, drop, gram, liter, ounce, Tablespoon etc.).
    3. Name
    4. Notes
    5. The example of ingredients will be:
    1. 1       Cup               oil           refined only
    2. 5       Tablespoon Salt        Iodized salt only
    3. Qty.   Unit               Name   Notes
    4. Unlimited Ingredients can be added.
  6. Source Optional. Does anyone else deserve credit for this recipe? (KFC)
  7. Instructions Step by step instructions on how to prepare and cook the recipe.
  8. Additional notes Optional. Describe a great dining experience relating to this recipe, or note which wine or other dishes complement this recipe.
  9. Cooking time How long does this recipe take to prepare, in minutes.
  10. Preparation time How long does this recipe take to cook, in minutes.
  11. URL redirects URL alias.

We can enable the comments for the recipe also.

Settings:
Navigate to admin/content/Recipes to configure the various settings for Recipe.

Import and Export:
Navigate to admin/content/Recipes/Bulk import to import the Recipe.
Navigate to admin/content/Recipes/Bulk export to export the Recipe.

Additional Notes:
Add Ingredients as terms in Tags vocabulary to auto complete while adding ingredients in creating recipe.

DATABASE DESCRIPTION
Data is saved in normal form. Recipes are collections of pointers to ingredients and to quantity terms. New terms can be added by modifying the schema. New ingredients are added automatically whenever they are used for
the first time.

Features:

  1. CCK integration: adding custom fields, field ordering, contrib field modules, and ingredient pages.
  2. Import/Export for popular recipe formats
  3. Various index pages through Views integration
  4. Recipe scaling (quantity multiplier)

Unknown Facts:

  1. Admin can enable and disable desired features In Recipe Admin e.g Enable a Recipes menu item so users may find it…
  2. Adjust Permissions for user roles. NOTE: a ‘site editor’ role is supported (see ‘edit all recipes’ permission).

Realtidbits Comment integration with Drupal

Realtidbits

After spending good amount of time integrating Disqus with SSO on my Drupal site for comments, my search begins to find a better commenting system which is easy to integrate. My search ends here.

The developer documentation here is awesome and provides all the steps and even code to include the commenting system in any site. The catch for writing this blog was to integrate it in Drupal and to make it available as a Drupal module.

I have added a new custom module to my site to integrate the comments on my pages.

Adding a Drupal custom module

Step 1:
Add a custom module say “realtidbits” to your site at sites/all/modules/custom/realtidbits.
Add a file as realtidbits.info as

name = Realtidbits
description = "Forget everything you think you know about a comments company. Try Realtidbits"
package = MNN
version = VERSION
core = 7.x
php = 5.3
files[] = realtidbits.module
files[] = realtidbits.admin.inc
configure = admin/config/services/realtidbits

Step 2:
Add a realtidbits.module file and implement following hooks:
A) Hook Permission to add a new site permission for comments administration.

/**
 * Implements hook_permission().
 */
function realtidbits_permission() {
 return array(
 'administer realtidbits' => array(
 'title' => t('Administer Realtidbits'),
 'description' => t('Perform administrative actions with Realtidbits.'),
 ),
 );
}

B) Hook menu to make a settings page under site configuration “Web services” section.

/**
 * Implements hook_menu()
 */
function realtidbits_menu() {
 $items = array();
 $items['admin/config/services/realtidbits'] = array(
 'title' => 'Realtidbits',
 'description' => 'Provides configuration options for the realtidbits comment system.',
 'access arguments' => array('administer realtidbits'),
 'page callback' => 'drupal_get_form',
 'page arguments' => array('realtidbits_admin_settings'),
 'file' => 'realtidbits.admin.inc',
 );
 return $items;
}

C) Hook block info to Add a custom block for comments.

/**
 * Implements hook_block_info()
 */
function realtidbits_block_info() {
 $blocks = array();
 $blocks['realtidbits_js_code'] = array(
 'info' => t('Realtidbits Comments'),
 );
 return $blocks;
}

D) Hook Block Configure to configure the custom block options.

/**
 * Implements hook_block_configure().
 */
function realtidbits_block_configure($delta='') {
 $form = array();
 switch($delta) {
 case 'realtidbits_js_code' :
 // Text field form element
 $form['realtidbits_comments_js_code_field'] = array(
 '#type' => 'textarea',
 '#cols' => 20,
 '#rows' => 5,
 '#resizable' => TRUE,
 '#title' => t('Include the following javascript code on every page you’d like to display comments anywhere on the html page replacing the ALL CAPS elements with your own credentials'),
 '#default_value' => variable_get('realtidbits_comments_js_code', ''),
 );
 break;
 }
 return $form;
}

E) Hook Block Save to save the custom comments block.

/**
 * Implements hook_block_save().
 */
function realtidbits_block_save($delta = '', $edit = array()) {
 switch($delta) {
 case 'realtidbits_js_code' :
 variable_set('realtidbits_comments', $edit['realtidbits_comments_js_code_field']['value']);
 break;
 }
}

F) Hook Block View to show the comments in action.

/**
 * Implements hook_block_view().
 */
function realtidbits_block_view($delta='') {
 $block = array();
 $js_code = 'WILL BE EXPLAINED IN NEXT SECTION ';
 switch($delta) {
 case 'realtidbits_js_code' :
 $block['content'] = $js_code;
 break;
 }
 return $block;
}

Displaying the Realtidbits comments on the site
Integrate the custom block created as above on all the pages where you want to display the comments using any of block integration method as below or add the pages to display the block in block configuration settings.

// @params module, block_view, delta
$block = module_invoke('realtidbits', 'block_view', 'realtidbits_js_code');
print render($block);

Register your site on Realtidbits
Once you register your site with realtidbits, you will get an email with your account credentials and an installation link to grant your login credentials administrator status.. Click on it and then follow the instructions onscreen to grant your login credentials administrator status.

Configure realtidbits account credentials
We will add a settings form to our module to allow administrator easily add the realtidbits account credentials on the site. Add a file as realtidbits.admin.inc add add the below function to define a settings form and save the realtidbits account credentials as drupal variables.

/**
 * Menu callback; Displays the administration settings for Realtidbits.
 */
function realtidbits_admin_settings() {
 $form = array();
 $form['realtidbits_domain'] = array(
 '#type' => 'textfield',
 '#title' => t('Shortname'),
 '#description' => t('The website shortname that you registered Realtidbits with. If you registered http://example.realtidbits.com, you would enter "example" here.'),
 '#default_value' => variable_get('realtidbits_domain', ''),
 );
 $form['settings'] = array(
 '#type' => 'vertical_tabs',
 '#weight' => 50,
 );
 // Advanced settings.
 $form['advanced'] = array(
 '#type' => 'fieldset',
 '#title' => t('Advanced'),
 '#group' => 'settings',
 '#description' => t('Use these settings to configure the more advanced uses of Realtidbits. You can find more information about these in the <a href="@installation">Installation</a> section of Realtidbits. To read the <a href="@documentation">Documentation</a>.', array(
 '@installation' => 'http://documentation.realtidbits.com/Comments_V3/Getting_Started/Installation',
 '@documentation' => 'http://documentation.realtidbits.com/Comments_V3',
 )),
 );
 $form['advanced']['realtidbits_echo_appkey'] = array(
 '#type' => 'textfield',
 '#title' => t('Echo Appkey'),
 '#description' => t('Echo Appkey.'),
 '#default_value' => variable_get('realtidbits_echo_appkey', ''),
 );
 $form['advanced']['realtidbits_echo_api_secret'] = array(
 '#type' => 'textfield',
 '#title' => t('Echo API Secret'),
 '#description' => t('Echo API Secret.'),
 '#default_value' => variable_get('realtidbits_echo_api_secret', ''),
 );
 $form['advanced']['realtidbits_rpx'] = array(
 '#type' => 'textfield',
 '#title' => t('RPX URL'),
 '#description' => t('RPX URL.'),
 '#default_value' => variable_get('realtidbits_rpx', ''),
 );
 $form['advanced']['realtidbits_echo_api_secret'] = array(
 '#type' => 'textfield',
 '#title' => t('Echo API Secret'),
 '#description' => t('Echo API Secret.'),
 '#default_value' => variable_get('realtidbits_echo_api_secret', ''),
 );
 // Behavior settings.
 $form['behavior'] = array(
 '#type' => 'fieldset',
 '#title' => t('Behavior'),
 '#group' => 'settings',
 );
 $form['behavior']['realtidbits_backplane_busname'] = array(
 '#type' => 'textfield',
 '#title' => t('Backplane Busname'),
 '#description' => t('Backplane Busname.'),
 '#default_value' => variable_get('realtidbits_backplane_busname', ''),
 );
 $form['behavior']['realtidbits_backplane_password'] = array(
 '#type' => 'textfield',
 '#title' => t('Backplane Password'),
 '#description' => t('Backplane Password.'),
 '#default_value' => variable_get('realtidbits_backplane_password', ''),
 );
 $form['behavior']['realtidbits_backplane_server'] = array(
 '#type' => 'textfield',
 '#title' => t('Backplane Server'),
 '#description' => t('Backplane Server.'),
 '#default_value' => variable_get('realtidbits_backplane_server', ''),
 );
 return system_settings_form($form);
}

Navigate to admin/config/services/realtidbits to save the realtidbits account credentials received.

Installing Realtidbits comments on the site
I suggest to use version 3 of the comments instead of version 2 which will be deprecated soon.
Replace the $js_code in hook_block_view above with the following code.

 $js_code = ‘
 <div id="comments"></div>
 <script src="http://cdn.echoenabled.com/sdk/v3/loader.js"></script>
 <script>
 Echo.Loader.initApplication({
 "script": "http://cdn.realtidbits.com/libs/v3/comments/comments.min.js",
 "component": "RTB.Apps.Comments",
 "backplane": {
 "serverBaseURL": "https://api.echoenabled.com/v1",
 "busName": "'. variable_get('realtidbits_backplane_busname') .'"
 },
 "config": {
 "appkey": "'. variable_get('realtidbits_echo_appkey') .'",
 "target": document.getElementById("comments"),
 "janrain": {
 "appUrl": "'. variable_get('realtidbits_rpx') .'"
 }
 }
 });
 </script>’;

You can further check the realtidbits developer documentation here for further details and other features of realtidbits comments. The parameter description and other optional parameters are better explained by realtidbits guy Kelly Abbott on developer documentation.

A simple guide to Drupal to Drupal Migration

druplicon_migrate_6-7

Contributed Modules:

Download the contributed module and dependencies if any.

  1. Migrate : http://drupal.org/project/migrate
  2. Migrate D2D : http://drupal.org/project/migrate_d2d

Extends the Migrate framework with Migration classes.

Migration includes:

  1. Role migration
  2. Picture migration
  3. User migration
  4. File migration
  5. Taxonomy term migration
  6. Node migration
  7. Comment migration
  8. Menu migration

Step 1:
Setting up Source Database Connection holding the source Drupal installation. How to connect to multiple databases within Drupal.
Define the source DB connection In settings.php as

$databases = array (
 'default' => array (.. Destination Database ...),
 'source_connection' =>
 array (
 'default' =>
 array (
 'database' => 'your source database name',
 'username' => 'your source database user',
 'password' => 'your source database password',
 'host' => 'your source database host',
 'driver' => 'mysql',
 'prefix' => '',
 ) ));

Step 2:

Add a custom module say my_site_migration with a .info and .module files and define the following dependencies.

  • migrate
  • migrate_ui
  • migrate_d2d

If you are extending the default migration classes, use the separate files to extend classes and add in .info file as

  • files[] = user.inc
  • files[] = taxonomy.inc
  • files[] = node.inc

Step 3:
In your .module file define the following hooks:

/**
 * Implementation of hook_migrate_api().
 */
 function my_site_migration_migrate_api() {
 $api = array(
 'api' => 2,
 );
 return $api;
 }
/**
 * Implementation of hook_flush_caches().
 */
 function my_site_migration_flush_caches() {
 //define all migrations in this function
 }

Migration Classes:
Classes have names of the form Drupal{object}{version}Migration, where {object} is the type of Drupal 7 thing to create (User, Node, etc.) and {version} is the Drupal version number of the source system (5, 6, or 7). Thus, to import pictures from Drupal 6, you would use DrupalPicture6Migration.

Class Arguments:
All migrate_d2d migration classes require the following arguments:

  1. machine_name: The unique machine name to assign to this migration.
  2. source_version: The Drupal version of the source database (5, 6, or 7).
  3. description: A brief description of the migration
  4. source_connection: Connection key for the source Drupal installation.

Optional arguments that apply to all migrate_d2d migration classes:

  1. source_database: Database array as an argument to migrations. Alternative to defining source connection in settings.php.
  2. group_name: Migration group name.
  3. dependencies: Migrations that must be run before this migration.
  4. soft_dependencies: Migrations that should be run before this migration (not enforced).
  5. format_mappings: An array mapping format IDs or machine names in the source database to format machine names in the destination.
  6. source_options: An array to be passed as options to the MigrateSourceSQL constructor.
  7. version_class: Overriden helper class name.

Define the common arguments array to reuse in all migrations.

$common_arguments = array(
 'source_version' => 6,
 'source_connection' => 'source_connection'
 );

Role migrations:
Supports one additional argument

  • role_mappings: An array keyed by the source role name, with a destination role name as the value. When importing roles, instead of the source role name being created on the destination, its role ID will map to the specified destination role’s ID.
$role_arguments = $common_arguments + array(
 'machine_name' =>,
 'role_mappings' => array(
 'Admin' => 'Administrator',
 OR
 1 => 5,
 ),
 );

User migration:
Pictures should be migrated before users.

/*
 * User Picture Migration
 */
 $picture_arguments = $common_arguments + array(
 'machine_name' => 'Machine_name_of_Picture_migration',
 'description' => t('some description'),
 'default_uid' => 1, // The default owner id if owner is not present
 'source_dir' => 'path_to_source_picture_folder',
 'destination_dir' => 'path_to_destination_picture_folder',
 );</pre>
Migration::registerMigration('DrupalPicture6Migration', $picture_arguments['machine_name'], $picture_arguments);

User migration take following additional arguments:
role_migration: The machine name of your role migration class, if any.
picture_migration: The machine name of your picture migration class, if any.

$user_arguments = $common_arguments + array(
 'machine_name' => 'Machine_name_for_user_migration',
 'description' => t('Import Drupal 6 users'),
 'role_migration' => 'Machine_name_for_role_migration',
 'picture_migration' => 'Machine_name_for_picture_migration',
 );</pre>
Migration::registerMigration('DrupalUser6Migration', $user_arguments['machine_name'], $user_arguments);

File Migration:
Use the distinct file migration class, which basically map the source files (or file_managed) table to the destination file_managed table. The supported arguments are:

  1. user_migration: The machine name of your user migration, used to properly assign ownership of the files.
  2. default_uid: A default destination uid to use as the default owner of files where a legacy owner isn’t identified.
  3. source_dir: The source destination from which to copy migrated files.
  4. destination_dir: The destination to which to copy migrated files. This defaults to public://.
  5. file_class: An override class for the extended default MigrateFileUri class with application-specific behavior.
$file_arguments = $common_arguments + array(
 'machine_name' => 'Machine_name_for_file_migration',
 'description' => t('Migration of files from Drupal 6'),
 'user_migration' => 'Machine_name_for_user_migration',
 'default_uid' => 1,
 'source_dir' => 'path_to_source_file_folder',
 'destination_dir' => 'path_to_destination_file_folder',
 );</pre>
Migration::registerMigration('DrupalFile6Migration', $file_arguments['machine_name'], $file_arguments);
<pre>

Using this strategy, files are migrated before being used in a subsequent migration, such as for a node containing a referenced image field. In the (custom) node migration, the referenced file should be migrated with a field mapping specifying a file_class of MigrateFileFid. This migrates only the reference to the file, not the file itself.
Additionally, preserve_files should be set to TRUE to avoid deleting the actual file, should the node migration be rolled back.

Term Migration:
The key is mapping the source vocabulary to the destination vocabulary. The migrate class would instantiate multiple times, one for each vocabulary to migrate.

  • source_vocabulary: The unique identifier of the source vocabulary (a machine name in D7, or a vid for earlier Drupal versions).
  • destination_vocabulary: The unique machine name of the destination vocabulary.
$vocabulary_arguments = array(
 array(
 'description' => t('Migration of Tags from Drupal 6'),
 'machine_name' => 'Machine_name_of_this_vacab_migration',
 'source_vocabulary' => '1', // source vocab ID
 'destination_vocabulary' => 'Destination_Vocabulary_Machine_Name',
 ),
 array(
 'description' => t('Migration of Categories from Drupal 6'),
 'machine_name' => 'Machine_name_of_this_vacab_migration',
 'source_vocabulary' => '2', // source vocab ID
 'destination_vocabulary' => 'Destination_Vocabulary_Machine_Name',
 ),
 );

$common_vocabulary_arguments = $common_arguments + array(
 'class_name' => 'DrupalTerm6Migration'
 );

foreach ($vocabulary_arguments as $arguments) {
 $arguments += $common_vocabulary_arguments;
 Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
 }

Node Migration:
Node migrations do mapping a source node type to a destination node type and takes the arguments.
source_type: The unique machine name of the source node type.
destination_type: The unique machine name of the destination node type.
user_migration: The machine name of your user migration, used to properly assign authorship of the nodes.
default_uid: A default destination uid to use as the default author of nodes where a source owner isn’t identified.
default_language: Default language for the node and the node body. Defaults to LANGUAGE_NONE.

$node_arguments = array(
 array(
 'machine_name' => 'Machine_name_of_content_type_1_migration',
 'description' => t('Migration of content type: nodes from Drupal 6'),
 'source_type' => 'source_content_type',
 'destination_type' => 'destination_content_type',
 'dependencies' => array('Machine_name_of_dependent_migration'), // if the dependency is defined
 ),
 array(
 'machine_name' => 'Machine_name_of_content_type_2_migration',
 'description' => t('Migration of Content Type: nodes from Drupal 6'),
 'source_type' => 'source_content_type',
 'destination_type' => 'destination_content_type',
 'dependencies' => array('Machine_name_of_dependent_migration'),
 )
 );

$common_node_arguments = $common_arguments + array(
 'user_migration' => 'Machine_name_of_user_migration',
 'default_uid' => 1,
 'class_name' => 'DrupalNode6Migration',
 );

The user_migration argument both establishes the sourceMigration() call to properly map uids, and adds the Machine_name_of_user_migration migration to the dependency list to be sure this migration runs after the user migration.

foreach ($node_arguments as $arguments) {
 $arguments = array_merge_recursive($arguments, $common_node_arguments);
 Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
 }

Comment migration:
Comment migrations are coupled to their corresponding node migrations – for each node type that has comments, you will define a corresponding comment migration.

  1. source_type: The unique machine name of the source node type.
  2. destination_type: The unique machine name of the destination node type.
  3. user_migration: The machine name of your user migration, used to properly assign authorship of the comments.
  4. default_uid: A default destination uid to use as the default author of nodes where a legacy owner isn’t identified.
  5. node_migration: The machine name of the migration for the nodes parenting these comments.
$comment_arguments = array(
 array(
 'machine_name' => 'Machine_name_of_content_type_1_comment_migration',
 'description' => t('Migration of content type: nodes comments from Drupal 6'),
 'source_type' => 'source_content_type',
 'destination_type' => 'destination_content_type',
 'node_migration' => 'Machine_name_of_content_type_1_migration',
 ),
 array(
 'machine_name' => 'Machine_name_of_content_type_2_comment_migration',
 'description' => t('Migration of content type: nodes comments from Drupal 6'),
 'source_type' => 'source_content_type',
 'destination_type' => 'destination_content_type',
 'node_migration' => 'Machine_name_of_content_type_2_migration',
 )
 );
 $common_comment_arguments = $common_arguments + array(
 'user_migration' => 'Machine_name_of_user_migration',
 'default_uid' => 1,
 'class_name' => 'DrupalNode6Migration',
 );
 foreach ($comment_arguments as $arguments) {
 $arguments = array_merge_recursive($arguments, $common_comment_arguments);
 Migration::registerMigration($arguments['class_name'], $arguments['machine_name'], $arguments);
 }

Menu Migration:
Menu migration defines no arguments beyond the common ones. Menus themselves just have names, titles, and descriptions to migrate.

$menu_arguments = $common_arguments + array(
 'machine_name' => 'Machine_name_of_Menu_migration',
 'description' => t('Import Drupal 6 menus'),
 );</pre>
Migration::registerMigration('DrupalMenu6Migration', $menu_arguments['machine_name'], $menu_arguments);

Menu links are more complex, and require a few arguments:
menu_migration: The machine name for your menu migration, so links get assigned to the correct menu.
node_migrations: An optional array of node migrations, required in order to update nids in link_path.
term_migrations: An optional array of term migrations, required in order to update tids in link_path.

$menu_link_arguments = $common_arguments + array(
 'machine_name' => 'Machine_name_of_Menu_link_migration',
 'description' => t('Import Drupal 6 menu links'),
 'menu_migration' => 'Machine_name_of_Menu_migration',
 'node_migrations' => array('Machine_name_of_content_type_1_migration', 'Machine_name_of_content_type_2_migration'),
 'term_migrations' => array('Machine_name_of_vacab1_migration', 'Machine_name_of_vacab2_migration'),
 );
Migration::registerMigration('DrupalMenuLinks6Migration', $menu_link_arguments['machine_name'], $menu_link_arguments);

Extending the migration classes:
Standard migrate_d2d classes maps all the core fields – mapping of any custom fields will be by extending the drupal_d2d classes and adding field mappings.
Example:
Suppose in your legacy system you had field_published on your article nodes, and in the new D7 system the equivalent field is field_published_date. You can map these fields by implementing a custom class overriding the provided node class and adding the mapping:

class ExampleArticleMigration extends DrupalNode6Migration {
 public function __construct(array $arguments) {
 parent::__construct($arguments);
 $this->dependencies[] = 'ExCategories';
 // We're replacing the legacy field_published, which was a text field, with a new date field
 $this->addFieldMapping('field_published_date', 'field_published');
 //Adding a default value to a field.
 $this->addFieldMapping('domain_user')->defaultValue(array('4' => 4));
 //Defining source migration for the field value
 $this->addFieldMapping('field_avatar', 'picture')->sourceMigration('Machine_name_of_picture_migration');
 // passing arguments
 $this->addFieldMapping('field_avatar', 'picture')->sourceMigration('machine_name')->arguments(array('source_type' => 'tid'));
 // call back functions
 $this->addFieldMapping('path', 'path')->callbacks(array($this, 'callback_function'));
 }
 }

To make use of your custom class, pass its name rather than DrupalNode6Migration when registering your classes:

Migration::registerMigration('ExampleArticleMigration', $article_node_arguments['machine_name'], $article_node_arguments)

Modifying queries:
Each of the migrate_d2d classes has a query() method, returning the query object used to pull source data. We can modify the base query method in extended class to customize the query for your application:

class ExampleUserMigration extends DrupalUser6Migration {
 protected function query() {
 // Get the default query (all rows in the users table other than uid 1)
 $query = parent::query();
 // Exclude test accounts
 $query->condition('name', 'test-%', 'LIKE');
 // Add fields from a custom table
 $query->innerJoin('myextradata', 'd', 'u.uid=d.uid');
 $query->fields('d', array('favorite_food', 'favorite_song'));
 return $query;
 }
 }

Of course, you can do much more when you extend the migrate_d2d classes – add a prepareRow() implementation to manipulate the data, prepare()

Useful Migration Links:

  1. http://drupal.org/node/1813498 :: Migrate Drupal 6 data to drupal 7.
  2. http://drupal.org/migrate
  3. https://www.acquia.com/blog/drupal-drupal-data-migration-part-1-basics
  4. https://www.acquia.com/blog/drupal-drupal-data-migration-part-2-architecture

Setting up Source Database Connection in settings.php:

  1. http://drupal.org/node/18429 :: How to connect to multiple databases within Drupal
  2. http://drupal.org/node/1014558 :: Add a database connection of source database in your settings.php of destination installtion.

Hooks Used:

  1. hook_flush_cache: http://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_flush_caches/7

Run Migrations:
Enable migrate_ui module (under migrate module) and check all migration from admin/content/migrate to run your migrations. Don’t forget to flush cache after you complete your migration scripts or you have made any changes in migration classes.