PHPMail ------- v1.0 May 1998 Written in PHP/FI, features included emailing and custom ack page, both with variable substitutions, and specification of required fields. v2.0 December 1998 Converted to PHP3. Standardized configuration variable names, added autoresponder and text file logging. Phorm ----- v1.0 March 1999 Changed the name to Phorm. Re-did the documentation in RTF format. Added MySQL logging, configuration files, emailing alert messages to the user. Handled security problem with visitor being able to perform variable substitutions v1.1 June 1999 Added ability to have multiple email templates. v2.0 September 1999 Significantly revised and enhanced the documentation. Added data validation feature, RCONFIG variable. Standardized internal variable names. Revamped and greatly enhanced error handling and reporting. Historical Note: Generally when I write a program, I get the concept, code it, test it, then write the documentation for it. Documentation serves two purposes: there is the obvious one of explaining how to use the program; but also, as I'm writing the documentation, I'll very often see that some feature or way of doing something isn't as practical as I had originally thought, and I'll go revise the code. As I started to work on this version, I planned to improve the existing documentation and add the data validation scheme. I started tweaking the documentation, all the while thinking about the validation. When I came to the point in the docs where the description of the validation scheme was going to go, I put in a header. Then I jotted down a couple of ideas about it. Then I wrote a little more, and a little more.... By the time I was done, I had fully documented this feature, without having written a line of code! It was really weird. Of course, as I wrote the code I saw that certain features or ways of doing things weren't as practical as I had originally thought, and I went and revised the documentation. But it was really interesting. In 24 years of programming, I've never developed something in this fashion. v2.01 October 1999 Added security features with $PHORM_BASE, phormbase.txt, and forced declaration of $PHORM_ variables, aimed primarily at preventing others from abusing user's installation of Phorm. Made it easier for user to specify alternate location for sendmail. Further enhanced error handling and reporting. Introduced multi-user version with special security and administrative features. v2.02 November 1999 Doh! One of the most stunning realizations of my entire programming career: I discovered that, in all this time, I had never tested the MySQL logging feature. Unbelievable! But I couldn't possibly have tested it, as the INSERT query being generated was totally the wrong syntax and could never have worked! How utterly, incredibly embarassing! Fixed this colossal blunder. Made some clarifications in the docs. Handled a bug which caused the validation parser to hang if there was a blank line at the end of the file. Added $ph_debug variables and checkpoints, and enhanced MySQL error reporting. Removed the requirement for $PHORM_CONFIG to be declared. Fixed the locations of sample files in the distribution. And yes, I tested it all! Now leave me alone! v2.5 May 2000 Optimized the validation loop. Optimized the variable substitution parsing. Added GE, LE, NE, PHONEC, REGEX and NUMERIC criteria. (I'm not sure how I overlooked NUMERIC earlier!) Greatly enhanced the EMAIL criterion, including levels of checking. Clarified the documentation more (an ongoing process), including a QuickStart document. Added data recycling feature. Fixed problem with handling of phormbase.txt. Changed the email functions to use mail() instead of sendmail, in order to work with Windows systems. Handled MySQL-logging bug which generated a bad query if the first field specified was blank. Fixed MySQL logging problem to allow text to include ' character. Handled CC validation bug which accepted input if it contained only non- numeric characters. Fixed PHP4 endless looping bug, problem with finding Phorm's directory on some systems and bug which caused a warning if no PHORM_ fields were used in the form with ForceDec set. Improved the example files. Added $PHORM_HEADERS. Historical Notes: Phorm Jr. was conceived and released in March 2000; Phormation was conceived in April 2000 and released shortly after Phorm v2.5. Er, make that after v2.51. I mean, v3.0. No, really! Shortly after v3.0! I promise! v2.51 August 2000 Fixed problem with some validation criteria failing to recognize 0 as a valid argument or field value (treating 0 as "not set"). Smarter operation of AddSlashes() on data being passed to MySQL. Made the REQ criterion more accurate. Fixed MailVal bug that allowed an address with no user name (e.g. '@holotech.net'). Allowed variable substitution in validation criterion arguments. Fixed variable substitution regex that wasn't allowing field names containing the number 2; added $ph_RegEx to give regex selection for different installations. Hopefully this is the end of the regex problems. Added $PHORM_ALERTFRM. Added $PHORM_POSTINC for post-processing. Allowed variable substitution in email headers in secondary templates. Fixed secondary templates not working with conversion to mail(). Added $ph_config_delim. Allowed multiple MySQL entries. Added UNIQUE criterion. Added error and alert numbers. Added $PHORM_PHPMAIL requirement for PHPMail support. Forced getenv() for $HTTP_REFERER and $REMOTE_ADDR, included them in alert message. Added $PHORM_LOGQUOT. Changed operation of $PHORM_RCONFIG and $PHORM_URL, and added $PHORM_RDIRECT. Trivia Note: The data validation section is nearly 1/2 of the entire code of Phorm. v3.0 February 2002 Fixed bug which broke data recycling if HTML tags were in lower case. Moved MySQL logging before all other functions to expose LAST_INSERT_ID. Fixed bug which bypassed post-processing if there was no ack template. Fixed bug which flagged empty email address as invalid in EMAIL criterion.Added new expressions for $ph_RegEx. Hopefully THIS is the end of the regex problems. If not, I'm going to shoot Linus Torvalds. Laid an easter egg. Added EXISTS criterion. Fixed bug in email headers (using LF instead of CRLF). Added file attachment capability. Put documentation on line. Added file uploading. Finally decided to split off code into library modules - Phorm has exceeded 2000 lines, and is just too unwieldy in one file. Plugin capability. Optimized the HTML parser (and there was much rejoicing (yaaaaaay!)). Added checking for $HTTP_REFERER. Fixed bug allowing null second-level domain on email checking. Changed $ph_Errs and $ph_Alerts to arrays. Added custom error page capability. Added variables PHORM_NAME, PHORM_ROOT and PHORM_INFONLY. Added FLDLEN criterion. Multiple text logging. Ability to specify location of individual validation error messages. Added DATECMP criterion. Ability to check concatenated columns in UNIQUE and EXISTS criteria. Manual extraction of $HTTP_*_VARS to support installations with register_globals off. Optimized variable substitution. Late addition: ability to reference arrays of any number of indices in variable substitutions (and there was much rejoicing (yaaaaaay!)). Trivia Note: The initial release of PHPMail was 140 lines of code, and 52 lines of documentationin a text file. Phorm now comprises over 3,000 lines of code (well, a few of those are comments) and over 50 pages of documentation. The folder where I keep all the past versions is 870KB. v3.0.1 March 2002 Fixed a bug which caused warnings if the validation error template contained no form fields. Fixed a bug which caused a 090 error if there was a 040 error condition or 060 alert condition, when Phorm was trying to re-direct (thereby cancelling the redirect). Moved strreplace() from the function library to phorm.php3, to make it available under all error conditions. Fixed problem with text logging function. v3.0.2 March 2002 One of these days, after I become a real programmer, I may learn to test my code. Earlier moved strreplace() from the library to the main file, but failed to also move CheckVers(), which it relies on. Was not checking the library was loaded when calling PlugStat(). Sections 'phormbase' and 'phormconfig' were not checking $ph_Abort. Added condition to deal with an empty phormbase file without causing an alert. Note: Phorm Jr. v2.0 was released in March 2002. Fixed regex problem. Added text log capability, $PHORM_REFERER checking, _err.html template capability. v3.0.3 April 2002 Fixed text log bug. Fixed case sensitive bug in data recycling, added ParseHTML function. Modified the file attachment module to work with the HTMLMail plugin. Added the generic templates and ph_FORMVARS variable and revised the Quick Start document. Added error_reporting() setting. v3.0.4 With a couple months in the field, it looks like v3 has pretty much stabilized. Corrected variable substitution: was only allowing array indices with characters [A-Za-z0-9_]. Made variable subsitution tolerant of $ before variable names. Added conditional validation rules. Added ability for PHP code in error and ack templates. Note to would-be hackers: yes, the PHP parsing is done *before* variables are expanded, so don't even bother. Finally, fully, certainly handled the case-sensitive bug in data recycling. Added variable substitution for $PHORM_SUBJECT and $PHORM_RESUBJ. Added ability to handle OPTION tags with no VALUE attribute in data recycling. Made database logger tolerant of $ before variable names. Of course, if the user uses double quotes when constructing $PHORM_MYVARS and puts a dollar sign in front of the variable name, it's not going to work because PHP is just going to insert the actual value of the variable right there. But there's only so much you can do to protect people from their own denseness. Made text logger tolerant of $ before variable names. See previous caveat. See, the thing is, I just know someone is going to trip over this and ask me about it. I just *know* it. No I am not talking to myself, so be quiet. Updated plugin developer documentation to reflect changes in Phorm's operation. Added $PHORM_LINEBRK. Changed ph_FORMVARS to return only fields which have a value. Added $ph_FORMVARSF. Fixed bug which wasn't returning fields for ph_FORMVARS if request method was GET. Added test for ENCTYPE= "multipart/form-data" when PHP4 is not configured to accept uploads, a condition which makes the form data inaccessible.