Drupal 6: Uploading a file via the Forms API and attaching it to an email
In this tutorial I’ll show how I used the Forms API to add a file upload field and attach the uploaded file in an email. I have experience using the PEAR libraries Mail and Mail_MIME to handle MIME/HTML emails and file attachments, so I decided to use them.
If you are unfamiliar with PEAR, here are a few quick tips:
# install pear via YUM (this will vary across operating system)
$ sudo yum install php-pear
# upgrade all PEAR packages
$ sudo yum upgrade-all
# check for Mail and Mail_MIME libraries
$ pear list | grep -i mail
Mail 1.1.14 stable
Mail_Mime 1.5.2 stable
# install a PEAR library
$ sudo pear install Mail
Now we can create our form callback function. NOTE: I’m keeping this form as simple as possible to focus on the file attachment functionality.
<?php
function _MYMODULE_form() {
// create an empty form array
$form = array();
// set the form encoding type
$form['#attributes']['enctype'] = "multipart/form-data";
// add a file upload file
$form['upload'] = array(
'#type' => 'file',
'#title' => t('Attach a file'),
);
// add a submit button
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
}
?>
The above will create a basic form object with a file upload file and a submit button. The form can be included using the drupal_get_form function. Example:
<?php
$html = drupal_get_form('_MYMODULE_form');
?>
Next I added a validation function to validate the file upload.
<?php
function _MYMODULE_form_validate($form, &$form_state) {
// define upload field name
// NOTE: this should match the name of your form file field
$fieldName = 'upload';
// If a file was uploaded, process it.
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;
}
else {
// set error
form_set_error($fieldName, 'Error uploading file.');
return;
}
}
?>
The above validation form will check to see if a file has been uploaded and set a form error as necessary. The last line of the function sets information about the successfully uploaded file to the $form_state array, which will then be passed to the submit handler function.
Next I created a form submit handler function which will create a Mail_Mime object, attach the file, send the email, and set a drupal message for the user to see.
<?php
function _MYMODULE_form_submit($form, &$form_state) {
// create the email subject
$subject = 'File attachment form submitted';
// create the text version of the email body
$body_text = "Dear Eric,\n\nblah blah blah.\nblah blah blah.\n\nRegards,\nEric";
// create an html version of the email
$body_html = str_replace("\n", "<br>", $body_text);
// define who receives the email
$to = "YOUREMAILADDRESS";
// include pear libraries
require_once('Mail.php');
require_once('Mail/mime.php');
// create new mail mime object
$mime = new Mail_mime("\n");
// add attachment
if ($form_state['values']['file']) {
$mime->addAttachment(
$form_state['values']['file']->filepath,
$form_state['values']['file']->filemime,
$form_state['values']['file']->filename
);
}
// set text message
$mime->setTXTBody($body_text);
// set html message
$mime->setHTMLBody($body_html);
// get message body
$body = $mime->get();
// define headers
$hdrs = array(
'From' => variable_get('site_mail','YOUREMAILADDRESS'),
'Subject' => $subject,
);
// process headers
$hdrs = $mime->headers($hdrs);
// create mail object
$mail =& Mail::factory('mail');
// send email
$mail->send($to, $hdrs, $body);
// set message to user
drupal_set_message('The file attachment form has been submitted.');
}
?>
If everything worked correctly, the form will be validated, submitted, and an email with the file attachment will be sent.