??????????????? ??????????????? FormMail. * * Author: Russell Robinson, 23rd April 2004 * * Read this first * ~~~~~~~~~~~~~~~ * Intelligent user error handling for forms is difficult. * This script does a lot of the work, but it's not magic. * You *must* have a good knowledge of creating HTML forms to start. * Don't even try to get FMBadHandler working unless you're comfortable * with creating HTML forms. * Note also the formatting requirements we've listed below. * * We recommend you start by reading our HOW-TO guide here: * http://www.tectite.com/fmhowto/adverror.php * * Learn a lesson from software developers: if you've got 20 sub-tasks * to perform to achieve something, don't try and do all 20 at once! * It's a recipe for wasting huge amounts of time and getting into a big * mess. Instead, do sub-task 1. When it's working, move onto sub-task 2, * when it's working, move onto sub-task 3, and so on. * * First, check that your hosting provider has a recent version of PHP. * FMBadHandler and FormMail work on PHP version 4.0.x and above. * FMBadHandler has been tested on PHP version 4.0.6, however, session * variables don't seem to work reliably on 4.0.6 (this means you may * have problems with forms with large amounts of data submitted). * * There are 2 configuration values you will need to set. See the * CONFIGURATION section below. These are necessary for security purposes. * * We recommend the following steps: * 1. Confirm that your webserver accepts PHP and can send email from * PHP (see the sticky posts on our forums at www.tectite.com/vbforums). * 2. Create a basic HTML form, preferably using our sample form * as a base (see our download forums at www.tectite.com/vbforums). * 3. Get FormMail basically working with that form. Get it sending you * mail from your form submissions. * 4. Get the "good_url" feature working. Tell FormMail to redirect to * a page of your choosing on success. * 5. Install fmbadhandler.php on your server. Configure it as described * below. Specify its URL in your form as hidden field "bad_url". * Specify the form's own URL in the form as hidden field "this_form". * 6. Submit a form with an error (e.g. a missing field). You should be * redirected to the default error page of fmbadhandler.php. It should * provide a link to see the form again. If you click that link, the * form should be re-displayed and all the fields you entered should * be filled in in the form. * 7. Finally, create a template for your errors and specify it as hidden * field "bad_template". Use our sample "samplebadtemplate.htm" as * a starting point. * * Purpose * ~~~~~~~ * This script (FMBadHandler) is designed for use with our PHP FormMail * (available from www.tectite.com). * FMBadHandler is an intelligent script that you can use to provide * good error handling for your users who submit forms with errors. * * Requirements * ~~~~~~~~~~~~ * This script requires PHP version 4.0.x or above. It has been verified * to work with PHP version 4.0.6, except for passing data in session * variables. Therefore, if you have an old version of PHP, you may be * restricted to small forms (i.e. small amount of data). * * What does this PHP script do? * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Once you've got FormMail working in a basic way, you may want to handle * user errors in a more advanced way. * FormMail has several error handling features built in, but this * script (FMBadHandler) can be used to: * - display errors in a particular way, listing items * in an HTML list * - use an HTML template of your design to format the error * page the way you want * - provide a link that will show the form again with the fields * that the user has previously entered filled in * * Formatting your form fields * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * To display the form again, with the user's fields already filled in, * FMBadHandler does this: * 1. opens the form's URL (that is, your server opens the form just * like a browser does) * 2. reads the whole form into memory * 3. searches for the field definitions and modifies them * 4. outputs the changed HTML to the browser * * In order for this to work reliably, you need to format your field * definitions in a certain way. Here are the rules: * * INPUT these fields must have any "value" attribute after * the "type" and "name" attributes. The "type" and "name" * attributes must be present but can be specified in * either order. Examples: * * * Only "text", "password", "radio" and "checkbox" types * are supported. * For "radio" and "checkbox" types, any "checked" attribute * must appear after "name", "type", and any "value" attribute. * Examples: * * * or (for XHTML compliance): * * For checkboxes with multiple values assigned to the one * field name, you must use "[]" with the field name: * * * * Note that INPUT "text" fields generally don't have a value * attribute unless you're providing a default value for the * user to replace. In you do provide a value attribute, * follow the instructions as above. * * SELECT select fields can be single or multiple selection. * For multiple selection fields, ensure the name has * "[]" appended. Examples: * * If you use the "selected" attribute on any options, ensure * that it appears *after* the "value" attribute, like this: * * or (for XHTML compliance): * * * TEXTAREA textarea fields have no specific formatting requirements, * except they must have a name to be usable on the form. * Examples: * * * * * case sensitivity * any names and values you use in your form should be unique * in a case insensitive comparison. * The following will cause problems: * * * * * * * However, this is OK: * * * * non-alphanumerics * Use of non-alphabetic and non-numeric characters in names * and values may cause problems. Test thoroughly! * * attribute values * These must be enclosed in double quotes with no whitespace * before or after the '='. Single quotes are not supported * as attribute delimiters. * * HTTP Authentication * ~~~~~~~~~~~~~~~~~~~ * If your form requires the user to authenticate themselves, FMBadHandler * may have trouble accessing the form when the user clicks the * return-to-form link. * * HTTP Authentication is generally specified in Apache's .htaccess file. * Other Web Server software will have similar mechanisms. * * From version 1.11, FMBadHandler is designed to automatically * authenticate itself using the user's own authentication. For this to work * you must be using FormMail version 7.05 or later, *and* formmail.php * must be in the same authentication realm (i.e. controlled by the same * authentication directives as the HTML form itself). * * Put simply, this means you need to put formmail.php in the same * directory or folder as your HTML form. When your form POSTs to * FormMail, FormMail retrieves the authentication details and passes * them to FMBadHandler so it can use them too. * * Also, FMBadHandler only supports the Basic authentication mechanism. * * An alternative way to allow FMBadHandler to access your protected HTML form * is to use directives in the .htaccess file. You simply need to tell * Apache that your server has unrestricted access to your HTML * form (remember, FMBadHandler makes your server open the * form just like a browser does). * * These Apache directives can be added to your .htaccess file: * Order allow,deny * Allow from HOST 127.0.0.1 * Satisfy any * * replacing HOST with the name of your server or its IP address. * Note that a name must resolve to the IP address that your server will * make requests from. On shared hosting servers, that have many IP * addresses, it might be tricky to find out what this IP address is! * * See this post on our forums for more information: * http://www.tectite.com/vbforums/showthread.php?p=3365#post3365 * * Copying and Use * ~~~~~~~~~~~~~~~ * fmbadhandler.php is provided free of charge and may be freely distributed * and used provided that you: * 1. keep this header, including copyright and comments, * in place and unmodified; and, * 2. do not charge a fee for distributing it, without an agreement * in writing with Root Software allowing you to do so; and, * 3. if you modify fmbadhandler.php before distributing it, you clearly * identify: * a) who you are * b) how to contact you * c) what changes you have made * d) why you have made those changes. * * Warranty and Disclaimer * ~~~~~~~~~~~~~~~~~~~~~~~ * fmbadhandler.php is provided free-of-charge and with ABSOLUTELY NO WARRANTY. * It has not been verified for use in critical applications, including, * but not limited to, medicine, defense, aircraft, space exploration, * or any other potentially dangerous activity. * * By using fmbadhandler.php you agree to indemnify Open Concepts (Vic) Pty Ltd * t/as Root Software, their agents, employees, and directors from any liability * whatsoever. * * We still care * ~~~~~~~~~~~~~ * If you report problems to us, we will respond to your report and make * endeavours to rectify any faults you've detected as soon as possible. * To contact us, visit http://www.tectite.com/contacts.php. * * Version History * ~~~~~~~~~~~~~~~ * **Version 1.22: 30-Sep-2010 * Improved to handle redirects when retrieving the form for "return to form" * processing. This allows FMBadHandler to operate within WordPress and * other systems that rely heavily on redirecting URLs. * * Added support for alternative template tag formats to avoid problems * with systems that don't link non-HTML tags in documents (e.g. WordPress). * **Version 1.21: 25-Jan-2010 * Fixes two bugs which make the error template output non-validating * by the w3c HTML validator: * - was incorrectly adding
after . * - did not use HTML entities in the return URL. * **Version 1.20: 23-Sep-2009 * * Improved some of the above comments and expanded instructions with regard * to formatting form fields. * * Improved to accept "this_form" and "bad_template" from the session. * This allows FMBadHandler to operate with version 8.19 (and later) of * FormMail and overcomes a problem caused by security settings on some * servers. * **Version 1.19: 17-Jul-2009 * * Fixes potential Cross-Site Scripting (XSS) vulnerability when a failure * occurs in FMBadHandler (such as being unable to open an error template) * and it displays an error. * **Version 1.18: 20-Mar-2009 * * Fixes a problem when the user has entered $123 or \123 in a field. * In this case in previous version, when they return to the form, the * value would be truncated when the field was re-filled. * **Version 1.17: 2-Dec-2008 * * Fixes potential Cross-Site Scripting (XSS) vulnerabilities. * **Version 1.16: 23-Aug-2006 * * Copied some useful code from FormMail. This means you can now use * $REAL_DOCUMENT_ROOT in the configuration section. * This also adds $SET_REAL_DOCUMENT_ROOT to the configuration section. * **Version 1.15: 14-Mar-2006 * * Fixed problems with encoding URLs. The AddURLParam function * decoded the URL before adding the parameter, but didn't re-encode it! * AddURLParam no longer decodes the URL (it was not necessary because * the browser decodes it!) * **Version 1.14: 1-Mar-2006 * * Re-implemented the session passing to use the standard SID * value in addition to the "sessid". This should then cover * the case of use_trans_sid disabled and cookies enabled or disabled * in the browser. * * So, at the top of the script the code should now be: * if ((bool) ini_get("session.use_trans_sid") == false) * if (isset($_GET['sessid']) && $_GET['sessid'] !== "") * session_id(urldecode($_GET['sessid'])); * session_name(""); // optional * session_start(); * * Also, in case use_trans_sid is disabled in your PHP *and* the user's * browser has cookies disabled, then you need to put this in the * form: * if ((bool) ini_get("session.use_trans_sid") == false) * echo "\n"; * **Version 1.13: 27-Feb-2006 * * Fixes a problem with encoding URL parameters (previously this * would have just been the User Agent and may not have caused any problems). * * When opening a URL to the form or a template, the session ID is now * passed in the URL parameters. This means a script can access the * session by using the following code (this is a PHP example): * if (isset($_GET['sessid']) && $_GET['sessid'] !== "") * session_id(urldecode($_GET['sessid'])); * session_name(""); // optional * session_start(); * * This allows your forms to be scripts that can create and/or access a * PHP session even when they are being processed by FMBadHandler. * **Version 1.12: 11-Jan-2006 * * Fixed a problem with sending the USER_AGENT in the query string * to the $return_link URL. * Also, if a URL contains a fragment (#blah), adding the USER_AGENT * now works properly - previously, the USER_AGENT was put in the * wrong location. * **Version 1.11: 27-Oct-2005 * * Fixed some typographical errors and improved some wording. * Added support for automatic HTTP authentication when used with FormMail * version 7.05 or later. * **Version 1.10: 26-Sep-2005 * * Fixed bug in matching "selected" and "checked" attributes. This bug only * occurs under rare circumstances. An example is: *