Wednesday, September 29, 2010

Css Tutorial : Sending feedback

In this section, you’ll check out how to send form data using a CGI script and PHP. Once
users submit information, it needs to go somewhere and have a method of getting there.
Several techniques are available for parsing forms, but we’re first going to cover using a
server-side CGI script. Essentially, this script collects the information submitted, formats it,
and delivers it to the addresses you configure within the script.
FormMail, available from Matt’s Script Archive (www.scriptarchive.com), is probably the
most common, and a number of web hosts preconfigure this script in their web space
packages. However, FormMail does have flaws, and it hasn’t kept up with current technology.
A better script is nms FormMail (available from http://nms-cgi.sourceforge.net/
and described next)—it emulates the behavior of FormMail but takes a more modern and
bug-free approach.

Configuring nms FormMail
 
The thought of editing and configuring scripts gives some designers the willies, but nms
FormMail takes only a couple of minutes to get up and running. First, you need to add
some more input elements to your web page, after the form start tag:
<input type="hidden" name="subject" value="Contact form from
å website" />
<input type="hidden" name="redirect"
å value="http://www.yourdomain.com/contact-thanks.html" />
Obviously, the values in the preceding elements need changing for your site. The subject
value can be whatever you like—just make it obvious, so you or your clients can use an
e-mail package to filter website form responses efficiently.
The redirect value isn’t required, but it’s good to provide positive feedback to users, not
only to confirm that their form has been sent, but also to communicate that their query
will be dealt with as soon as possible. Many “thank you” pages online tend to look a little
barren, with a single paragraph of text. That’s why I tend to make this page a duplicate of
my standard contact page, but with the confirmation paragraph above the form. The script
itself needs only minimal editing. Because CGI scripts tend to break with slight errors, I
highly recommend editing them in a text editor that doesn’t affect document formatting,
such as HTML-Kit for Windows (www.chami.com) or BBEdit for Mac (www.barebones.com).
The first line of the script defines the location of Perl on your web host’s server. Your hosting
company can provide this, so you can amend the path accordingly.
#!/usr/bin/perl -wT
Elsewhere, you only need to edit some values in the user configuration section. The
$mailprog value defines the location of the sendmail binary on your web host’s server.
You can find this out from your web host’s system admin.
$mailprog = '/usr/lib/sendmail -oi -t';
The $postmaster value is the address that receives bounced messages if e-mails cannot be
delivered. It should be a different address from that of the intended recipient.
$postmaster = 'someone@your.domain';
The @referers value lists IP addresses or domain names that can access this script, thereby
stopping just anyone from using your script and your server resources. For instance, the
Snub Communications mail form has snubcommunications.com and the site’s IP address
for this value (as a space-delimited list). If you use localhost, that enables local testing, if
you have the relevant software set up on your PC.
@referers = qw(dave.org.uk 209.207.222.64 localhost);
The @allow_mail_to value contains the addresses to which form results can be sent, again
as a space-delimited list. If you include just a domain here, then any address on that
domain is valid as a recipient. If you’re using only one address, set the $max_recipients
value to 1 to increase security.
@allow_mail_to = qw(you@your.domain some.one.else@your.domain
å localhost);

Multiple recipients

