This was the most time consuming aspect for the recent port of my Document module for Drupal 7.

You would be knowing that File system API underwent a complete revamp in Drupal 7 (see this and this link, a very good introduction of the changes and new concepts is available on Randy Fay’s blog). In Drupal 6, handling file uploads was this easy:

 

{syntaxhighlighter brush: as3;fontsize: 100; first-line: 1; }$file = file_save_upload(‘file_form_field_name’, array(), ‘relative_path_to_files_folder’);
if ($file !== 0) {
//Set the status of the uploaded file.
file_set_status($file, FILE_STATUS_PERMANENT);
}{/syntaxhighlighter}

Drupal 7 has completely overhauled the File API introducing things like stream wrappers and managed/unmanaged apis etc. You would appreciate the architecture behind these changes in D7 once you understand how it works. But till you do so, it might really get onto you to get it working. And this is what happened to me during the D7 port of the Document module.

I made the following mistakes during the path (which you should avoid obviously):

  1. The first mistake I made was not to pass the stream wrapper’s scheme to the file_save_upload method. In D7 and using managed File API, you need to pass in the stream wrapper’s scheme compulsarily. I originally tried with this:
    $file = file_save_upload('document_filepath', array(), 'docs', FILE_EXISTS_RENAME);

    Here “docs” is a sub-folder inside the files folder to which I wanted to save the uploaded file to. Because I wanted to save to the public file-system path, I should have used the “public://” scheme as belows:

    $file = file_save_upload('document_filepath', array(), 'public://docs'), FILE_EXISTS_RENAME);

     

  2. The base path of the file-system you are trying to save the file to should not be passed to the file_save_upload method. Suppose your public file-system’s path is “sites/default/files”. And you want to save the uploaded file to “sites/default/files/docs”. Then this is the call you should make:
    $file = file_save_upload('document_filepath', array(), 'public://docs'), FILE_EXISTS_RENAME);

    while I originally tried with this (which was wrong):

    $file = file_save_upload('document_filepath', array(), 'public://sites/default/files/docs'), FILE_EXISTS_RENAME);
  3. Finally the uploaded file’s path in the $file object is now represented by:
    $file->uri
    in Drupal 7 as opposed to:
    $file->filepath
    in Drupal 6.

So, here’s the complete code from the Document module to handle a file upload and save it to the public file-system path:

 

{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }$file = file_save_upload(‘document_filepath’, array(), ‘public://’ . variable_get(‘document_path’, ”), FILE_EXISTS_RENAME);
if ($file) {
$fid = $file->fid;
$doc_url = file_create_url($file->uri);
//Set the status of the uploaded file.
$file->status = FILE_STATUS_PERMANENT;
file_save($file);
}
else {
drupal_set_message(t(‘Please select a document to upload.’), ‘error’);
}{/syntaxhighlighter}