I am trying to create a node based on a custom form submission. Everything works great except for the images that get uploaded.
I can capture them fine and set them in the form object cache. When I pass the data into the function to create the node, I get this error:
"The specified file could not be copied, because no file by that name exists. Please check that you supplied the correct filename."
I also receive the error multiple times, despite only submitting one or two images at a time.
Here is the code I am using. $uploads is passed in and is an array of file objects returned from file_save_upload() in a previous step:
if (isset($uploads)) {
foreach ($uploads as $upload) {
if (isset($upload)) {
$file = new stdClass;
$file->uid = 1;
$file->uri = $upload->filepath;
$file->filemime = file_get_mimetype($upload->uri);
$file->status = 1;
$file = file_copy($file, 'public://images');
$node->field_image[$node->language][] = (array) $file;
}
}
}
node_save($node);
I also tried this:
if (isset($uploads)) {
foreach ($uploads as $upload) {
$upload->status = 1;
file_save($upload);
$node->field_image[$node->language][] = (array) $upload;
}
}
}
node_save($node);
The second causes a duplicate key error in MySQL on the URI field. Both of these examples I saw in tutorials, but neither are working?
For Drupal 7, I played around with this quite a bit and found the best way (and only way that I've got working) was to use Entity metadata wrappers
I used a managed file form element like so:
// Add file upload widget
// Use the #managed_file FAPI element to upload a document.
$form['response_document'] = array(
'#title' => t('Attach a response document'),
'#type' => 'managed_file',
'#description' => t('Please use the Choose file button to attach a response document<br><strong>Allowed extensions: pdf doc docx</strong>.'),
'#upload_validators' => array('file_validate_extensions' => array('pdf doc docx')),
'#upload_location' => 'public://my_destination/response_documents/',
);
I also pass along the $node object in my form as a value
$form['node'] = array('#type' => 'value', '#value' => $node);
Then in my submission handler I simply do the following:
$values = $form_state['values'];
$node = $values['node'];
// Load the file and save it as a permanent file, attach it to our $node.
$file = file_load($values['response_document']);
if ($file) {
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
// Attach the file to the node.
$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->field_response_files[] = array(
'fid' => $file->fid,
'display' => TRUE,
'description' => $file->filename,
);
node_save($node);
}