Starting with version 2.00, FormMail supports the concept of deriving fields from other fields.
Here are some issues that derived fields solve:
- you want to ask people for their First Name and their Last Name separately, but FormMail insists on having a "realname" field (a single field containing the whole name);
- you want to store the date and time of the form submission, along with the data, in a CSV file, but you don't want to rely on JavaScript in the form;
- you want to include the date and time of the form submission in the email that you get sent;
- you want your own field name for a person's email address - you don't want to be stuck with "email", which FormMail requires.
To derive a field, you simply add a hidden field specification in your form, like this:
<input type="hidden" name="derive_fields" value="specification" />
The specification part is a comma-separated list of field derivations.
A field derivation looks like this:
DerivedField = Value1 joiner Value2 joiner Value3...
A Simple Field Derivation
Here's an example of a simple field derivation. It allows you to call your field "EmailAddress", and also provide the special "email" field to FormMail:
email = EmailAddress
The complete entry in your form would be:
<input type="hidden" name="derive_fields" value="email = EmailAddress" />
This says to FormMail: create a new field called email and give it the same value as the field EmailAddress in the form submission.
And somewhere in your form you would have this field:
<input type="text" name="EmailAddress" />
Joining Two Fields to Create a Third
FormMail uses the special field "realname" to tell you who the form submission is from. But suppose you want to ask people their first and last name separately - in two fields.
To solve this, you can derive "realname" from the two separate name fields:
realname = FirstName + LastName
The "+" is a joiner. It tells FormMail to join the values of the fields FirstName and LastName together with a single space between them. The "+" joiner is intelligent; it won't add the space if the following field is empty.
For example, suppose I enter my name "Russell" into your FirstName field, but I don't enter anything into LastName. The "+" joiner will create a realname field that contains "Russell" - no extra space added to it.
There are several joiners available:
+ | joins fields together with a single space, but only if the following field is not empty |
---|---|
. | joins fields together with no space added between |
* | joins fields together and always adds a single space between |
So, to derive the two fields email and realname, your form field entry would be:
<input type="hidden" name="derive_fields"
value="email = EmailAddress, realname = FirstName + LastName" />
Special Values
FormMail can insert a date or time value when you're deriving a field.
Date = %date%
will create a field called Date, containing the current date on the server in this format:
DD-MMM-YYYY
(e.g. 01-Jan-2005)
Similarly for time:
TheTime = %time%
will create a field called TheTime, containing the current time on the server in this format:
HH:MM:SS
(e.g. 14:30:02)
You can also specifiy parts of dates and times - see below for more information.
Literals
When deriving a new field, you can use existing fields and also literal values.
A literal value is any string surrounded by '%' and single quotes:
%'This is a literal value'%
For example, suppose you wanted a new field which showed the date and time with a prompt:
DateTime = %'Date of form submission was: '% . %date% + %time%
The field DateTime will look like this:
Date of form submission was: 13-May-2004 22:54:06
To get a single quote literal, use this:
%'''%
Date and Time Components
The following shows the special values you can use to get various components of the date and time:
This string... | Expands to... |
---|---|
%ampm% | lower case "am" or "pm" depending on morning or afternoon |
%AMPM% | upper case "AM" or "PM" depending on morning or afternoon |
%dom0% | the day of the month with a leading zero for 01 to 09 |
%dom% | the day of the month with no leading zero |
%day% | the abbreviated day name (Mon thru Sun) |
%dayname% | the full day name (Monday thru Sunday) |
%daysuffix% | the English suffix for a day number (st for 1, nd for 2, rd for 3, th for 4, 5, 6, and so on) |
%moy0% | the month of the year with a leading zero for 01 to 09 |
%moy% | the month of the year with no leading zero |
%month% | the abbreviated month name (Jan thru Dec) |
%monthname% | the full month name (January thru December) |
%year% | the last two digits of the year (00 thru 99) |
%fullyear% | the full year (e.g. 2000, 2001, 2002) |
%rfcdate% | the RFC822 formatted date (e.g. Thu, 21 Dec 2000 16:01:07 +0200). Requires PHP 4.04 or above |
%tzname% | the timezone name |
%tz% | the timezone difference from Greenwich (e.g. +0200) |
%hour120% | the hour of the day in 12-hour notation with leading zero for 01 thru 09 |
%hour12% | the hour of the day in 12-hour notation with no leading zero |
%hour240% | the hour of the day in 24-hour notation with leading zero for 01 thru 09 |
%hour24% | the hour of the day in 24-hour notation with no leading zero |
%min% | the minute of the hour |
%sec% | the second of the minute |
A Complex Specification
Here is a sample derived fields specification which is somewhat complex:
<input type="hidden" name="derive_fields" value="email = EmailAddress,
Date=%dom0%.%'-'%.%moy0%.%'-'%.%year%,
Time=%time%" />
This will create:
- a field called Date which looks like this: 04-09-11 (on the 4th September, 2011)
- a field called Time which looks like this: 09:15:00 (at quarter past nine in the morning)
- a field called email which is a copy of the field called EmailAddress
File Uploads
From version 7.06 of FormMail, if you use a file upload field name in a derivation, the name of the file on the user's computer is substituted.
For example, supposed you have a file upload field called "your_picture" and the user uploads a file called "photo.jpg" from their computer with this field. The following derivation will create a field called "photo_id" with the value "15-6-2006photo.jpg":
<input type="hidden" name="derive_fields" value="photo_id=%date%.your_picture" />
You can also derive a field containing the size of the uploaded file. See Other Functions below.
Conditional Derivation
From version 7.07 of FormMail, you can derive a field based on a simple conditional test. The syntax is:
%if(field_name;then-spec;else-spec)%
If the given field is empty, then the else-spec is used, otherwise the then-spec is used to derive the field.
Here's an example which creates a message field depending on whether a file was uploaded:
<input type="hidden" name="derive_fields"
value="upload_mesg=%if(your_picture;%'Picture was uploaded'%;%'No picture was uploaded'%)%" />
Obtaining Server Values
You can create a derived field using the special names of Server Variables. Note: this feature is only available in FormMail version 5.02 or later.
Server Variables are provided by PHP and often contain useful information. A common use is to obtain the user's IP address or browser type.
All the available Server Variables are defined here: www.php.net/reserved.variables, under the heading $_SERVER.
You can also obtain Environment variables this way, but their availability is not well defined, except for the CGI interface.
The following example shows how to obtain the user's IP address, browser type, and the referring page:
<input type="hidden" name="derive_fields" value="ipaddr = REMOTE_ADDR,
browser = HTTP_USER_AGENT, referrer = HTTP_REFERER" />
Use in CSV Files
As you probably already know, FormMail supports the creation of CSV files. If you want to put your derived fields in your CSV file (a common use of dates and times), just refer to the field you've created.
Here's an example:
<input type="hidden" name="csvcolumns" value="firstname,lastname,email,Date,Time" />
(where Date and Time are derived fields, like in the previous section).
Special Characters
As at version 2.09 of FormMail, you can insert any ASCII value into a field. You do this by using the character's hexadecimal value.
The syntax is simple:
%XX%
where XX is the hexadecimal value (in upper case).
Below we've shown several special characters together with the %XX% value you need to use:
, | %2C% | (comma) |
---|---|---|
' | %27% | (single quote) |
+ | %2B% | (plus sign) |
. | %2E% | (dot/period/full stop) |
* | %2A% | (asterisk) |
% | %25% | (percent sign) |
The following (rather complicated-looking) example joins some text and special characters together to create a field called HexTest.
<input type="hidden" name="derive_fields"
value="HexTest = %'comma:'%.%2C%.%' quote:'%.%27%.%' plus:'%.
%2B%.%' dot:'%.%2E%.%' asterisk:'%.%2A%.%' percent:'%.%25%" />
This example creates a date field with '.' separating the numbers:
<input type="hidden" name="derive_fields" value="Date = %dom0%.%2E%.%moy0%.%2E%.%fullyear%" />
Other Functions
Beginning with version 7.12 of FormMail, derive_fields supports a number of useful functions for extracting or modifying the values of fields. These functions are described below.
size | This function returns the size of an uploaded file in bytes. You provide the field name of the file upload and FormMail sets the derived field with the size of the file. If the field you use in the size function does not represent an uploaded file (no file was uploaded or the field is not a file field), then the size function returns an empty value. |
---|---|
ext | This function returns the extension of an uploaded file. You provide the field name of the file upload and FormMail sets the derived field with the extension of the file (the extension is the part of the file name after the last '.' - it's also known as the file type). For example, the extension of 'names.txt' is 'txt'. If the field you use in the ext function does not represent an uploaded file (no file was uploaded or the field is not a file field), then the ext function returns an empty value. |
ucase |
These functions return the given field value with all alphabetic characters converted to upper or lower case, respectively. The characters that are determined to be alphabetic characters are determined by the current locale that your PHP system is set for. |
ltrim |
These functions return the given field value with whitespace removed. Whitespace is defined by PHP as:
ltrim removes whitespace from the left hand side of the field, rtrim removes whitespace from the right hand side of the field, and trim removes whitespace from both sides. |
ltrim0 | This function returns the given field value with zeroes removed from the left hand side (i.e. leading zeroes are removed). For example, a field value of '00012' would be returned as '12'. |
nextnum | This function returns a number which increments on each form submission. You can use this value as a unique number or a sequence number. Note that it's possible for there to be gaps in the values (you can't rely on the numbers being sequential) due to user or other errors. To enable this function, you must create a file on your server in which FormMail will store the next number to be returned. For instructions on how to do this, see the NEXT_NUM_FILE configuration setting. You can also specify an optional padding amount and an optional base or radix for the number returned. The format is: Both pad and base are optional, but if you want to use base, you must also specify pad. The padding value ensures you get no less than that many digits padded on the left with zeroes. |
Using Functions with Conditional Derivation
Due to size requirements, there are limits to the amount of parsing FormMail can perform on derive_fields. So, in order to use the special functions or multiple conditionals, you must perform your complex derivations in stages.
For example, suppose you want to include the size of an uploaded file in a message field you need to create. Using the earlier Conditional Derivation example, you could change this:
<input type="hidden" name="derive_fields" value="
upload_mesg=%if(your_picture;%'Picture was uploaded'%;%'No picture was uploaded'%)%" />
to this:
<input type="hidden" name="derive_fields" value="
upload_size=%size(your_picture)%,
upload_mesg=%if(your_picture;%'Picture was uploaded with size '%.
upload_size;%'No picture was uploaded'%)%" />
Limitations
Languages other than English may not be supported with the date-time Day name and Month name expansions. Feedback on this would be appreciated, and we may be able to resolve any issues in a future version.
Enjoy!