Last updated 6 February 2012. Created on 4 February 2012.
Edited by StuartDH. Log in to edit this page.

With roles, users, forum structure and threads migrated, we can now add posts to the threads with something like...

class vBulletinPostMigration extends Migration {
  public function __construct() {
    $this->description = t('Migrate vBulletin forum posts');

    // Set the source table's primary key
    $this->map = new MigrateSQLMap(
        'postid' => array(
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
          'description' => 'vBulletin forum posts',
          'alias' => 'p',

    // Set the query to get the source object
    $query = Database::getConnection('default', 'for_forum_migration')
      ->select('post', 'p')
      ->fields('p', array(

    // D7 thread includes the first post as it's body, so join with the post table and do not the first post for each thread

    $query->join('thread', 't', 't.threadid = p.threadid AND p.postid != t.firstpostid');
    // This sort ensures that post parents are saved before children.

    $query->orderBy('dateline', 'ASC');
    $count_query = Database::getConnection('default', 'for_forum_migration')
                ->select('post', 'p');
    $count_query->addExpression('COUNT(postid)', 'cnt');

    $this->source = new MigrateSourceSQL($query, array(), $count_query, array('map_joinable' => FALSE));

    // Define the destination as the D7 comment

    $this->destination = new MigrateDestinationComment('comment_node_forum');

    // Map fields from vBulletin posts to D7 forum comments

    $this->addFieldMapping('nid', 'threadid')

    $this->addFieldMapping('name', 'username');

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

    $this->addFieldMapping('thread', 'title')

    $this->addFieldMapping('subject', 'title')

    $this->addFieldMapping('created', 'dateline');

    $this->addFieldMapping('changed', 'dateline');

    $this->addFieldMapping('status', 'visible');

    $this->addFieldMapping('hostname', 'ipaddress');

    $this->addFieldMapping('comment_body', 'pagetext');

    //Do not map the following source fields
    $this->addFieldMapping(NULL, 'allowsmilie') ->description(t('Not a setting per comment in D7'))
    $this->addFieldMapping(NULL, 'showsignature') ->description(t('Set at roles level in D7'))
    $this->addFieldMapping(NULL, 'iconid') ->description(t('Not used in vBulletin or D7'))
    $this->addFieldMapping(NULL, 'attach') ->description(t('Set at content type level in D7'))
    $this->addFieldMapping(NULL, 'infraction') ->description(t('Not used in vBulleton or D7'))
    $this->addFieldMapping(NULL, 'reportthreadid') ->description(t('Not used in D7'))
    $this->addFieldMapping(NULL, 'parentid') ->description(t('No parentid as I want thread posts to be linear rather than threaded in D7'))

    // Unmapped destination fields

    $this->addFieldMapping('pid') ->description(t('Want linear rather than threaded threads so pid not used in D7'))
    $this->addFieldMapping('mail') ->description(t('No anonymous comments in vBulletin and email set at user level in D7'))
    $this->addFieldMapping('homepage') ->description(t('No anonymous comments in vBulletin and homepage set at user level in D7'))
    $this->addFieldMapping('language') ->description(t('Language set at site level in D7'))

    // D7 comment subject titles need to be trimmed to a max of 50 characters

  public function prepareRow(stdClass $row) {
    if (drupal_strlen($row->title) > 50) {
      $row->title = drupal_substr($row->subject, 0, 50) . '...';

Looking for support? Visit the forums, or join #drupal-support in IRC.