|
This HOW TO guide describes the steps required to configure your HTML form and
FormMail to allow file uploads.
FormMail can email uploaded files to your or store them on your server.
Your HTML Form
Firstly, the HTTP protocol requires that you specify a particular encoding for
the form submission. This encoding is specified in the HTML form tag
with the enctype attribute.
<form method="post" action="http://your-site.com/formmail.php"
name="SampleForm" enctype="multipart/form-data">
NOTE: HTML requires you to specify method="post" and
enctype="multipart/form-data",
as shown. Without these two attributes, file uploads will not work properly.
Next, you create form fields to specify file uploading. FormMail does not
place a limit on the number of files you can upload.
<p>File to upload: <input type="file" name="first_file" /></p>
<p>File to upload: <input type="file" name="second_file" /></p>
FormMail
File uploading can represent a minor security problem for you. For example, an
attacker could bypass your HTML form and use FormMail to send you many unwanted
files. For this reason, the default for FormMail is to disallow file uploads.
To enable file uploads, look for the FILEUPLOADS setting in
FormMail's configuration section and set it to "true", like this:
define("FILEUPLOADS",true); // set to true to allow file attachments
Your Server
Most PHP installations allow file uploads by default. You may, however,
need to contact your hosting provider and ask them to enable file uploads.
The setting is in the server's php.ini file and is called
upload_tmp_dir.
Limiting the File Upload Size
There is usually a maximum file size allowed for uploading files in PHP.
This setting is also specified in the
php.ini file
and is called
upload_max_filesize.
The default is usually 2 megabytes. If you need a larger
limit, you may need to contact your hosting provider.
On some servers, you can override this yourself in your own .htaccess
file:
php_value upload_max_filesize "3M"
this will set the upload limit to 3 megabytes for a FormMail script located
in the same directory
as the .htaccess file.
If you want a smaller maximum size for file uploads, PHP supports a
hidden field called MAX_FILE_SIZE:
<input type="hidden" name="MAX_FILE_SIZE" value="25000" />
In this example, PHP will limit the file uploads to 25,000 bytes. Note,
however, this is easily bypassed by an attacker, so you shouldn't rely on it to
protect you or your server.
Therefore, FormMail provides you with a secure way of limiting
the size of uploaded files. In the configuration section look for
MAX_FILE_UPLOAD_SIZE:
define("MAX_FILE_UPLOAD_SIZE",30); // default of 0 means that other software
FormMail interprets this setting in kilobytes. So, 30 means 30,720
bytes. If you set this value to zero, then FormMail does not enforce a
limit on the uploaded file size (so any limit imposed will be by other systems as described above).
Very Large Files
If you need to allow users to upload very large files, there are several
settings inside PHP that can affect this operation:
- upload_max_filesize
- max_input_time
- post_max_size
- memory_limit
- session.gc_maxlifetime
Your hosting provider controls these settings, but may provide a way for you
to override them.
Using Conditions and Required
FormMail allows your HTML forms to control your user's file uploads
using required and conditions. Review the HOW TO guide for these
features for full details. Briefly, when you use the name of a file field in
required, FormMail checks whether a file has been uploaded.
When you use the name of a file field in a conditions string comparison,
FormMail substitutes the name of the file the user uploaded (the name of the
file on the user's computer).
When used in a conditions numeric
comparison, FormMail substitutes the size of the file in bytes.
Here's an example of checking that a file has been uploaded using required:
<input type="hidden" name="required" value="first_file:Please upload a
file." />
This is the same example using conditions:
<input type="hidden" name="conditions1" value=":@
@TEST@first_file@Please upload a file.@" />
Here's an example of checking the file name provided the file has been uploaded (this
example checks that the file ends in .pdf):
<input type="hidden" name="conditions1" value=":@
@IF@first_file@first_file~/^.*\.pdf$/i@@You can only upload PDFs@" />
Here's an example of checking the file size provided a file has been uploaded:
<input type="hidden" name="conditions1" value=":@
@IF@first_file@first_file#<10240@@Maximum file upload size is 10 kilobytes.@" />
This example checks that the file has been uploaded and checks the name of the file and
its size:
<input type="hidden" name="conditions1" value=":@
@TEST@first_file@Please upload a file.@:
@TEST@first_file~/^.*\.(pdf|jpg|jpeg|gif|png)$/i@You can only upload PDF or
graphics files@:
@TEST@first_file#<10240@Maximum file upload size is 10 kilobytes.@" />
Storing Uploaded Files on the Server
By default, FormMail attaches uploaded files to the email it sends you with
the results of the form submission. You can, however, direct FormMail to
store uploaded files on your server instead of emailing them to you.
To do this you need to create a directory or folder on your server. We
call this the file repository. The file repository can be within or outside
your web server document root. If you want to ensure the files are not
downloadable from the web, we recommend you put the file repository outside
(above) the document root.
The file repository must be writable by the web server software. In most
cases this means you need to "chmod" the directory you create as mode
777 or rwxrwxrwx.
Once you've created the directory for the file repository, you need to know
its full pathname. You then set this value in FormMail's configuration
setting called $FILE_REPOSITORY:
$FILE_REPOSITORY = "/home/your-site/filerepos";
The actual directory or folder path will depend on your server.
Setting File Permission Modes
When an uploaded file is stored on your server you may want to control the
permission modes. You can control the file permission
modes with the FILE_MODE
configuration setting in FormMail. Review the documentation above this
setting in formmail.php for full details.
Renaming Files
You can direct FormMail to rename the files that are uploaded. For example,
your users will typically upload files with a variety of different names. In
particular, you may want to indicate which field the file was uploaded in if
your form allows multiple file uploads.
You rename files using the file_names hidden field. The syntax and
features of this field are similar to deriving fields from other fields.
In particular, the nextnum function will be important if you want to store
files on your server.
This example prefixes the file name with a field identifying string:
<input type="hidden" name="file_names" value="
first_file=%'File1-'%.first_file,
second_file=%'File2-'%.second_file" />
This example prefixes the file name with the date:
<input type="hidden" name="file_names"
value="first_file=%date%.first_file" />
This example identifies the two files uploaded by
the users who uploaded them:
<input type="hidden" name="file_names"
value="first_file=realname.%'-file1'%,
second_file=realname.%'-file2'%" />
The file_names feature does two things:
- Sets the name of the uploaded file for storage or email attachment.
- Creates (derives) a new field called "name_of_X", where X is the name
of the file field. You can use this new field just like any other
derived field. The above examples would create new fields called
"name_of_first_file" and "name_of_second_file",
whose values would be the new names for the files. Note however,
the creation of the "name_of_" fields occurs after
normal field derivations, so you cannot use these new fields in
a derive_fields specification.
File renaming works with files stored on the server and also files attached
to email.
Note that the original uploaded file name (the file on the form submitter's
computer) is always available as the file name field.
So, "first_file" is the original file name and
"name_of_first_file" is the new name of the file that you've
chosen.
Rename But Keep File Extension
For download links and general application requirements, when you rename a
file you will generally want to keep the original file extension or type.
For example, if the uploaded file is a JPEG, then you want to keep the
".jpg" extension.
To do this, you use the %ext% feature, which provides the file extension.
However, it doesn't include the leading period, so you need to prepend that
using %2E%.
<input type="hidden" name="file_names"
value="first_file=realname.%'-file1'%.%2E%.%ext(first_file)%,
second_file=realname.%'-file2'%.%2E%.%ext(second_file)%" />
Illegal Characters in File Names
It's important to remember that your users may use different operating systems
with different rules for file names.
For example, a user might upload a file with a character that cannot be used in
a file name when the file is stored on your server.
Therefore, you will generally need to use the file renaming features of
FormMail as described above.
Working with Multi-Page Forms
To use file uploads with multi-page forms, you must set
SCRATCH_PAD
in FormMail's configuration section. This is required so that FormMail
can save uploaded files in your private temporary folder when moving between
the pages of your multi-page form.
Advanced Features for Multi-Page Forms
FormMail's multi-page features
and file uploading can be used
for very advanced and complex forms processing. Especially
when combined with our FormMail Computation Module and Advanced Templates.
In these cases, you sometimes need to distinguish between files just uploaded
from a page and files that were previously uploaded and saved to your
file repository (see above).
Prior to version 8.13 of FormMail, the file field name would sometimes
refer to a newly uploaded file and sometimes refer to the file previously
stored in the repository. For very complex processing, this ambiguity
was not helpful.
From version 8.13 of FormMail, the file field name on a submitted form now
only refers to the file just uploaded (if any). Also, when a file is saved to the
repository, FormMail creates a new field name that you can use to refer to the
file so saved. The field name begins with the prefix "repository_". When the
file is also renamed (see the renaming feature above), the new name of the
file stored in the repository is a field with the prefix
"repository_name_of_".
For example, suppose a page in your multi-page form sequence has a file upload
field called "photo". On the next page (which will be a template page) and in email templates and other
processing, you can refer to that uploaded file as "$photo", and, if renamed, its new name as
"$name_of_photo".
If you've configured FormMail to save files to the repository, on subsequent
pages your repository file can be referenced as
"$repository_photo", and if it was renamed, "$name_of_repository_photo".
|