rewrote logentry() to use PEAR::Log instead of using syslog directly;
rewrote displaypermissiondenied() to call displayerrorpage(); changed
displayerrorpage() so it has an optional 'template' argument; removed
displayerrormessage() function (previously deprecated in favor of
displayerrorpage()); changed setreturnto() so that the url parameter is
optional and defaults to the value of getreturntourl(); removed 'title',
'stylesheets', and 'template' arguments from displaypermissiondenied();
removed 'return value by reference' from dbconnect(); added to
processupload() with the beginnings of handling multiple files at once (an
html5 feature); buildbreadcrumbs() changed to use php 5.4+ array syntax;
added cartidexists() function; rewrote getcurrentcart() to use getcart()
function; rewrote getcurrentcartid() to use new cartidexists() function;
added clearcart() function and rewrote clearcurrentcart() to use it; added
accesscartitem(), buildcartitemactions(), accesscart(), cartitemexists(),
iscartowner(), and buildcartactions(); added getcurrentsig() and
setcurrentsig(); added buildbutton() function which accepts a quickform
instance, a field name and a value and adds a button element.

bbsengine3.php: added setMetaRefresh() call to displayerrorpage() so that it
will work properly with jquery.smoothstate; changed displayerrorpage()'s
$status param default from 500 to 418; buildnotifyactions() changed actions
to reference ENGINEURL define; changed return value of getcurrentcart() to
the currentcartid, which is odd; changed getcartitems() to dbconnect() to
SYSTEMDSN before proceeding.

updated copyright date; updated documentation for getquickform() and
_getsmarty(); _getsmarty() changed to accept optional options dictionary and
accept keys 'compileid', 'compiledir', 'templatedir', 'pluginsdir', and
'vars'; added 'currenturi' and 'currentpath' to list of vars automagically
passed to every template; added a default 'getsmarty' function if another
has not already been defined; marked 'fetcherrorpage' deprecated;
fetchredirectpage() and displayerrorpage() updated to use 'pagedata' option
so it works with the new 'page.tmpl'; displayerrormesage(), displayheader()
marked deprecated; renamed _fetchsidebar() to _fetchnavbar(); added
closelog() call to logentry(); new feature: _getpage() now accepts a
"stylesheets" option for adding page-specific stylesheets; new defines in
config.php: METAKEYWORDS (added to page using <meta> tag); new permission in
accessmember 'editcredits' which is only enabled if USEMEMBERCREDITS is
defined in config.php; changed function prototype of sendnotify() to make
third parameter (data) optional; changed getsig() such that calling the
teosurl function from php is no longer needed; in buildloginfieldset(),
renamed 'username' field to 'name' and 'password' field to 'passwd'; in
getnotify(), change references to 'notify' to 'engine.notify'; added 'edit'
permission to accessnotify(); handleform() updated to check if the given
callback function is actually callable before calling it, and logging an
error when it isn't; made a generic displaypage() function in case one has
not already been defined; displayform() updated to use 'pagedata' option;
new functions: buildlabelpath(), normalizelabelpath(), buildsigfieldset(),
accesssig(), buildsigactions(), buildpagerinfo(), buildbreadcrumbs(),
getsigidfromlabelpath(), getcurrentpath(), getcurrentcart(),
getcurrentcartid(), setcurrentcartid(), addcartitem(), clearcurrentcart(),
normalizecart(), setcurrentcart(), getcart(), buildcartrecord(),
getcartitems(), updatesigmap(), getsigmap(), implodesigmap(),
explodesigmap(), explodesiglabelpaths(), and explodeuri().

===
INSTALL.txt
===
- removed references to sourceforge project, since I am no longer active on that site
- removed details about installing an operating system since that info was quickly outdated.
- removed notes about how to configure apache
- removed specific version references for php, apache, etc
- removed reference to google's "spidering" rules
- removed notes about modifying 'getsmarty()' function
- tightened up the shameless plug about writing custom modules for a fee.

