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º') );
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
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º') );
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.