Handling File Uploads
Last modified: January 12, 2009 - 08:24
In order to use file uploads with the Form API, you will have to include the following in your form:
<?php
$form['#attributes'] = array('enctype' => "multipart/form-data");
?>You can then handle the upload with file_check_upload. Here's an example:
<?php
function form() {
$form['#attributes'] = array('enctype' => "multipart/form-data");
//'upload' will be used in file_check_upload()
$form['upload'] = array(
'#type' => 'file');
}
function form_validate() {
if(!file_check_upload('upload')) {
// If you want to require it, you'll want to do it here... something like this:
form_set_error('upload', 'File missing for upload.');
}
}
function form_submit() {
$file = file_check_upload('upload');
//handle the file, using file_save_upload, or something similar
}
?>
This should work alright(at least in 4.7)
function render_form() {
// Form:
$form['new']['upload'] = array('#type' => 'file', '#title' => t('Upload image'), '#size' => 40);
$form['new']['attach'] = array('#type' => 'submit', '#value' => t('Upload'));
$form['#attributes']['enctype'] = 'multipart/form-data';
$output = drupal_get_form('render_form', $form);
return $output;
}
print render_form();
function render_form_submit($form_id, $form_values) {
// Submit hook:
# if ($op == t('Upload')) {
$dir = variable_get('file_directory_path', NULL); //file_create_path('files/badges'); If you want your files in a new directory
$is_writable = file_check_directory($dir, 1);
if($is_writable) {
$source = file_check_upload('upload');
// Security measure to prevent exploit of file.php.png
$source->filename = upload_munge_filename($source->filename);
if ($file = file_save_upload($source,$dir )) {
if (image_get_info($file->filepath)) {
drupal_set_message(t('New image saved.'));
} else {
file_delete($file->filepath);
drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
}
}
}
#}
}
Tree Style Forms
I'm not 100% about this, but with Drupal 5.1 it seems that if your form looks like this:
<?php
function form() {
$form['#attributes'] = array('enctype' => "multipart/form-data");
$form['itemone']['itemtwo']['upload'] = array(
'#type' => 'file');
...
return $form
}
?>
...then you need to pass "itemone" to file_check_upload(), rather than "upload" as you may be expecting.
Addition to the way drupal 5.x does file uploads.
You are correct coofercat. This is how I managed to get around that by using static text in a naming scheme such as $form['upload_1'], $form['upload_2'], etc...
if($is_writable)
{
// loop through each of the upload items
foreach($form_values as $key=>$data)
{
//print "Key: $key<br/>";
if(strpos($key, 'upload') !== FALSE) // MAKE SURE WE ARE IN A KEY FOR AN UPLOAD
{
$source = file_check_upload($key);
print "<pre>" . print_r($source, TRUE) . "</pre>";
// Security measure to prevent exploit of file.php.png
$source->filename = upload_munge_filename($source->filename);
if ($file = file_save_upload($source,$dir ))
{
if (image_get_info($file->filepath))
{
drupal_set_message(t('New image saved.'));
}
else
{
file_delete($file->filepath);
drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
}
}
}
}
}
Hope this helps anyone looking for file upload info as well.
A slightly more complete
A slightly more complete example found here: http://drupal.org/node/85922
Also, if you are associating this file with a custom node type, you may want to use file_save_upload() in your hook_insert() function when the fully populated node object is available. This is good for saving the file with a unique name and/or saving that new file name to your custom content type's table.
File uploading problem to desitnation - Solved
I was facing a problem with file_save_upload when I wanted to save a file in some destination directory. If someone may face the problem, try out http://drupal.org/node/331331