Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
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
Comment #1
seanr