Here are my migration classes:

/**
 * Created by DOOR3 Business Applications, Inc.
 * Developer: Sean Robertson
 * Date: 9/20/13
 * Time: 11:28 AM
 */

/**
 * @file
 * A basic example of using the Migrate module to import taxonomy, users, nodes,
 * and comments.
 *
 * The basic idea is
 * - The users in the source application are listed in the
 *   migrate_example_beer_account table and are transformed into Drupal users.
 * - Drupal "beer" nodes describe beers; The information to create the nodes
 *   comes from the migrate_example_beer_node table.
 * - Taxonomy terms for the beer nodes (ale, pilsner) come from the
 *   migrate_example_beer_topic table and they are applied to nodes using the
 *   source information in the migrate_example_beer_topic_node table.
 * - Comments to be attached to the beer nodes are described in the source
 *   migrate_example_beer_comment table.
 *
 * We will use the Migrate API to import and transform this data and turn it into
 * a working Drupal system.
 */

/**
 * To define a migration process from a set of source data to a particular
 * kind of Drupal object (for example, a specific node type), you define
 * a class derived from Migration. You must define a constructor to initialize
 * your migration object. By default, your class name will be the "machine name"
 * of the migration, by which you refer to it. Note that the machine name is
 * case-sensitive.
 *
 * In any serious migration project, you will find there are some options
 * which are common to the individual migrations you're implementing. You can
 * define an abstract intermediate class derived from Migration, then derive your
 * individual migrations from that, to share settings, utility functions, etc.
 */
abstract class CasestudyMigration extends Migration {
  public function __construct($arguments) {
    // Always call the parent constructor first for basic setup
    parent::__construct($arguments);
    $connection_info = variable_get('example_migrate_settings_database', array());
    if (!empty($connection_info)) {
      Database::addConnectionInfo('example_migrate', 'default', $connection_info);
    }
    else {
      drupal_set_message(t('Example Migrate module database settings not found. Please set the module and go to <a href="@url">Migrate page</a>.', array('@url' => url('admin/content/migrate'))));
      drupal_goto('admin/config/content/example_migrate');
    }

    // With migrate_ui enabled, migration pages will indicate people involved in
    // the particular migration, with their role and contact info. We default the
    // list in the shared class; it can be overridden for specific migrations.
    $this->team = array(
      new MigrateTeamMember('Sean Robertson', 'sean.robertson@door3.com', t('Implementer')),
    );
  }
}

/**
 * Migration class for media images.
 */
class CasestudyMediaImageMigration extends CasestudyMigration {
  public function __construct($arguments) {
    parent::__construct($arguments);
    $this->description = t('Example migration of media images');

    $this->map = new MigrateSQLMap($this->machineName,
      array(
        'id' => array(
          'type' => 'int',
          'not null' => TRUE,
          'description' => 'ID',
          'alias' => 'c',
        )
      ),
      MigrateDestinationMedia::getKeySchema()
    );

    $query = Database::getConnection('default', 'example_migrate')
      ->select('mos_casestudies', 'c')
      ->fields('c', array('id', 'name', 'logo'));

    $count_query = Database::getConnection('default', 'example_migrate')
      ->select('mos_casestudies', 'c');
    $count_query->addExpression('COUNT(id)', 'cnt');

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

    // In the simplest case, just pass the media type.
    $this->destination = new MigrateDestinationMedia('image');

    // The source images are in a local directory - specify the parent.
    $this->addFieldMapping('source_dir')
      ->defaultValue('/.../example-old/images/stories/casestudies');
    // The 'value' of the media destination is mapped to the source field
    // representing the media itself - in this case, a filename relative to
    // source_dir.
    $this->addFieldMapping('value', 'logo');

    $this->addFieldMapping('uid')
      ->defaultValue(1);

    $this->addUnmigratedDestinations(array('destination_dir', 'destination_file', 'file_replace', 'preserve_files', 'timestamp'));
    if (module_exists('path')) {
      $this->addUnmigratedDestinations(array('path'));
    }
  }
}