You can also use the script to e-mail multiple recipients. To do so, an additional hidden
input element is needed in the HTML:
<input type="hidden" name="recipient" value="emailgroup" />
And in the script itself, two lines are changed. The @allow_mail_to value is removed,
because it’s catered for by the newly amended %recipient_alias. Both are shown here:
@allow_mail_to = ();
%recipient_alias = ('emailgroup =>
å 'your-name@your.domain,your-name@somewhere-else.domain');
Should a script be used for multiple groups of recipients, you need a unique value for each
in the HTML and to amend the %recipient_alias value accordingly:
%recipient_alias = ('emailgroup1' => 'your-name@your.domain,your-name@
åsomewhere-else.domain', 'emailgroup2' => 'foo@your.domain');

Script server permissions

Upload the script to your site’s cgi-bin. Once there,
the script’s permissions must be set. Exactly how this is
achieved depends on what FTP client you’re using.
Some enable you to right-click and “get info,” while
others have a permissions or CHMOD command buried
among their menus. Consult your documentation and
find out which your client has. If you can, use the
CHMOD command to set the octal numbers for the
script (thereby altering the file permissions) to 755. If
you have to manually set permissions, do so as per the
screenshot to the right. Check that the script’s file
extension matches that in your form element’s action
attribute (.pl or .cgi—the latter is usually preferred
by servers). Also, you might want to amend your
script’s name (and update the form element’s action
value accordingly), in an attempt to outfox automated
spammers. (This explains the rather odd name of the
script in the adjacent screenshot.)

Sending form data using PHP

If your hosting company offers support for PHP, the most widely used server-side technology,
there is no need to install a CGI script such as FormMail. Everything can be done with
PHP’s built-in mail() function. As a minimum, the function requires the following three
pieces of information:
The address(es) the mail is being sent to
The subject line
The message itself
An optional fourth argument to mail() permits you to send additional information in the
e-mail headers, such as from, cc, and bcc addresses, and to specify a particular character
encoding (if, for instance, you need to include accented characters or an Asian language
in the e-mail). Unfortunately, spammers frequently exploit this ability to add extra e-mail
headers, so you need to check the form input for suspicious content and stop the
e-mail from being sent if any is found. A script written by my fellow friends of ED author,
David Powers, does this for you automatically. Even if you have no experience working
with PHP, the following instructions should have you up and running quickly:
1. Copy process_mail.inc.php from the download files to the same folder (directory)
as the page containing the form. This is the PHP script that does all the hard
work. You don’t need to make any changes to it.

2. Save the page containing the form with a PHP extension—for instance,
feedback.php. Amend the opening form tag like this:
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">

3. At the top of the page, insert the following PHP code block above the DOCTYPE.
Although I’ve warned you elsewhere in the book never to place any content above
the DOCTYPE, it’s perfectly safe to do so in this case, because the PHP code doesn’t
produce any HTML output.
<?php
if (array_key_exists('SUBMIT', $_POST)) {
//mail processing script
$to = 'me@example.com'; // use your own email address
$subject = 'Feedback from website';
// list expected fields
$expected = array('realname', 'email', 'phone', 'message');
// set required fields
$required = array('realname', 'email', 'message');
$headers = 'From: My website<feedback@example.com>';
$process = 'process_mail.inc.php';
if (file_exists($process) && is_readable($process)) {
include($process);
}
else {
$mailSent = false;
mail($to, 'Server problem', "$process cannot be read", $headers);
}
}
?>

4. This script begins by checking whether the PHP $_POST array has been set. This
happens only when a user clicks the form’s Submit button, so this entire block of
code will be ignored when the page first loads. It sets the address to which the
e-mail is to be sent and the subject line. It then checks that all required fields have
been filled in, and sends the form input for processing by process_mail.inc.php.
If the mail processing file can’t be found, the script e-mails an error message
to you.
To adapt this script to your own form, you need to change some of the values, as
explained in upcoming steps.

5. Change SUBMIT in the second line of the script to the same value as the name of the
form’s Submit button.

6. Replace me@example.com with the e-mail address that the feedback is to be sent to.
Make sure the address is in quotes, and that the line ends with a semicolon.
If you want to send the e-mail to multiple addresses, separate them with commas
like this:
$to= 'me@example.com, him@example.com, her@example.com';

7. Replace the content inside the quotes in the following line (Feedback from website)
with whatever you want the subject line to say.

8. Next, list the name attributes of each form element as a comma-separated list
between the parentheses in the following line:
$expected = array('realname', 'email', 'phone', 'message');
This tells the script what form input you’re expecting. This is very important, as it
prevents malicious users from trying to pass unexpected—and possibly dangerous—
data through your form. Any form field not included in this list will be
ignored, so make sure you update the list whenever you add a new field to a form.
Note that the commas go outside the quotes. You can use single or double quotes.
It doesn’t matter as long as each set of quotes is a matching pair.

9. The next line of code looks very similar:
$required = array('realname', 'email', 'message');
This is used to check whether all required fields have been filled in. You’ll notice
that I’ve omitted phone from the list, so the script will treat it as optional. The order
of items in the $expected and $required arrays is not important, but it makes
maintenance easier if you use the same order as they appear in the form.

10. The next line looks like this:
$headers = 'From: My website<feedback@example.com>';
This sets the e-mail’s From: header. Change My website <feedback@example.com>
to the name and e-mail address that you want the e-mail to be sent from.
There are many additional headers you can add to an e-mail, such as Cc, or Bcc.
You can also set the encoding to UTF-8 (for messages that require accents or Asian
languages). The following example shows how to add a cc address and UTF-8
encoding:
$headers = "From: My website<feedback@example.com>\r\n";
$headers .= "Cc: copycat@example.com\r\n";
$headers .= "Content-type: text/plain; charset=UTF-8";
There are a couple of important points to note about this code. First, the headers
are enclosed in double quotes. This is because each header must be on a separate
line, and the characters \r\n at the end of the first two lines represent a carriage
return and new line when enclosed in double quotes. You need these two characters
at the end of each header except the last one. Second, there’s a period in front
of the equal sign in the second and third lines. This has the effect of stringing all
the values together so the script treats the headers as a single block.
One nice touch with e-mail headers is to put the user’s e-mail address in the
Reply-to field of the e-mail, so all the user has to do is click Reply in their e-mail
program to send a message back to the right person. Unfortunately, this is frequently
used by spammers to inject malicious code into your script. The code in
process_mail.inc.php filters out potential attacks and inserts the sender’s e-mail
address only if it’s safe to do so. Consequently, there is no need to add a Reply-to
header yourself; it’s done automatically by the script.
If you want to use a special encoding, such as UTF-8, for your e-mails, make sure
the web page containing the form uses the same encoding in its meta tag.
You don’t need to use all these headers. Just remove the complete line for any you
don’t want.

11. You don’t need to make any other changes to the code you inserted in step 3.

12. The script in process_mail.inc.php processes the form input and sends the e-mail
if there are no problems. The final stage is to let the user know what happened.
Immediately above the form in the main part of your page, insert the following
code:
<?php
if ($_POST && isset($missing) && !empty($missing)) {
?>
<p class="warning">Not all required fields were filled in.</p>
<?php
}
elseif ($_POST && !$mailSent) {
?>
<p class="warning">Sorry, there was a problem sending your message.
Please try later.</p>
<?php
}
elseif ($_POST && $mailSent) {
?>
<p><strong>Your message has been sent. Thank you for your feedback.
</strong></p>
<?php } ?>
This block of code displays an appropriate message depending on the outcome.
Put whatever messages you like in place of the ones shown here, and add the following
rule to your style sheet:
.warning {
font-weight: bold;
color: #ff0000;
}
If you’re using a visual HTML editor like Dreamweaver, all three messages will
appear to be displayed at once. However, when you load the page onto your website,
the PHP conditional logic hides all the messages, and only the appropriate one
is displayed after the user submits the form.

13. Save the page and upload it to your hosting company, together with process_
mail.inc.php. Test it. In a few moments, you should receive the test message in
your inbox. That’s all there is to it!
If you get error messages or a blank screen, it means you have made a mistake in
the script. Check the commas, quotes, and semicolons carefully. If you get a message
saying that process_mail.inc.php cannot be read, it probably means that
you have forgotten to upload it, or that it’s not in the same folder as the form.

No comments:

Post a Comment