I have a custom form where admin users upload a CSV file. Everything is working fine, but the file is saved with an underscore. For example, I upload callLog4127_Lorem_20170701.csv but the file is saved as callLog4127_Lorem_20170701_1.csv.

I checked the database, but I don't find any reference to callLog4127_Lorem_20170701. I also deleted the temp folder, and ran cron, but I am still getting the same problem.

It happens just with this file; when I upload another file it's working correctly, which means the filename is not changed.

This is my form validation handler. Is there anything wrong with it that could cause the behavior I am seeing?

function upload_rtap_validate($form, &$form_state) {
  $file = file_save_upload('calllogrtap_file', array(
    'file_validate_extensions' => array('csv'), // Validate extensions.
    'public://mrtap/', FILE_EXISTS_REPLACE

  if ($file) {
    $file = file_move($file, 'public://mrtap/', FILE_EXISTS_REPLACE);
    $file->status = 1;
    $form_state['storage']['filename'] = $file->uri;

If I print the content of $file with print_r($file), after file_save_upload(), I get the following.

stdClass Object(
  [uid] => 1
  [status] => 0
  [filename] => callLog4127_GentleDental_20170701.csv
  [uri] => temporary://callLog4127_GentleDental_20170701_4.csv
  [filemime] => text/csv
  [filesize] => 48429
  [source] => calllogrtap_file
  [destination] => temporary://callLog4127_GentleDental_20170701_4.csv
  [timestamp] => 1501309335
  [fid] => 235
  • As side note, that code is moving the file twice: once with file_save_upload(), and once with file_move(). – kiamlaluno Jul 29 '17 at 10:22
  • What you are showing is the form validation handler, but what does the form submission handler do? – kiamlaluno Jul 29 '17 at 10:39
  • In submit just insert data in custom table – Pankaj Yogi Jul 29 '17 at 10:46

The main error is that you aren't passing the last two arguments of file_save_upload() to that function, since you are putting them in the array you pass as second argument. The code you are using is the following one; see the comments I added.

  $file = file_save_upload('calllogrtap_file', array(
    // First line of the array
    'file_validate_extensions' => array('csv'),
    'public://mrtap/', FILE_EXISTS_REPLACE
    // Last line of the array

As you aren't passing the last two arguments to file_save_upload(), the function is using the default values for those parameters, which are:

  • $destination = FALSE
  • $replace = FILE_EXISTS_RENAME

The first values is making Drupal save the uploaded file in temporary://; the second value is telling Drupal to rename the file if there is already a file with that name.

The function call should be the following one.

  $file = file_save_upload('calllogrtap_file', array('file_validate_extensions' => array('csv')), 'public://mrtap/', FILE_EXISTS_REPLACE);

If you change the code in this way, then the following code line is not necessary, since the uploaded file is already moved in public://mrtap/ from the call to file_save_upload().

$file = file_move($file, 'public://mrtap/', FILE_EXISTS_REPLACE);

If filename is the ID of the form element for uploading the file, the following code probably needs to be changed.

$form_state['storage']['filename'] = $file->uri;

Probably, the correct line is the following one.

$form_state['values']['filename'] = $file;

I would also keep the code to validate the user input in upload_rtap_validate(), and the code saving the file as managed file in upload_rtap_submit().
For example, see the code used from the form handlers for system_theme_settings(), system_theme_settings_validate() and system_theme_settings_submit(). (I replaced the comments with mine.)

  // system_theme_settings_validate()
  $file = file_save_upload('logo_upload', $validators);
  if (isset($file)) {
    // The user upload the logo file.
    if ($file) {
      // The uploaded file passed the validation in $validators.
      $form_state['values']['logo_upload'] = $file;
    else {
      // The file upload failed.
      form_set_error('logo_upload', t('The logo could not be uploaded.'));
  // system_theme_settings_submit()
  // If the user uploaded a new logo, save it to a permanent location.
  if (!empty($values['logo_upload'])) {
    $file = $values['logo_upload'];
    $filename = file_unmanaged_copy($file->uri);
    $values['default_logo'] = 0;
    $values['logo_path'] = $filename;
    $values['toggle_logo'] = 1;

In your case, you could use file_copy() instead of file_unmanaged_copy(), or file_save() as your code is doing.

  • Basically this, and also one of my main issues with the core file field. But since this is in custom code, FILE_EXISTS_REPLACE is the way to go. – Kevin Jul 29 '17 at 20:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.