Last updated January 25, 2010. Created by AlexisWilke on January 22, 2007.
Edited by nicksanta, add1sun, Darren Oh, bradlis7. Log in to edit this page.
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
}
?>
Comments
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.
Anthony Wlodarski
PHP/MySQL Developer
www.thrillist.com
560 Broadway, Suite 308
New York, NY 10012
p 646.274.2435
f 646.557.0803
Come on!
It has been more than THREE YEARS since someone noticed this awful behaviour on Drupal 5! And it's still present on 6? That's just ridiculous.
Still not fixed...
Seems people even tried to provide a patch but the patch failed the tests. Sad that this is still an issue.
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.
Be well,
R.J. Steinert III
RjSteinert.com
"Happiness is the process not the place."
-Diener
file_check_upload() does not
file_check_upload() does not exist in Drupal 6.x
Example using Drupal 6 BUT not enought: module alternative
Yes, it has been cleared from Drupal 6.
I've found a working example using Drupal 6:
http://thedrupalblog.com/uploading-file-forms-api-and-attaching-it-email
You have to use file_save_upload. Continuing the example of this page:
$fieldName = 'upload';
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$fieldName])) {
// attempt to save the uploaded file
$file = file_save_upload($fieldName);
// set error if file was not uploaded
if (!$file) {
form_set_error($fieldName, 'Error uploading file.');
return;
}
// set files to form_state, to process when form is submitted
$form_state['values']['file'] = $file;
}
(code borrowed from the above link)
As you see you may check if file was uploaded using first if sentence.
$fieldname is set to 'upload' because is the name used in the $form definition in the example.
BUT uploaded file info is lost if validation fails. Not a funny thing. To avoid that you must track file info with $_SESSION PHP var. Luckily, there's a module that does that:
http://drupal.org/project/upload_element
The same funcionality is included in D7, so only needed for D6.
In Drupal 6.x you can use
In Drupal 6.x you can use http://api.drupal.org/api/function/file_save_upload/6
Déja Augustine
A note should be added that,
A note should be added that, file uploads should be stored in a subdirectory under drupal's main files directory, for security reasons.
enctype
Note that as of Drupal 7 the Form API automatically sets the
enctype="multipart/form-data"
, so you don't have to.--Andy
Developing Drupal websites for Livelink New Media