3

I am using the Migrate module, and I need to upload a CSV file before every migration run. I've created a module that allows me to upload a file.

My first step was to make sure I had the logic correct for overwriting a file, so I have the following code:

function migrate_htmlfiles_form_alter(&$form, &$form_state, $form_id) {

if ($form_id == 'migrate_ui_dashboard_form') {
  $form['fldset'] = array(
   "#type"        => "fieldset",
   "#title"       => "CSV to Import",
   "#collapsible" => "TRUE",
   "#collapsed"   => "FALSE",
   "#weight"      => "-98",
 );
$form['fldset']['csv_file'] = array(
   "#type"   => 'managed_file',
   "#title"  => t('Choose a file'),
   "#upload_location" => 'private://user_migration',
   "#upload_validators" => array(
      "file_validate_extensions" => array('csv'),
   ),

 );

$form['fldset']['actions'] = array(
   "#type"    => 'submit',
   "#value"   => t('Uploady'),

 );

}

return $form;

}

That creates the file upload widget etc.

The following is what I do upon form submission:

 function migrate_htmlfiles_form_submit($form, &$form_state) {

  $file = file_load($form_state['values']['csv_file']);
  //TODO: rename file to user_migrate.csv
  $file->status = FILE_STATUS_PERMANENT;
  $file->replace = FILE_EXISTS_REPLACE;
  file_save($file);
}

The file uploads fine, and then when I refresh the form, and do another upload, that works but the file is not overwritten, but is incremented.

2

What you're describing is the expected behaviour for a managed_file widget. If you dig through the functions you eventually get to file_managed_file_save_upload(), which is responsible for actually saving the file.

That function calls file_save_upload() without the 4th parameter, which is $replace.

Since the default for that parameter is FILE_EXISTS_RENAME, file_save_upload() has no choice but to use in that context.

When you refresh the page, the original file that was uploaded has not been cleared up; in fact it won't be until the temp file cron job runs. So Drupal is "correctly" ensuring that the original file doesn't exist, because the managed file field is telling it to rename, not replace, files.

  • So should I just go with #type => 'file' then in my top part of the code, and leave the bottom half alone? – StevenPatz Oct 15 '13 at 15:38
  • If you use '#type' => 'file' you'll need to handle the file saving/moving/replacing etc yourself; but yes, if managed_file doesn't give you what you need, file is the next best thing – Clive Oct 15 '13 at 15:54

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.