Using the following code:
foreach ($form_state['values']['uploads'] as $key => $value) {
if (strlen($value)) {
$file = file_save_upload($key, array(
'file_validate_is_image' => array(), // Validates file is really an image.
'file_validate_extensions' => array('png gif jpg jpeg'), // Validate extensions.
));
// If the file passed validation:
if ($file) {
// Move the file, into the Drupal file system
if ($file = file_move($file, 'public://')) {
// Save the file for use in the submit handler.
$form_state['values']['uploaded_photos'][] = $file;
$x++;
} else {
form_set_error($key, t('Failed to write the uploaded file the site\'s file folder.'));
}
}
}
}
I am trying to save images attached to a form into a cached object with CTools. All of that was working fine, until I tried uploading the same file again, and I got a white screen that said "Error - The website encountered an error." (ripped from watchdog):
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'public://ad-10.jpg'; for key 2: UPDATE {file_managed} SET uid=:db_update_placeholder_0, filename=:db_update_placeholder_1, uri=:db_update_placeholder_2, filemime=:db_update_placeholder_3, filesize=:db_update_placeholder_4, status=:db_update_placeholder_5, timestamp=:db_update_placeholder_6
WHERE (fid = :db_condition_placeholder_0) ; Array
(
[:db_update_placeholder_0] => 0
[:db_update_placeholder_1] => ad-10.jpg
[:db_update_placeholder_2] => public://ad-10.jpg
[:db_update_placeholder_3] => image/jpeg
[:db_update_placeholder_4] => 4912
[:db_update_placeholder_5] => 0
[:db_update_placeholder_6] => 1326221376
[:db_condition_placeholder_0] => 834
)
";s:9:"%function";s:21:"drupal_write_record()";
Since I am not setting the $replace argument, shouldn't it default to FILE_EXISTS_RENAME and therefor not throw this error? How can I resolve this?
Try this module. It fixes the issue of concurrent file object being written to db. https://drupal.org/project/upload_qc
I can't comment as to why that doesn't work (it looks like it certainly should) but I can offer a simpler solution.
Drupal actually has a form widget built-in to handle file uploads, the managed_file
type. It handles all of the file uploading/validating for you, you just need to mark the files as permanent in your form's submit handler.
So in your form function:
$form['files'] = array('#tree' => TRUE);
for ($i = 0; $i < $num_file_fields; $i++) {
$form['files']["file_$i"] = array(
'#type' => 'managed_file',
'#title' => 'Select a file',
'#upload_location' => 'public://',
'#upload_validators' => array(
'file_validate_is_image' => array(),
'file_validate_extensions' => array('png gif jpg jpeg')
)
);
}
And then in your submit handler:
$count = count($form_state['values']['files']);
for ($i = 0; $i < $count; $i++) {
$file = file_load($form_state['values']['files']["file_$i"]);
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
Hope that helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With