Programmatically creating nodes with ImageFields
Last modified: January 8, 2009 - 21:26
Here's a snippet for programmatically creating nodes with imagefields:
<?php
$node = new StdClass();
$node->type = 'official_photo';
$node->title = t('Sample official photo');
$node->taxonomy[4] = 15; // Candid shots gallery
$file_temp = file_get_contents('./profiles/multisite/files/official-photo.png');
$file_temp = file_save_data($file_temp, file_directory_path() .'/official_photos/official-photo.png', FILE_EXISTS_RENAME);
$node->field_photo = array(
array(
'fid' => 'upload',
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
),
);
$node->uid = 1;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);
?>You'll have to add the code for your other fields if any, obviously

Needed file id for this to work
I could not get this to work until I added
'fid' => 'upload' like this :
$node->field_the_name_of_the_field = array(array(
'fid' => 'upload',
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
),
);
As far as I can tell, this makes sure the files table is populated correctly.
ImageField seems to drop a subdirectory
Our script, using the code above, sends this to node_save:
//print_r($node->field___mt_photo) outputsArray(
[0] => Array
(
[fid] => upload
[title] => 61539_aa.jpg
[filename] => 61539_aa.jpg
[filepath] => files/images/61539/61539_aa.jpg
[filesize] => 137735
)
)
And yet, after node save, what's happened is this:
//print_r($node->field___mt_photo) outputsArray(
[0] => Array
(
[fid] => 1530
[title] => 61539_aa.jpg
[filename] => 61539_aa.jpg
[filepath] => files/images/61539_aa_2.jpg
[filesize] => 137735
)
)
The image has been uploaded to files/images/ instead of files/images/61539/. AND(!) it's a duplicate (_aa_2.jpg). And yet, on occasion, it DOES keep the numbered subdirectory... seemingly without rhyme or reason. Appears to me that one of the functions drops the last subdirectory. Since other images (not attached to any node) go in there BEFORE we run node_submit/node_save, we know the directory is writable. (I also have it print the result of 'is_writable' first, and the directories are always writable.) Another thing I do is retrieve the fid if it exists first, and if it does, I send that instead of fid=>upload, but since I search by the file path the image SHOULD be in, it comes back empty for these messed-up-path images.
I'm hoping someone may have an idea how to fix this problem, or even what the problem is.
Programmatically creating nodes with ImageFields
Hi,
How can I change this to get it working in Drupal 6?
CCK upload fields and attachments
This custom node_save() function uploads CCK fields or files as attachments (besides handling changed value and returning the node object when done).
Usage:
$form_values['title'] = 'Demo file and picture upload';$form_values['files']['upload'] = array('http://example.com/path/to/file.pdf');
$form_values['field_my_image']['upload'] = array('http://example.com/path/to/image.png');
my_node_save('my_content_type', $form_values);
<?php
function my_node_save($node, $form_values = array()) {
if (is_string($node)) {
$node = array('type' => $node);
}
else {
$node = (array) $node;
}
$form_id = $node['type'] .'_node_form';
// If uid is set load user and fill in name.
// To circumvent uid reset in node_submit().
// @todo: roll patch for D7.
if ($form_values['uid']) {
$account = user_load(array('uid' => $form_values['uid']));
$form_values['name'] = $account->name;
}
// Store changed date - we will set it manually at end of function.
if ($form_values['changed']) {
$changed = $form_values['changed'];
}
else if ($form_values['created']) {
$changed = $form_values['created'];
}
// @todo: multiple file uploads not tested.
foreach ($form_values as $field_name => $value) {
if (is_array($value) && is_array($value['upload'])) {
foreach ($value['upload'] as $upload) {
if (!$file_data = file_get_contents($upload)) {
drupal_set_message(t('Couldn\'t read file !url', array('!url' => $upload)), 'error');
return FALSE;
}
if (!$file_temp = file_save_data($file_data, file_directory_path().'/'.basename($upload), FILE_EXISTS_RENAME)) {
drupal_set_message(t('Couldn\'t save file.'), 'error');
return FALSE;
}
$i = 0;
$file = array(
'fid' => 'upload_'. $i,
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
'list' => 1, // always list
'filemime' => mimedetect_mime($file_temp),
);
// File upload likes objects, others like arrays.
$file = ($field_name == 'files') ? (object) $file : $file;
$node[$field_name]['upload_'. $i] = $file;
$i++;
}
unset($form_values[$field_name]);
}
}
$path = explode('/', drupal_execute($form_id, $form_values, $node));
if (is_numeric($path[1])) {
$node = node_load($path[1]);
// If changed present, set manually - node_save() set changed to time().
if ($changed) {
db_query('UPDATE {node} SET changed = %d WHERE nid = %d', $changed, $node->nid);
$node->changed = $changed;
}
return $node;
}
}
?>
Twitter: http://twitter.com/lx_barth
D6 code
Above code did not work for me. Issue #292904: Mass import/upload? may help you in Drupal 6.
FileField
To attach a file in a "File" field (i.e. the field type supplied by FileField module) you have to add a "description" item to the field array, like this:
<?php
$node->field_file = array(
array(
'fid' => 'upload',
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
'list' => 1, // always list
'filemime' => mimedetect_mime($file_temp),
'description' => basename($file_temp),// <-- add this
),
);
?>
Is this also supposed to
Is this also supposed to work in D6?
Drupal 6?
I too am having trouble getting this to work in Drupal 6. The node gets created, but the CCK image field is empty.
This is the code I'm using:
$filepath = file_directory_path() . '/tmp/DSC00630.JPG';
$file_temp = file_get_contents($filepath);
$file_temp = file_save_data($file_temp, file_directory_path() .'/' . $image_unique_id . '.jpg', FILE_EXISTS_RENAME);
// Build the node.
$node = new stdClass();
$node->type = 'story';
$node->uid = $user->uid;
$node->name = $user->name;
$node->title = 'Testing Node Creation ' . time();
$node->body = 'Testing';
$node->teaser = 'Testing';
$node->status = 1;
$node->active = 1;
$node->promote = 1;
$node->field_photo = array(
array(
'fid' => 'upload',
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
'description' => basename($file_temp),
'list' => 1,
),
);
node_save($node);
print"<pre>";
print_r($node);
print"</pre>";
Did you get this working ?
I've been tearing my hair out for hours, but no luck.
Did you find a solution?
Same here
And no luck with David's post below either. =(
--
http://www.drupaler.co.uk/
Programmatically creating nodes with ImageFields drupal 6
Hi
what to change to get it working in drupal 6. I followed david's post but not working. anyhelp pls?
I have related response here:
I have related response here: http://drupal.org/node/458778#comment-1653696
This works for imagefield in Drupal 6
I uploaded the files to the dest in the files dir but I needed to associate them with the existing nodes.
Here's the code
<?phpfunction mymodule_attach_files(){
// query the db for nodes of the selected type to attach files to
$result = db_query("SELECT nid FROM {node} WHERE type = '%s'", 'supplies_equipment');
// loop through result set
while($row = db_fetch_object($result)){
// load the node object
$node = node_load($row->nid);
// add uploaded images to node data structure
// images exist in dest folder but need saving to node, check if matching file exists
if( file_exists( file_directory_path().'/images/supplies/'.$node->field_e_number[0]['value'].'.jpg' )){
// path to existing file to attach to node
// filename matches cck e-number field
$image = file_directory_path().'/images/supplies/'.$node->field_e_number[0]['value'].'.jpg';
// Load up the CCK field
$field = content_fields('field_images', 'supplies_equipment');
// 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($image, $validators, $files_path, FILE_EXISTS_REPLACE);
// Apply the file to the field, this sets the first file only, could be looped
$node->field_images = array(0 => $file);
// Save the node with image data
node_save($node);
}
}
}
?>
hope it helps.
DT
Thanks David, very clean :)
Thanks David, very clean :)
Level09 Studios
------------------
http://www.level09.com
http://www.level09.net
Creating a node with the Image module
I'm stuck trying to create the necessary array for the image_node_form.
Does anyone know what the array should contain.
<input type="file" name="files[image]" class="form-file" id="edit-image" size="40" />Programmatically creating nodes with ImageFields
How can I chnage this code to get it working in Drupal 6
<?php$node = new StdClass();
$node->type = 'official_photo';
$node->title = t('Sample official photo');
$node->taxonomy[4] = 15; // Candid shots gallery
$file_temp = file_get_contents('./profiles/multisite/files/official-photo.png');
$file_temp = file_save_data($file_temp, file_directory_path() .'/official_photos/official-photo.png', FILE_EXISTS_RENAME);
$node->field_photo = array(
array(
'fid' => 'upload',
'title' => basename($file_temp),
'filename' => basename($file_temp),
'filepath' => $file_temp,
'filesize' => filesize($file_temp),
),
);
$node->uid = 1;
$node->status = 1;
$node->active = 1;
$node->promote = 1;
node_save($node);
?>
Is it possible to insert a
Is it possible to insert a image title into each image node while using this snippet or something of the like? For example, along with the $file object, I would want a title and maybe alt text to be inserted with each object. Where would this information go?
hi2u
Only works for insert node for me
When working on a node which already exists, this function is called:
filefield_field_update($node, $field, &$items, $teaser, $page)
This one will delete every old image associated with the node and which is not present in it's third parameter.
Erlend Strømsvik
erlend@nymedia.no
Ny Media AS - www.nymedia.no
Limits on image sizes
I tried just about every code example on this page and others that I could find. Nothing worked. Just silent failure.
Eventually I realized that the images I was uploading were larger than the maximum file size I had set, and the automatic scaling down of images which would occur if I uploaded images through a web form was not being done.
So far I don't know the incantation to get drupal to scale the images as it imports them, and I think I'm just going to do it from the command line with ImageMagick.
I've been using drush to run my import script in drupal context. I'm thinking that if I'd been working through a web interface some error messages might have been displayed. Maybe there's some call I need to make to get the error messages that need displaying.
Any pointers on these issues much apreciated.
Of course
Drupal always has to upload the image before it can act on it (e.g. process a resize), so if you set an image file size that is too restrictive then it will never get as far as resizing, because it will refuse the upload.
If your intention is to upload and resize a batch of images on the server, I would remove the file size restriction for the duration of the import and let Image Field do it's thing. Then reinstate the file size limit afterwards, if you are concerned users will upload silly-big files.
See ImageCache and ImageAPI modules for more powerful dynamic image manipulation options, including ImageMagick integration within Drupal.
Hope that helps! =)
--
http://www.drupaler.co.uk/