Migrate module: file handling
on
October 27, 2009
Migrate module: file handling
So you're migrating pages and users from another CMS to Drupal using the Migrate module, but how do you handle all those file attachments? This example will cover taking the input filename and adding it to an imagefield on a Drupal content type. However, this should work in exactly the same way for filefields too.
The first thing you need to do is to take all files to be migrated and place them in your site's
In our example, we used a content type called "news" with a
files directory. If you plan on using the migrate module's "clear imported records" feature, so as to do multiple test runs, you should retain a backup of these files as when the nodes are cleared / deleted, so are the files.
Create the CCK content type and add an imagefield to it to store the migrated image. Then add a content set to map the source content fields to their Drupal equivalents. When configuring the content set, you will see three fields for your image: "fid", "list" and "data". We're going to ignore these and instead set the field value using the hook_migrate_destination_prepare_node().
<?php
function mymodule_migrate_destination_prepare_node(&$node, $tblinfo, $row) {
$extensions = variable_get('upload_extensions_default', 'jpg jpeg gif png txt html doc xls pdf ppt pps odt ods odp');
if ($node->type == 'news') {
$filepath = 'sites/all/files/images/'. $row->cms_news_table_image;
// Ensure the file exists.
if (file_exists(file_create_path($filepath))) {
// Check if the file exists in the 'files' table already.
$file = db_fetch_object(db_query("SELECT * FROM {files} WHERE filepath = '%s'", $filepath));
// Create the file entry in the 'files' table if necessary.
if (!$file->fid) {
$file = new stdClass;
$file->filepath = $filepath;
$file->filename = file_munge_filename(basename($file->filepath), $extensions);
$file->filemime = file_get_mimetype($file->filename);
$file->uid = 1;
$file->status = 1;
$file->timestamp = $node->created;
$file->filesize = filesize($file->filepath);
drupal_write_record('files', $file);
}
// Set up the image field.
$node->field_news_image[0] = array(
'fid' => $file->fid,
'list' => 1,
'data' => array('alt' => $node->title, 'title' => $node->title, 'description' => $node->title),
'uid' => $node->uid,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filemime' => $file->filemime,
'status' => 1,
'timestamp' => $node->created,
);
}
// Print an error message if the file doesn't exist.
else {
drupal_set_message(t('Failed to find file: %file', array('%file' => $filepath)), 'error');
}
}
}
?>field_news_image imagefield, while the column containing the image filename in the source CMS is cms_news_table_image.
The hook_migrate_destination_prepare_node() hook is invoked just before each node record is migrated, allowing the module to manipulate the node data, one row at a time, immediately before it is stored to Drupal's database.
For each row, we check that the file we wish to migrate exists in the "files" directory and create a record for it in Drupal's files table if one doesn't already exist. Finally we configure the field_news_image field with all the required information.
attiks (not verified) October 28, 2009
You have to create your own module file, dont forget to create the .info file as well and enable the module
Anonymous (not verified) October 28, 2009
Thanks!
I made note of this page in a discussion about this subject at Migrate:
Anonymous (not verified) October 27, 2009
Where do you put this code?












Hi Stella.
Thanks for this, really helpful. As it happens I was doing exactly this a couple of weeks ago and I'm glad to see I follwed pretty much the same steps as you. Although I omitted to check if the file already existed (doh!) and I hadn't come across
<span style="color: #000000;"><span style="color: #007700;"></span><span style="color: #0000bb;">file_munge_filename</span><span style="color: #007700;">()</span></span>If ussing the 'clear imported records' feature in migrate module to repeatedlty test the same few records, I found it useful to change the permissions of the files such that the webserver does not have permission to delete them. In my case this meant changeing the owner of the files to the ftpuser rather than apache.
This left the source files in place every time I used the 'clear imported records', which saved me lot of time copying files.
So many thanks for the pointers.
Finn.