Creating nodes programmatically that have CCK image fields in Drupal 6
Sun, Oct 18, 2009 by Afraaz
When creating nodes programmatically it's easy enough to give the node a
title, body, and type by using the following:
$node = new stdClass();
$node->title = 'title';
$node->body = 'body text';
$node->type = 'type';
These are simple properties that ALL nodes will have. What about nodes with CCK fields attached to them? Well for text fields we can simply use the following:
$node = new stdClass();
$node->title = 'title';
$node->body = 'body text';
$node->type = 'type';
$node->$field_name[0]['value'] = 'TEXT'
Where $field_name can take place of the internal CCK field name (field_XXX_XXX)
That covers the text fields but what about images? Here's a little background on the situation that was put infront of me. I had images on a different server which I needed to attach to an image field on one of our content types. So I used a combination of cURL and a CCK function in order to attach the images to the nodes.
First we'll start with the function that uses cURL in order to save the images to our server.
/**
* Allows us to save images from the phonedog webservice
*
* @param $img - The path of the image file
* @param $fullpath - The path to where the image will be saved
*
* @return none
*/
function modulename_save_image($img, $fullpath){
$ch = curl_init($img);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$rawdata = curl_exec($ch);
curl_close ($ch);
if(file_exists($fullpath)){
unlink($fullpath);
}
$fp = fopen($fullpath, 'x');
fwrite($fp, $rawdata);
fclose($fp);
}
This function will take a URL to the image and will save the image in a directory of your choosing. When I used this function I decided to use the temp directory of the Drupal instance. IE:
variable_get('file_directory_temp', '/tmp');
Thhis function will save all your images in your temp directory. Now that you have all your images in the tmp directory you can begin to save the node.
I used the following to save images to nodes:
$node = new stdClass();
$node->title = 'title';
$node->body = 'body text';
$node->type = 'type';
$filepaths = array('/tmp/foo.jpg', '/tmp/bar.jpg');
foreach ($filepaths as $filepath) {
$field = field_file_save_file($filepath, array(), file_directory_path() .'/'. $directory);
$node->$field_name[] = $field;
}
$node = node_submit($node);
node_save($node);
In the above code the $directory variable can be a sub folder for your images just so you can keep them organized. The $field_name variable is again the internal CCK field name (field_XXX_XXX). This method will support fields that allow for multiple images as well. The $filepaths variable in the above example is hard coded, of course you can create a function that will return an array of image paths.
Well that's how one would go about saving images to nodes programmatically. Please
feel free to let me know if there's a better way of doing the same thing.
The interweb my ~ away from ~
Badger posted on December 7, 2009 3:32 pm
I can't use:
$field_name = 'field_text';
$node->$field_name[0]['value'] = 'TEXT';
I get "PHP Fatal error: Cannot use string offset as an array ..."
Any ideas?
Peter posted on November 13, 2009 8:06 am
Thanks alot for the post! Really helped! I think the proper way to create a node via code is to use drupal_execute like:
drupal_execute('node_form', $form_state, $node);
Matt posted on November 10, 2009 6:22 pm
Hey,
Thanks for the code. What if I'd like to use an image already in the right place? That is, I don't want to copy the image at all, but just get the array generated from this function.
Thanks,
~Matt
admin posted on October 19, 2009 5:12 pm
The node_submit call just prepares the node object for the node_save call. Using the node object it returns, you can pass this into node_save which will allow other modules to modify the node object using hook_nodeapi.
admin posted on October 19, 2009 5:04 pm
Cool thank you. I'll look into using drupal_http_request.
Drupal Theme Garden posted on October 19, 2009 9:31 am
Thanks for this useful article.
Can you, please explain a bit:
$node = node_submit($node);
dalin posted on October 19, 2009 5:17 am
I find drupal_http_request() to be a much better choice than CURL. It's much easier to use and there's no dependency on a PHP module that may or may not be there.
Post new comment