==
bbsengine3.php:
==
* moved calls to addRecursiveFilter ('trim' and 'striptags') from the apps to the getquickform() function
* updated displayredirectpage() to use new displaypage() function
* renamed 2nd param in dipslayerrorpage() function from 'errorcode' to 'statuscode' and updated it to use
displaypage()
* updated displaypermissiondenied() to use displaypage()
* added 'editcredits' operation to accessmember() to check if a user is allowed to
edit the 'credits' field in the member table
* changed buildmemberfieldset() to check for new 'editcredits' op and if true adds a field and a rule
* changed buildmemberrecord() to handle the 'credits' field if set
* FEATURE: handleform()
** accepts an html_quickform2 instance and a callback function
** if the form is submitted and validates, the callback is called.
** return value is whatever was returned by the callback or False if the form does not validate.
* FEATURE: added displaypage() which handles the 'pageprotocol' gracefully and removes a lot of duplicate
code from all of the zoidweb2 apps
* FEATURE: added displayform() function, which accepts an
html_quickform2_renderer instance and a pagetitle and calls displaypage()
to display the form, removing a lot of duplicate code in apps. this
function is normally called after a call to handleform() has returned
False. the optional 3rd param is a dictionary of options. currently the
only options are "stylesheets", which is a list of css files to add to the
html_page2 instance, and "template" which allows override of the default
of 'form.tmpl' if needed.

===
bbsengine3.php
===
* removed 'return by reference' (&) on getquickform()
* changed getmember() so that if no args are passed getcurrentmemberid()
result is used
* changed header() call in displayerrorpage() so it will
actually work
* changed getreturntourl() so it returns SITEURL define instead
of null
* header() call in displaypermissiondenied() changed to emit proper
error code (same change as displayredirectpage())
* changed getcurrentmemberid() to accept an optional 'key' parameter which
determines the key to use in _SESSION that holds the id of the current user
and defaults to "currentmemberid"
* in _getpage(), removed define and code for using PEARHTTPSESSION
* in _getpage() also changed setDocType() call from "XHTML 1.0 Strict" to "XHTML 1.0
Transitional"
* removed check for PEARHTTPSESSION define and associated code in
setcurrentpage()
* changed call to autoExecute (MDB2) in updatemember() so it references the
session name ('engine')
* added defines for SESSIONCOOKIEEXPIRE and SESSIONCOOKIEDOMAIN instead of
hardcoding them in startsession()
* in _writesession(), store IP address, user agent, memberid,
and datecreated
* changed processupload() so it takes only 2 arguments
("value" and "destinationdir"). value is derived from a key in $values
which is passed to the callback (f.e. insert and update) instead of passing
an entire html_quickform2 instance. the code is simplified and it could
work even without html_quickform2 ($value is a dictionary)
* removed function getquickform2 which was never used
* changed accessmember() function so it always returns True when the op is 'detail'
* wrapped getmemberfieldset() in a function_exists() call so that the app can override it easily
* changed getpageprotocol() so it looks for "pageprotocol" in $_REQUEST so the session
can easily be overridden.. this was added as part of a project to enhance
pages as well as forms
* wrapped buildmemberrecord in a function_exists() so the app can easily override it
* checkpassword() function uses new function hashpassword() instead of hardcoding a call to md5()
* new function checklogin() which accepts a dictionary with two keys: username and
password.. this function serves as a callback to an html_quickform2 rule
for a better UX
* hashpassword() changed so that if CRYPTSALT is defined uses
crypt() and falls back to md5() if not
* added function _buildnotifydata() and changed notifydata so it can be overridden by the app
* new functions: getmemberidfromemail() and getmemberidfromusername() which
call getmemberfrom() to get a member dictionary based on a given key like
"email" or "username".
* added buildbuttonfieldset() which is allowed to be overridden
* added toboolean() which accepts a fieldvalue (a string normally as a 't'
or 'f') and converts it to an "actual" boolean value (True or False)
* new function handleform() so that there is a consistent interface to
handling forms including 'enhanced forms' if enabled. it accepts an
html_quickform2 instance, a callback, a page title, and an optional
smarty3 template name defaulting to "form.tmpl".
* added functions getmembercredits(), setmembercredits(),
getcurrentmembercredits(), and setcurrentmembercredits() which handle
account credits. these functions are intended to help in writing games
(like "blackjack")