Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PDOException on Duplicate filename in Drupal 7

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?

like image 703
Kevin Avatar asked Jan 17 '23 20:01

Kevin


2 Answers

Try this module. It fixes the issue of concurrent file object being written to db. https://drupal.org/project/upload_qc

like image 67
krylov Avatar answered Mar 06 '23 10:03

krylov


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

like image 36
Clive Avatar answered Mar 06 '23 10:03

Clive