views:

402

answers:

4

Hey there!

I'm trying to write a sync function that saves some data to nodes, which works fine, until I try to save the thumbnail image associated with the node.

I've managed to download the file and put it in my sites/default/files folder, but what's the best way to tell Drupal, "put this file in that CCK imagefield"?

EDIT To clarify a bit.. I sync the thumbnails separately (since one image can be used by several nodes)... I would like the initial thumbnail sync to save the files in the correct folder (not a temp one) and just point the imagefield to this file... That's what annoys me with field_file_save_file(), it saves a new file instead of just making a pointer.. Any advice?

A: 

You will need to poke around in the database. Unfortunately, your database can be layed out in numerous ways, acc to the use of fields. So explaining is a little hard. CCK will move around tables, rename stuff, and (de) normalise databases if it thinks this is needed. The data may be anywhere :) And depending on where it lives now, it becomes easier or harder to fix this problem.

Say, your node type is foo and the thumbnail field is bar. You could have a column bar in the table content_foo, but you could also have a table content_field_bar

Inside that table, the imagefield stores foreign keys to the file table. You either need to find the entry in the file table, if it exists, or else enter a new record. This is not easy. Then add the key for that file entry in the content_foo table, column bar, or in content_field_bar.

But, before starting with this: it really is not worth the pain: just delete the node and copy-paste the content in a new one.

berkes
Noooooo! don't poke around in the database!
Rimian
sure. But if your database is broken, you will need to poke arount in it to fix it again. And Aces Database seems broken.
berkes
Very bad advice ... never touch the database directly.
Disco
Why is that bad? If your database is broken, you will need to dive into the Database. Period. But aside: why would it be bad to touch the database directly?
berkes
+4  A: 

You can use field_file_save_file(); to move the file from a temp directory to your desitnation and create the object to be saved as a CCK field.

See: http://api.lullabot.com/field_file_save_file

Then you can save your field using the returned value like so:

$node->field_image[0] = field_file_save_file($my_file_path, array(), $my_destination);

You'll probably need to run a few tests. So you'll need to trash your destination directory and do it again.

Rimian
+2  A: 

This code will do it:

$imagefile = '/temp/somefile.jpg';
// Load up the CCK field  
$field = content_fields('field_image', 'mycontenttype');
// Load up the appropriate validators
$validators = array_merge(filefield_widget_upload_validators($field), imagefield_widget_upload_validators($field));
// Where do we store the files?
$files_path = filefield_widget_file_path($field);
// Create the file object, replace existing file with new file as source and dest are the same
$file = field_file_save_file($imagefile, $validators, $files_path, FILE_EXISTS_REPLACE);


$node = node_load($mynode);
$node->field_image[] = $file;
$node = node_submit($node);
node_save($node);
Tom
Cool! I had something similar laid out, but without node_submit().. What's the diff?
Ace
node_submit creates the teaser, adds user if not set and sets creation date and update date for the node.
Tom
http://api.drupal.org/api/function/node_submit/6
Tom
Oooh! I didn't know that Tom. Thanks for the tip!
Rimian
A: 

Kinda solved this myself I think. I field_file_save_file() my thumbnails separately and then field_file_load() them when syncing the nodes.

Seems to be working alright. :)

Ace