File always save with underscore 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, &amp;$form_state) {
  $file = file_save_upload('calllogrtap_file', array(
    'file_validate_extensions' =&gt; array('csv'), // Validate extensions.
    'public://mrtap/', FILE_EXISTS_REPLACE
  ));

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


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

stdClass Object(
  [uid] =&gt; 1
  [status] =&gt; 0
  [filename] =&gt; callLog4127_GentleDental_20170701.csv
  [uri] =&gt; temporary://callLog4127_GentleDental_20170701_4.csv
  [filemime] =&gt; text/csv
  [filesize] =&gt; 48429
  [source] =&gt; calllogrtap_file
  [destination] =&gt; temporary://callLog4127_GentleDental_20170701_4.csv
  [timestamp] =&gt; 1501309335
  [fid] =&gt; 235
 )
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' =&gt; 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' =&gt; 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-&gt;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'];
    unset($values['logo_upload']);
    $filename = file_unmanaged_copy($file-&gt;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.