Drupal 6 Programmatically adding an image to a FileField
How do I programmatically add an image to a file field? I have an url/filepath of an image that I wish to upload. I have tried the following:
$newNode->field_profile_image[0]['value'] = 'http://w开发者_Python百科ww.mysite.com/default.gif';
But it does not seem to work.
I have also tried:
$newNode->field_profile_image[0]['value'] = 'sites/default/files/default.gif';
The file does not need to be external to the webiste. I am happy to have it anywhere on the site in question.
You're probably going to have to use hook_nodeapi to set this correctly. You're going to want to modify it under the "Insert" operation. Make sure that you resave the node after you've added the required fields.
Drupal wants to map the image to an entry in the file table, so simply setting the URL will not work. First off, if it's a remote file, you can use the function listed in the Brightcove module on line 176, brightcove_remote_image, to grab the image and move it into your local directory.
Once the remote image is moved into place, you need to save it into the files table and then properly configure the node's property. I've done it in this method:
////// in NodeAPI /////
case "insert":
$node->field_image[0] = _mymod_create_filearray($image_url);
node_save($node);
This writes the files record, and then returns a properly formatted image array.
///// mymod_create_filearray /////
function _mymod_create_filearray($remote_url){
if ($file_temp = brightcove_remote_image($remote_url)) {
$file = new stdClass();
$file->filename = basename($file_temp);
$file->filepath = $file_temp;
$file->filemime = file_get_mimetype($file_temp);
$file->filesize = filesize($file_temp);
$file->uid = $uid;
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$file = array(
'fid' => $file->fid,
'title' => basename($file->filename),
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'mimetype' => $mime,
'description' => basename($file->filename),
'list' => 1,
);
return $file;
}
else {
return array();
}
}
And that should do it. Let me know if you have any questions.
Check out my Answer to a similar question from a while ago, where I describe how we did pretty much exactly what you need (if I understood the problem correctly).
The main point is to use the field_file_save_file()
function from the filefield module for attaching a file (during hook_nodeapi
, on operation presave
), which will do most of the work for you (more or less what jacobangel's '_mymod_create_filearray()' tries to do, but more tuned to filefields needs, including validation).
This assumes that the file already exists on the servers filesystem somewhere (usually in /tmp), and will correctly 'import' it into Drupal, with corresponding entries in the files table, etc. If you want to import files from remote URLs, you'll need to add the additional step of fetching them as a separate task/functionality first.
As mentioned in the answer linked above, I ended up using the code from the Remote File module as an example for a custom implementation, as we needed some project specific additions - maybe you can use it more directly for your purposes.
using nodeapi you should be able to set the value like you are trying to in the code example, but only or local images. You will most likely need to have the images in the "files" folder in your drupal install, but if that is set up everything else should work without a hitch. When using the nodeapi all the things that would normally happen when you save a node using a form would happen, such as updating the files table etc.
If you wanted to pull the image from the remote site using a module like feeds make it possible to pull the remote images, and create nodes. Depending on your use case you could either use it, or take a look at how it pulls the images and maps them to local files.
What you try will not work. Drupal offers no way to handle remote files, without the use for a module. AFAIK there is no module that offers an API to upload remote files trough.
Here is a quick example taken from one of my projects.
$node = new stdClass;
$node->title = 'Example Callout';
$node->type = 'wn_hp_callout';
// Search examples directory to attach some images.
$callouts_dir = drupal_get_path('module', 'wn_hp_callout').'/imgs/examples/';
$callout_imgs = glob($callouts_dir.'*.{jpg,jpeg,png,gif}',GLOB_BRACE);
// Now add the images and provide imagefield extended additional text.
foreach($callout_imgs as $img) {
$img_info = pathinfo($img);
$field = field_file_save_file($img, array(), file_directory_path() .'/example_callouts/');
if( !isset($field['data']) ) {
$field['data'] = array();
}
$field['data']['title'] = ucwords(str_replace('_',' ',$img_info['filename']));
$field['data']['alt'] = 'This is alt text.';
$node->field_wn_hp_callout_image[] = $field;
}
$node = node_submit($node);
node_save($node);
精彩评论