diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0591ab4241065911304dfcdf4710a1a20eedd94f..d1f60d1b4b179287a432e7fb35fdb0aca03739af 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -7,6 +7,7 @@ Features and enhancements - #1138096 - Added MigrateSourceMultiItems class for self-contained XML sources. - #1101586 - Add shortcut methods for adding several field mappings at once. - #1101592 - Replace --itemlimit with --limit, supporting time limits as well. +- #1139080 - Added example and test for importing profile pictures over http. Bug fixes - #1132034 - Don't assume entity is a stdClass. NOTE: Any field handler prepare() diff --git a/migrate_example/migrate_example.install b/migrate_example/migrate_example.install index 605f7aeaa1322e5955c4f9fe286d88365dd911c8..facc840456294c3eadb954dfb0a36238c9380f1b 100644 --- a/migrate_example/migrate_example.install +++ b/migrate_example/migrate_example.install @@ -114,4 +114,27 @@ function migrate_example_update_7002() { ->execute(); $ret[] = t('Added image_alt, image_title, and image_description fields.'); return $ret; -} \ No newline at end of file +} + +/** + * Add data for remote file examples. + */ +function migrate_example_update_7003() { + $ret = array(); + db_create_table('migrate_example_wine_files', migrate_example_wine_schema_files()); + migrate_example_wine_data_files(); + db_add_field('migrate_example_wine_account', 'imageid', array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'description' => 'Image ID.', + ) + ); + db_update('migrate_example_wine_account') + ->fields(array('imageid' => 1)) + ->condition('accountid', 9) + ->execute(); + $ret[] = t('Added migrate_example_wine_files table.'); + $ret[] = t('Added imageid field to migrate_example_wine_account table.'); + return $ret; +} diff --git a/migrate_example/wine.inc b/migrate_example/wine.inc index 8d9224c90cbee3d38c74413344377b39f967ae02..10c653417c0711ba1cb1753d423c75531477682d 100644 --- a/migrate_example/wine.inc +++ b/migrate_example/wine.inc @@ -143,11 +143,46 @@ class WineBestWithMigration extends WineTermMigration { } } +/** + * TIP: Files can be migrated directly by themselves, by using the MigrateDestinationFile + * class. This will copy the files themselves from the source, and set up the + * Drupal file tables appropriately. + */ +class WineFileMigration extends AdvancedExampleMigration { + public function __construct() { + parent::__construct(); + $this->description = t('Profile images'); + $this->dependencies = array('WinePrep'); + $this->map = new MigrateSQLMap($this->machineName, + array('imageid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Image ID.' + ) + ), + MigrateDestinationFile::getKeySchema() + ); + $query = db_select('migrate_example_wine_files', 'wf') + ->fields('wf', array('imageid', 'url')); + $this->source = new MigrateSourceSQL($query); + + // TIP: Set copy_file to copy the file from its source (which could be a + // remote server, i.e. the uri is of the form http://example.com/images/foo.jpg). + $this->destination = new MigrateDestinationFile(array('copy_file' => TRUE)); + + // Just map the incoming URL to the destination's 'uri' + $this->addFieldMapping('uri', 'url'); + $this->addUnmigratedDestinations(array('fid', 'uid', 'filename', 'status', + 'filemime', 'timestamp')); + } +} + class WineUserMigration extends AdvancedExampleMigration { public function __construct() { parent::__construct(); $this->description = t('Wine Drinkers of the world'); - $this->dependencies = array('WinePrep'); + $this->dependencies = array('WinePrep', 'WineFile'); $this->map = new MigrateSQLMap($this->machineName, array('accountid' => array( 'type' => 'int', @@ -161,7 +196,7 @@ class WineUserMigration extends AdvancedExampleMigration { $query = db_select('migrate_example_wine_account', 'wa') ->fields('wa', array('accountid', 'status', 'posted', 'name', 'password', 'mail', 'last_access', 'last_login', - 'original_mail', 'sig', 'sex')); + 'original_mail', 'sig', 'sex', 'imageid')); $this->source = new MigrateSourceSQL($query); $this->destination = new MigrateDestinationUser(); @@ -182,11 +217,13 @@ class WineUserMigration extends AdvancedExampleMigration { $this->addFieldMapping('init', 'original_mail'); $this->addFieldMapping('field_migrate_example_gender', 'sex') ->description(t('Map from M/F to 0/1 in prepare method')); + $this->addFieldMapping('picture', 'imageid') + ->sourceMigration('WineFile'); // Unmapped source fields // Unmapped destination fields - $this->addUnmigratedDestinations(array('theme', 'timezone', 'language', 'picture')); + $this->addUnmigratedDestinations(array('theme', 'timezone', 'language')); } public function prepare(stdClass $account, stdClass $row) { @@ -504,7 +541,7 @@ class WineWineMigration extends AdvancedExampleMigration { $this->addFieldMapping('body', 'body') ->arguments($arguments); $this->addFieldMapping(NULL, 'excerpt'); - $arguments = MigrateFileFieldHandler::arguments(drupal_get_path('module', 'migrate_example'), 'file_copy', FILE_EXISTS_RENAME); + $arguments = MigrateFileFieldHandler::arguments(NULL, 'file_copy', FILE_EXISTS_REPLACE); $this->addFieldMapping('field_migrate_example_image', 'image') ->arguments($arguments); $this->addFieldMapping('sticky') diff --git a/migrate_example/wine.install.inc b/migrate_example/wine.install.inc index d34e60b58fb76a2c2e314467ea0b85883adbeffb..96c9f80e74471a38635fdfcf57d4e3562bf674c9 100644 --- a/migrate_example/wine.install.inc +++ b/migrate_example/wine.install.inc @@ -17,6 +17,7 @@ function migrate_example_wine_schema() { $schema['migrate_example_wine_category_producer'] = migrate_example_wine_schema_category_producer(); $schema['migrate_example_wine_comment'] = migrate_example_wine_schema_comment(); $schema['migrate_example_wine_comment_updates'] = migrate_example_wine_schema_comment_updates(); + $schema['migrate_example_wine_files'] = migrate_example_wine_schema_files(); return $schema; } @@ -39,6 +40,7 @@ function migrate_example_wine_install() { migrate_example_wine_data_category_producer(); migrate_example_wine_data_comment(); migrate_example_wine_data_comment_updates(); + migrate_example_wine_data_files(); } function migrate_example_wine_uninstall() { @@ -59,6 +61,7 @@ function migrate_example_wine_uninstall() { function migrate_example_wine_disable() { MigrationBase::deregisterMigration('WinePrep'); + Migration::deregisterMigration('WineFile'); Migration::deregisterMigration('WineRegion'); Migration::deregisterMigration('WineUser'); Migration::deregisterMigration('WineVariety'); @@ -112,7 +115,7 @@ function migrate_example_wine_schema_wine() { 'type' => 'varchar', 'length' => 255, 'not null' => FALSE, - 'description' => 'Image path', + 'description' => 'Comma-separated list of images', ), 'posted' => array( 'type' => 'int', @@ -501,6 +504,12 @@ function migrate_example_wine_schema_account() { 'not null' => TRUE, 'description' => 'Signature for comments', ), + 'imageid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => FALSE, + 'description' => 'Image ID', + ), ), 'primary key' => array('accountid'), ); @@ -526,6 +535,27 @@ function migrate_example_wine_schema_account_updates() { ); } +function migrate_example_wine_schema_files() { + return array( + 'description' => 'Wine and account files', + 'fields' => array( + 'imageid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Image ID', + ), + 'url' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'description' => 'Image URL', + ), + ), + 'primary key' => array('imageid'), + ); +} + function migrate_example_wine_content_types() { // This code based on from standard.profile. // Insert default user-defined node types into the database. @@ -895,19 +925,19 @@ function migrate_example_wine_data_producer() { function migrate_example_wine_data_account() { $fields = array('accountid', 'status', 'posted', 'last_access', 'last_login', - 'name', 'sex', 'password', 'mail', 'original_mail', 'sig'); + 'name', 'sex', 'password', 'mail', 'original_mail', 'sig', 'imageid'); $query = db_insert('migrate_example_wine_account') ->fields($fields); $data = array( array(1, 1, '2010-03-30 10:31:05', '2010-04-30 18:25:24', '2010-04-30 14:01:02', 'darren', 'M', 'dpass', 'ddarren@example.com', 'darren@example.com', - 'All about the Australians'), + 'All about the Australians', NULL), array(3, 0, '2007-03-15 10:31:05', '2007-06-10 04:11:38', '2007-06-10 04:11:38', 'emily', 'F', 'insecure', 'emily@example.com', 'emily@example.com', - 'Sommelier to the stars'), + 'Sommelier to the stars', NULL), array(9, 1, '2004-02-29 10:31:05', '2004-02-29 10:31:05', '2004-02-29 10:31:05', 'fonzie', NULL, 'bike', 'thefonz@example.com', 'arthur@example.com', - 'Aaay!'), + 'Aaay!', 1), ); foreach ($data as $row) { $query->values(array_combine($fields, $row)); @@ -1072,3 +1102,16 @@ function migrate_example_wine_data_category_producer() { } $query->execute(); } + +function migrate_example_wine_data_files() { + $fields = array('imageid', 'url'); + $query = db_insert('migrate_example_wine_files') + ->fields($fields); + $data = array( + array(1, 'http://drupal.org/files/images/DA-individual.thumbnail.png'), + ); + foreach ($data as $row) { + $query->values(array_combine($fields, $row)); + } + $query->execute(); +} diff --git a/tests/plugins/destinations/comment.test b/tests/plugins/destinations/comment.test index 7ddc703dd8d4d43897c03b16a64b810faa6ba8a9..d69ae62a79b1ae339d4a9a75da523513bc2d0700 100644 --- a/tests/plugins/destinations/comment.test +++ b/tests/plugins/destinations/comment.test @@ -29,6 +29,10 @@ class MigrateCommentUnitTest extends DrupalWebTestCase { $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, t('"Best With" term import returned RESULT_COMPLETED')); + $migration = Migration::getInstance('WineFile'); + $result = $migration->processImport(); + $this->assertEqual($result, Migration::RESULT_COMPLETED, + t('File import returned RESULT_COMPLETED')); $migration = Migration::getInstance('WineUser'); $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, diff --git a/tests/plugins/destinations/node.test b/tests/plugins/destinations/node.test index fdecf6c63c572854c171fb3491ddcd821207e96c..f9d65cd32e23040e582b9640733fb6aa8515ee4a 100644 --- a/tests/plugins/destinations/node.test +++ b/tests/plugins/destinations/node.test @@ -29,6 +29,10 @@ class MigrateNodeUnitTest extends DrupalWebTestCase { $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, t('"Best With" term import returned RESULT_COMPLETED')); + $migration = Migration::getInstance('WineFile'); + $result = $migration->processImport(); + $this->assertEqual($result, Migration::RESULT_COMPLETED, + t('File import returned RESULT_COMPLETED')); $migration = Migration::getInstance('WineUser'); $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, diff --git a/tests/plugins/destinations/user.test b/tests/plugins/destinations/user.test index 8fbd3aef325ea1a4da5042e61dc5003c13357238..c0b75f9fc1429b477035eb98d2b33f24bbab862e 100644 --- a/tests/plugins/destinations/user.test +++ b/tests/plugins/destinations/user.test @@ -20,6 +20,10 @@ class MigrateUserUnitTest extends DrupalWebTestCase { } function testUserImport() { + $migration = Migration::getInstance('WineFile'); + $result = $migration->processImport(); + $this->assertEqual($result, Migration::RESULT_COMPLETED, + t('File import returned RESULT_COMPLETED')); $migration = Migration::getInstance('WineUser'); $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, @@ -78,8 +82,11 @@ class MigrateUserUnitTest extends DrupalWebTestCase { 1, t('Female gender migrated')); $this->assert(!isset($users['fonzie']->field_migrate_example_gender[LANGUAGE_NONE][0]['value']), t('Missing gender left unmigrated')); + $this->assert(is_object($users['fonzie']->picture) && + $users['fonzie']->picture->filename == 'DA-individual.thumbnail.png', + t('Picture migrated')); - // TODO: Theme, timezone, language, picture + // TODO: Theme, timezone, language // Test updates // Capture original terms diff --git a/tests/plugins/sources/xml.test b/tests/plugins/sources/xml.test index fecca8f8758890067961bac5148e4e6c8ce265a3..f5ba91816c8070aa469d9b7cdac1ba11f8c4e632 100644 --- a/tests/plugins/sources/xml.test +++ b/tests/plugins/sources/xml.test @@ -21,6 +21,10 @@ class MigrateXMLUnitTest extends DrupalWebTestCase { $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED, t('Region term import returned RESULT_COMPLETED')); + $migration = Migration::getInstance('WineFile'); + $result = $migration->processImport(); + $this->assertEqual($result, Migration::RESULT_COMPLETED, + t('File import returned RESULT_COMPLETED')); $migration = Migration::getInstance('WineUser'); $result = $migration->processImport(); $this->assertEqual($result, Migration::RESULT_COMPLETED,