File upload via Form API

Andrei Toutoukine - September 25, 2006 - 15:23

Dear Drupal developers,

I'm trying to upload a file to the server via module, using Forms API. Form is displayed via menu callback as expected. However file is not uploaded. Here's my code:

<?php
function date_pic_settings_form()
{
// Not very interesting code is skipped

   
if( user_access('date_pic manager') ) {
   
$form['font'] = array(
       
'#type' => 'file',
       
'#title' => 'TTF font file',
    );
   
   
$form['#attributes'] = array('enctype' => "multipart/form-data");
    }
   
   
$form['submit'] = array('#type' => 'submit', '#value' => t('Set week N&ordm;') );
    return
$form;
}

function
date_pic_admin_page()
{
// ......
   
$out .= drupal_get_form('date_pic_settings_form', date_pic_settings_form() );
// ....
   
print theme('page', $out);
}

function
date_pic_settings_form_validate($form_id, $form_values)
{
    if(!
$file=file_check_upload('font') ) {
       
form_set_error('font', t('Font file unavailable!') );
    }
}

function
date_pic_settings_form_submit($form_id, $form_values)
{
    if( isset(
$form_values['font']) && user_access('date_pic manager') ) {
       
$dir = drupal_get_path('module', 'date_pic') . '/fonts';

        if(
file_check_directory( $dir ) ) {
           
$file = file_save_upload('font', $dir, true);
           
variable_set('date_pic_font', $dir . '/' . $file);
        } else {
           
drupal_set_message( t('WARNING: Server DIR is not accessible. Consult with site admin!', 'status') );
        }
    }

}
?>

Playing with var_dump($form_values) I figured out that both in _validate and in _submit hooks $form_values['font'] is NULL!

What's wrong???

Solved

Andrei Toutoukine - September 26, 2006 - 08:41

Well, actually there are several things wrong.

1. File upload API must be understood correctly: Somehow uploads are available to functions file_check_upload() and file_save_upload(). In form_validate() one must check if upload was shipped to the server, and in submit one has to save it under appropriate name. Forget about $form_values, the universal file identifier which corresponds to form element's name should be used.

2. Upload files into the proper place. Better if it is your files/ directory. Check at least, if web-server can write there.

The correct code is:

<?php
function date_pic_settings_form()
{
//....
   
$form['font'] = array(
       
'#type' => 'file',
       
'#title' => 'TTF font file',
    );
   
   
$form['#attributes'] = array('enctype' => "multipart/form-data");
// ...
   
   
$form['submit'] = array('#type' => 'submit', '#value' => t('Set week N&ordm;') );
    return
$form;
}

function
date_pic_settings_form_validate($form_id, $form_values)
{
    if(!
$file=file_check_upload('font') ) {
       
form_set_error('font', t('Font file unavailable!') );
    }
}

function
date_pic_settings_form_submit($form_id, $form_values)
{
// ...
        // do something with the filename!
       
$dir = 'files/fonts'; // must be " variable_get('file_directory_path', 'files') . '/fonts' "

       
if( file_check_directory( $dir ) ) {
           
$dir .= '/font.ttf'; // not good. to be changed in future
           
$save = file_save_upload('font', $dir, true);
            if(!
$save) {
               
drupal_set_message('ERROR downloading the file to ' . $dir);
            } else {
               
drupal_set_message('The file: <strong>"' . $save->filename . '"</strong> is successfully uploaded');
            }
           
variable_set('date_pic_font', $dir . '/' . $file);
        } else {
           
drupal_set_message( t('WARNING: Server DIR is not accessible. Consult with site admin!', 'status') );
        }
// ...
}
?>

Hope the other module developers find the right way easier with this post.

 
 

Drupal is a registered trademark of Dries Buytaert.