How To: Migrate from Image.module to ImageField Documentation Project
Psicomante - December 18, 2007 - 13:27
| Project: | ImageField |
| Version: | 5.x-1.1 |
| Component: | Documentation |
| Category: | task |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | patch (code needs work) |
Description
Is there any possibility to convert image.module/imageattacch images in imagefield? Is there any project in progress?
Thanks.

#1
#2
This is a quick and dangerous suggestion... You should back up your database and do this on a test site before even considering it for production...
Background:
Both Image.module and ImageField maintain relationships between the files table and the node table. Relating files.fid to node.vid or node.nid. This means you can theoretically migrate from Image to ImageField by properly configuring a new Content type to replace Image and executing a few database queries. This process is dependent on the machine readable content type and field names used in the CCK image content type.
Here is a completely untested example workflow.
However be warned this will no longer work with any of the modules intended to work with image.module. You will have to setup imagecache to handle derivative images, and it is very likely your themes will be broken, and any custom code built around image.module will no longer work.
If anyone has luck or refinements to the process please post them here and we will build a handbook page out of it.
#3
#4
In my experience updating to Imagefiled 2, I needed to update the filepath in the files table.
Say your main files directory is "sites/default/files"
Your image.module directory will be "images" (sites/default/files/images)
You might find in the files table the filepath will be "image/blah.jpg"
Now say your new imagefield is configured to put images in "cck_image". The path will be "sites/default/files/cck_image".
But when you add an image this way, looking in the files table, the filepath is "sites/default/files/cck_image/blah.jpg
In short, imagefield stores the full filepath, while image module stored the filepath relative to the files directory.
So the SQL for me was something like:
UPDATE filesSET filepath = CONCAT('sites/default/files/', filepath)
WHERE filepath LIKE 'images%'
I also wanted to update the filename from '_original' so I simple worked out the length of, in this example, 'sites/default/files/cck_image/'. Which is 30. So:
UPDATE filesSET filename = RIGHT(filepath, LENGTH(filepath) - 30)
WHERE filename = '_original'
All from memory, can't guarantee the sql.
#5
Hi,
> In my experience updating to Imagefiled 2, I needed to update the filepath in the files table.
Has anyone tested this already? If the precedure is solid, I'd like to suggest to add migration as a sub-module to Imagefield. Would this be possible?
Thanks & greetings, -asb
#6
I migrated from image.module to imagefield the following way on http://www.ridetowork.org/everydayrides
Get Set Up
I used PHPMyAdmin to run these queries.
Load your 'content_field_image_cache' with info from the 'node' table.
insert into content_field_image_cache (vid,delta,nid,field_image_cache_fid, field_image_cache_title, field_image_cache_alt) SELECT n.vid,0 as delta,n.nid,f.fid,n.title,n.title FROM node n, files f WHERE n.nid = f.nid AND n.type = 'image' and f.filename = '_original'You're going to change the 'image_cache' parts to what ever you named your imagefield.
Alerter your 'files' table
update files set filepath = CONCAT('files/',filepath) where filename = '_original' and filepath not like 'files/%'This prepends 'files/' to your filepath field in
update files set filename = SUBSTRING(filepath,14) where filename = '_original'This is the tricky part. It extracts the file name from our filepath (e.g. files/images/123.jpg) you will chop it down to just the filename (e.g. 123.jpg). If you change where you have kept the original images then you'll need to change 14 to another number to accommodate.
Alert your 'node' table
update node set type = 'everydayride' where type = 'image'You're going to change 'everydayrides' to the name of your content type.
Empty Your Cache!!!
Clean Up
delete fr from files f, file_revisions fr WHERE f.fid = fr.fid AND f.filename = 'thumbnail'delete fr from files f, file_revisions fr WHERE f.fid = fr.fid AND f.filename = 'preview'delete from files WHERE filename = 'preview' OR filename = 'thumbnail'There are a bunch of variables to this conversion such as where you store your images and the imagefield name. YMMV. I thought I read somewhere that someone is going to write a migration module for this for D7.
#7
Very useful, Spydor. I will try this one of these days on groups.drupal.org for group nodes. I will report back afterwards. if anyone else tries this, please let us know how it goes.
#8
Subscribing so I can follow along at home.
#9
In my first attempt to migrate from image.module to imagefield +imagecache was pretty good. There were a few changes I had to make in the queries listed by Spydor, some tables and fields did not yet exist.
Now, how about image_attach? With your directions I noticed that the thumbnails that were previously attached to nodes via image_attach are now disassociated. A good migration path would resolve these as well.
Also something to consider as part of migration, I think that the Video Image module also depends on the Image module.
#10
imagefield users generally use imagecache for thumbnailing. the beatiful thing about imagecache is that it generates thumbnails when it needs to. so you don't need to even think about migrating thumbnails. just focus on the originals.
#11
Oh yeah, I get that.
But there is some step that I did incorrectly where old image_attach thumbnails have not been replaced by new imagecache thumbnails. AFAICT, I used to create a blog node and use the image_attach module to create both an image node and then a resulting reference to the thumbnail that gets attached to the original blog. Something in this migration process above is not properly sticking imagefield values to nodes that used image_attach.
About 50% of the image_attach-ed nodes are missing imagefield values. All of the thumbs that were image_attach-ed to video nodes are not inserted into their imagefields (video used the video_image module to use the image_attach module to post a thumb).
Is there an additional step or did I botch the process?
#12
I know very little about image attach... drewish would be the best person to talk to about that...
#13
Here is a migration script based on the code offerred here. The script is pretty well documented. I added a link to this issue from the imagefield project page. There may be more/other places which should link here.
<?php
/**
* @file
* Migrate all image.module nodes to imagefields. Any image nodes that participate in image_attach will be
* properly attached the imagefield. The script does migrate video_image.module images.
*
* PREREQUISITES
* --------------
* - You must create a single imagefield field to which all your images will be migrated. You
* should create a new content type for that.
* - If you use image_attach, you should also add this imagefield field to each content type that
* is image_attach enabled.
* - The imagefield should be configured for 'multiple values'.
* - The imagefield's Image path should be identical to the image.module's configured path (i.e. 'images' by default)
*
* USAGE
* ----------
* - Backup your Drupal database. Really.
* - Edit the 'Configuration' section below.
* - Place this script in the root of your Drupal site.
* - Run this script by requesting <a href="http://<yoursite>/imagefield_migrate.php" title="http://<yoursite>/imagefield_migrate.php" rel="nofollow">http://<yoursite>/imagefield_migrate.php</a> in your browser.
* - Remove this script from your site to prevent accidental re-run.
* - Disable and uninstall image and image_attach modules.
*
* KNOWN ISSUES
* -------------
* - Rename files that have a '+' in them in the files table and also rename in filesystem
*
* AUTHORS
* -----------
* spydor (see <a href="http://drupal.org/node/201983#comment-828698" title="http://drupal.org/node/201983#comment-828698" rel="nofollow">http://drupal.org/node/201983#comment-828698</a>)
* Moshe Weitzman (<a href="http://drupal.org/moshe" title="http://drupal.org/moshe" rel="nofollow">http://drupal.org/moshe</a>)
*/
// ***** CONFIGURATION *******
// The imagefield field that you have already created and configured as per Prerequisites.
$field_name = 'field_imagefield';
// The content type that you have already created as per Prerequisites.
$type_name = 'image2';
// ***** END CONFIGURATION *******
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// Populate the imagefield table for every image node.
$table = 'content_'. $field_name;
$fid = $field_name. '_fid';
$title = $field_name. '_title';
$alt = $field_name. '_alt';
$sql = "INSERT INTO $table (vid,delta,nid,$fid, $title, $alt) SELECT n.vid, 0 as delta, n.nid,f.fid,n.title,n.title FROM node n, files f WHERE n.nid = f.nid AND n.type = 'image' AND f.filename = '_original'";
if (db_query($sql)) {
echo "- $table populated.<br />\n";
}
// Set the needed filename in the files table.
$image_path = file_create_path(variable_get('image_default_path', 'images'));
$length = strlen($image_path)+2;
$sql = "UPDATE files SET filename = SUBSTRING(filepath, $length) WHERE filename = '_original'";
if (db_query($sql)) {
echo "- files table updated<br />\n";
}
// Change the content type from 'image' to the configured type.
$sql = "UPDATE node SET type = '%s' WHERE type = 'image'";
db_query($sql, $type_name);
// Loop over the image_attach records
if (module_exists('image_attach')) {
$sql = "SELECT n.nid, n.vid, ia.iid FROM {image_attach} ia INNER JOIN {node} n ON ia.nid=n.nid";
$result = db_query($sql);
if ($num = db_num_rows($result)) {
while ($row = db_fetch_object($result)) {
// UPDATE the imagefield to point to the attached node, not the standalone node
$sql = "UPDATE $table SET nid = $row->nid, vid = $row->vid WHERE nid = $row->iid";
if (db_query($sql)) {
// Successful update. Now unpublish the standalone node that we just made.
$sql = "UPDATE {node} SET status = 0 WHERE nid = $row->iid";
db_query($sql);
}
else {
echo "update $table failed for $row->iid<br />\n";
}
}
echo "- $num image_attach relationships were migrated.<br />\n";
}
}
if (module_exists('video_image')) {
// Loop over the video.module nodes. Migrate video_image thumbnails to imagefield.
$sql = "SELECT nid, vid FROM {node} WHERE type = 'video'";
$result = db_query($sql);
if ($num = db_num_rows($result)) {
while ($row = db_fetch_object($result)) {
$node = node_load($row->nid);
if ($iid = $node->iid) {
$sql = "UPDATE $table SET nid = $row->nid, vid = $row->vid WHERE nid = $iid";
if (db_query($sql)) {
// Successful update. Now unpublish the standalone node that we just made.
$sql = "UPDATE {node} SET status = 0 WHERE nid = $iid";
db_query($sql);
}
else {
echo "update $table failed for $iid<br />\n";
}
};
}
echo "- $num video.module thumbnails were migrated.<br />\n";
}
}
// Clear CCK cache.
$sql = "DELETE FROM cache_content";
db_query($sql);
?>
#14
/me hugs moshe.
#15
Here's a patch that puts curly braces around the table names that were lacking them and also rearranges a couple of the prerequisites into the order that you'll encounter them in the content type admin page. Possibly a couple of other style-level changes, but only on lines that I was already changing. Also attached is the patched version. Tested, and it worked as advertised. Thank you so much!
#16
Automatically closed -- issue fixed for two weeks with no activity.
#17
Unfortunately both scripts #13 and #15 didn't work for me. Had to restore from backup.
Created a node-type 'tijdelijk' and a imagefield 'image_field' prior to the migration. I added this field to 'tijdelijk' and 3 other content-types.
Here's a summary from the log:
update content_field_image failed for 581
..
..
update content_field_image failed for 3692
update content_field_image failed for 3694
- 682 image_attach relationships were migrated.
As far as I could see target tables were empty.
Question: take the scripts table-name-prefixes in account?
Other question: I would like to execute the migration manually (#6), but what are the queries to be executed to migrate the image_attach links?
Thanks for all the work.
#18
line 78 doesn't account for prefixes