/**
 * The BeerNodeMigration uses the migrate_example_beer_node table as source
 * and creates Drupal nodes of type 'Beer' as destination.
 */
class CasestudyNodeMigration extends CasestudyMigration {
  public function __construct($arguments) {
    parent::__construct($arguments);
    $this->description = t('Migrate press releases from the source database to nodes');
    $this->dependencies =
      array('CasestudyMediaImage');

    $this->map = new MigrateSQLMap($this->machineName,
      array(
        'id' => array(
          'type' => 'int',
          'not null' => TRUE,
          'description' => 'ID',
          'alias' => 'c',
        )
      ),
      MigrateDestinationNode::getKeySchema()
    );

    // We have a more complicated query. The Migration class fundamentally
    // depends on taking a single source row and turning it into a single
    // Drupal object, so how do we deal with zero or more terms attached to
    // each node? One way (demonstrated for MySQL) is to pull them into a single
    // comma-separated list.
    $query = Database::getConnection('default', 'example_migrate')
      ->select('mos_casestudies', 'c')
      ->fields('c', array('id', 'name', 'shortdescription', 'description', 'category', 'logo', 'published'));

    // By default, MigrateSourceSQL derives a count query from the main query -
    // but we can override it if we know a simpler way
    $count_query = Database::getConnection('default', 'example_migrate')
      ->select('mos_casestudies', 'c');
    $count_query->addExpression('COUNT(id)', 'cnt');

    // Passing the cache_counts option means the source count (shown in
    // drush migrate-status) will be cached - this can be very handy when
    // dealing with a slow source database.
    $this->source = new MigrateSourceSQL($query, array(), $count_query,
      array('cache_counts' => TRUE));

    // Set up our destination - nodes of type migrate_example_beer
    $node_options = MigrateDestinationNode::options(LANGUAGE_NONE, 'panopoly_wysiwyg_text');
    $this->destination = new MigrateDestinationNode('case_study', $node_options);

    // Mapped fields
    $this->addFieldMapping('sticky')
      ->defaultValue(FALSE);
    $this->addFieldMapping('status', 'published')
      ->defaultValue(FALSE);
    $this->addFieldMapping('uid')
      ->defaultValue(1);
    $this->addFieldMapping('title', 'name');
    $this->addFieldMapping('body', 'description');
    $this->addFieldMapping('body:summary', 'shortdescription');

    // These are related terms, which by default will be looked up by name
    $this->addFieldMapping('field_target', 'category')
      ->callbacks(array($this, 'transformTarget'));
    $this->addFieldMapping('field_target:create_term')
      ->defaultValue(TRUE);
    $this->addFieldMapping('field_target:ignore_case')
      ->defaultValue(TRUE);

    // Migrate logo images
    $this->addFieldMapping('field_logo', 'logo')
      ->sourceMigration('CasestudyMediaImage');
    $this->addFieldMapping('field_logo:file_class')
      ->defaultValue('MigrateFileFid');

    // Unmapped destination fields
    $this->addUnmigratedDestinations(array('promote', 'revision', 'language', 'revision_uid', 'log', 'body:format', 'body:language'));

    if (module_exists('path')) {
      $this->addFieldMapping('path')
        ->issueGroup(t('DNM'));
      if (module_exists('pathauto')) {
        $this->addFieldMapping('pathauto')
          ->issueGroup(t('DNM'));
      }
    }
    if (module_exists('statistics')) {
      $this->addUnmigratedDestinations(array('totalcount', 'daycount', 'timestamp'));
    }
  }

  protected function transformTarget($value) {
    $values = array(
      1 => 'Mergers & Acquisitions',
      2 => 'Restructuring',
    );
    return $values[$value];
  }
}

The nodes get created and the images end up in the managed files table, but the field on the node never gets set. Any idea what I'm missing?

Comments

seanr’s picture

Issue summary: View changes