migrating from D5 upload module to D6 cck filefields

I'm working to update a Drupal 5 site that uses the core upload module to a Drupal 6 site that uses CCK Filefields. I found some work on handling this by drewish, but it needed adapting for my uses.

Some considerations:

  • The files and upload tables have already been run through update.php to move core from D5 to D6.
  • The cck filefield is called "attachments".
  • It helps to assign the filefield to multiple content types. That gets it out into its own table, which makes the file records simpler to work with. If you don't legitimately have multiple content types that need attachments, you could temporarily add the field to a dummy content type and then delete it afterwards. CCK should take care of shuffling the tables and data around, because it is clever like that.

I just ran this function from within devel's "execute php" page.

<?php
function _migrate_upload_to_filefield() {
 
$files = db_query("SELECT * FROM {upload} u
    WHERE nid > 0 ORDER BY nid ASC, fid ASC"
);
 
 
$nid = 0;
 
  while (
$file = db_fetch_array($files)) {
   
$attachment = new stdClass();
   
   
// D5 didn't have weights,
    // so we'll store things in the order they were uploaded
   
if ($nid != $file['nid']) {
     
$delta = 0;
     
$nid = $file['nid'];
    }
   
   
$attachment->vid = $file['vid'];
   
$attachment->nid = $file['nid'];
   
$attachment->delta = $delta;
   
$attachment->field_attachments_fid = $file['fid'];
   
$attachment->field_attachments_list = $file['list'];
   
// schema will take care of the serialization
   
$attachment->field_attachments_data =
      array(
'description' => $file['description']);
   
   
$delta++;
   
   
drupal_write_record('content_field_attachments', $attachment);
  }
}
?>

Timestamping Migrated Files

Here is another little one that makes a best guess at providing a timestamp for the D6 files table based on the versions of the nodes they are attached to. Really just an SQL wrapper.

<?php
function _migrate_upload_file_timestamps() {
 
db_query("UPDATE {upload} u
    INNER JOIN {files} f ON u.fid = f.fid
    INNER JOIN {node_revisions} nr ON u.vid = nr.vid
    SET f.timestamp = nr.timestamp
    WHERE f.timestamp = 0"
);
}
?>

Populating Meta-Data

One more. This is for use with the filefield_meta submodule, to populate the meta information based on the old D5 table. Filefield has a really nice API.

<?php
function _migrate_update_filefield_meta() {
 
$files = db_query("SELECT f.* FROM {files} f
    LEFT JOIN {filefield_meta} fm
    ON f.fid = fm.fid WHERE fm.fid IS NULL"
);
 
  while (
$file = db_fetch_object($files)) {
   
filefield_meta_file_insert($file);
  }
}
?>