Index: /trunk/bin/acl.cli.php
===================================================================
--- /trunk/bin/acl.cli.php	(revision 501)
+++ /trunk/bin/acl.cli.php	(revision 502)
@@ -44,17 +44,22 @@
 // Make sure necessary files exist.
 define('COMMON_BASE', realpath('.'));
-$db_quth_file = COMMON_BASE . '/global/db_auth.inc.php';
-if (!file_exists($db_quth_file)) {
-    die(sprintf("%s error: the current directory must be common site directory (i.e. the parent directory of the document root) AND the global/db_auth.inc.php file must exist.\n", $this_script));
-}
-
-if (fileowner($db_quth_file) != getmyuid()) {
+$db_auth_file = false;
+$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(COMMON_BASE));
+$rii->setMaxDepth(2);
+foreach ($rii as $filename => $file) {
+    if (mb_strpos($filename, 'db_auth.inc.php') !== false) {
+        $db_auth_file = $filename;
+        break;
+    }
+}
+if (!$db_auth_file) {
+    die(sprintf("%s error: the current directory must be common site directory (i.e. the parent directory of the document root) AND the db_auth.inc.php file must exist.\n", $this_script));
+}
+if (fileowner($db_auth_file) != getmyuid()) {
     die(sprintf("%s error: you must execute this script as the owner of the web files.\n", $this_script));
 }
 
 // Set include path.
-ini_set('include_path', get_include_path()
-    . PATH_SEPARATOR . COMMON_BASE
-);
+ini_set('include_path', get_include_path() . PATH_SEPARATOR . COMMON_BASE);
 
 /********************************************************************
@@ -83,5 +88,5 @@
     'log_filename' => 'site_log',
 ));
-require_once 'global/db_auth.inc.php';
+require_once $db_auth_file;
 
 // Start application-based functionality: database, session, environment, ini setup, etc.
@@ -104,4 +109,5 @@
 if (!$db->tableExists('acl_tbl')) {
     printf("This project doesn't appear to be using ACL (there is no acl_tbl in the %s DB).\n", $app->getParam('db_name'));
+    $app->stop();
     die;
 }
@@ -220,4 +226,7 @@
     break;
 }
+
+$app->stop();
+die;
 
 
@@ -309,13 +318,13 @@
     case 'aro' :
         $tbl = 'aro_tbl';
-        printf("%-35s %-5s %-5s %s\n", 'Request objects', 'lft', 'rgt', 'Added');
+        printf("%-45s %s\n", 'Request objects', 'Added');
         break;
     case 'aco' :
         $tbl = 'aco_tbl';
-        printf("%-35s %-5s %-5s %s\n", 'Control objects', 'lft', 'rgt', 'Added');
+        printf("%-45s %s\n", 'Control objects', 'Added');
         break;
     case 'axo' :
         $tbl = 'axo_tbl';
-        printf("%-35s %-5s %-5s %s\n", 'Xtra objects', 'lft', 'rgt', 'Added');
+        printf("%-45s %s\n", 'Xtra objects', 'Added');
         break;
     default :
@@ -325,5 +334,5 @@
     }
 
-    echo "-----------------------------------------------------------\n";
+    echo "---------------------------------------------------------------------\n";
 
     // Retrieve the left and right value of the $root node.
@@ -342,5 +351,5 @@
 
         // Display indented node title.
-        printf("%-35s %-5s %-5s %s\n", str_repeat('    ', sizeof($depth)) . $name, $lft, $rgt, date($app->getParam('date_format'), strtotime($added_datetime)));
+        printf("%-45s %s\n", str_repeat('    ', sizeof($depth)) . $name, date($app->getParam('date_format') . ' ' . $app->getParam('time_format'), strtotime($added_datetime)));
 
         // Add this node to the stack.
@@ -373,5 +382,5 @@
     ");
     echo "\n";
-    printf("%-25s %-25s %-25s %-6s %-10s\n", 'Request objects', 'Control objects', 'Xtra objects', '', 'Added');
+    printf("%-25s %-25s %-25s %-6s %-10s\n", 'Request objects', 'Control objects', 'Xtra objects', 'Grant', 'Added');
     echo "------------------------------------------------------------------------------------------------\n";
     while ($p = mysql_fetch_assoc($qid)) {
Index: /trunk/lib/ACL.inc.php
===================================================================
--- /trunk/lib/ACL.inc.php	(revision 501)
+++ /trunk/lib/ACL.inc.php	(revision 502)
@@ -37,5 +37,6 @@
 require_once dirname(__FILE__) . '/Cache.inc.php';
 
-class ACL {
+class ACL
+{
 
     // A place to keep an object instance for the singleton pattern.
@@ -49,4 +50,8 @@
         // Automatically create table and verify columns. Better set to false after site launch.
         'create_table' => false,
+
+        // Maximum allowed length of names.
+        // This value can be increased only if {aro,aco,axo}_tbl.name VARCHAR length is increased.
+        'name_max_length' => 32.
     );
 
@@ -149,7 +154,7 @@
             $db->query("
                 CREATE TABLE IF NOT EXISTS acl_tbl (
-                    aro_id SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
-                    aco_id SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
-                    axo_id SMALLINT(11) UNSIGNED NOT NULL DEFAULT '0',
+                    aro_id SMALLINT UNSIGNED NOT NULL DEFAULT '0',
+                    aco_id SMALLINT UNSIGNED NOT NULL DEFAULT '0',
+                    axo_id SMALLINT UNSIGNED NOT NULL DEFAULT '0',
                     access ENUM('allow', 'deny') DEFAULT NULL,
                     added_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
@@ -180,7 +185,7 @@
                     CREATE TABLE IF NOT EXISTS {$a_o}_tbl (
                         {$a_o}_id SMALLINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
-                        name VARCHAR(32) NOT NULL DEFAULT '',
-                        lft MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
-                        rgt MEDIUMINT(9) UNSIGNED NOT NULL DEFAULT '0',
+                        name VARCHAR(" . $this->getParam('name_max_length') . ") NOT NULL DEFAULT '',
+                        lft MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
+                        rgt MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
                         added_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
                         UNIQUE KEY name (name(15)),
@@ -255,4 +260,11 @@
         if ('' == trim($name) || '' == trim($parent)) {
             $app->logMsg(sprintf('Cannot add node, parent (%s) or name (%s) missing.', $name, $parent), LOG_WARNING, __FILE__, __LINE__);
+            return false;
+        }
+
+        // Ensure node node name fits in the column size.
+        // This value can be increased if {aro,aco.axo}_tbl.name VARCHAR length is increased.
+        if (strlen(trim($name)) > $this->getParam('name_max_length')) {
+            $app->logMsg(sprintf('Cannot add node, %s character limit exceeded for name "%s"', $this->getParam('name_max_length'), $name, $parent), LOG_WARNING, __FILE__, __LINE__);
             return false;
         }
@@ -718,5 +730,5 @@
 
         if (!$this->check($aro, $aco, $axo)) {
-            $message = '' == trim($message) ? sprintf(_("You have insufficient privileges to view <em>%s %s</em>"), $aco, $axo) : $message;
+            $message = '' == trim($message) ? sprintf(_("Sorry, you have insufficient privileges for <em>%s %s</em>."), $aco, $axo) : $message;
             $app->raiseMsg($message, $type, $file, $line);
             $app->dieBoomerangURL();
Index: /trunk/lib/App.inc.php
===================================================================
--- /trunk/lib/App.inc.php	(revision 501)
+++ /trunk/lib/App.inc.php	(revision 502)
@@ -40,5 +40,6 @@
 require_once dirname(__FILE__) . '/Utilities.inc.php';
 
-class App {
+class App
+{
 
     // Minimum version of PHP required for this version of the Codebase.
@@ -627,8 +628,4 @@
         }
 
-        // Make sure to log in the system's locale.
-        $locale = setlocale(LC_TIME, 0);
-        setlocale(LC_TIME, 'C');
-
         // Strip HTML tags except any with more than 7 characters because that's probably not a HTML tag, e.g. <email@address.com>.
         preg_match_all('/(<[^>\s]{7,})[^>]*>/', $message, $strip_tags_allow);
@@ -678,4 +675,8 @@
         }
 
+        // Make sure to log in the system's locale.
+        $locale = setlocale(LC_TIME, 0);
+        setlocale(LC_TIME, 'C');
+
         // Data to be stored for a log event.
         $event = array(
@@ -692,4 +693,6 @@
         $event_short['url'] = truncate($event_short['url'], 120);
 
+        // Restore original locale.
+        setlocale(LC_TIME, $locale);
 
         // FILE ACTION
@@ -702,5 +705,5 @@
         if (false !== $this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority') && $send_notifications) {
             $hostname = (isset($_SERVER['HTTP_HOST']) && '' != $_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : php_uname('n');
-            $subject = sprintf('[%s %s] %s', $hostname, $event['type'], mb_substr($message, 0, 64));
+            $subject = sprintf('[%s %s] %s', $hostname, $event['type'], mb_substr($event['message'], 0, 64));
             $email_msg = sprintf("A %s log event occurred on %s\n\n", $event['type'], $hostname);
             $headers = 'From: ' . $this->getParam('site_email');
@@ -724,9 +727,4 @@
             file_put_contents('php://stderr', "[{$event['type']}] [{$event['message']}]\n", FILE_APPEND);
         }
-
-        // Restore original locale.
-        setlocale(LC_TIME, $locale);
-
-        unset($event, $event_short);
 
         return true;
@@ -850,11 +848,19 @@
      *                                     header('Location...') redirections.
      *
+     * @param   bool    $include_csrf_token     Set to true to include the csrf_token in the form. Only use this for forms with action="post" to prevent the token from being revealed in the URL.
      * @return string url with attached queries and, if not using cookies, the session id
      */
-    public function url($url, $carry_args=null, $always_include_sid=false)
+    public function url($url, $carry_args=null, $always_include_sid=false, $include_csrf_token=false)
     {
         if (!$this->running) {
             $this->logMsg(sprintf('Canceled method call %s, application not running.', __FUNCTION__), LOG_NOTICE, __FILE__, __LINE__);
             return false;
+        }
+
+        if ($this->getParam('csrf_token_enabled') && $include_csrf_token) {
+            // Include the csrf_token as a carried query argument.
+            // This token can be validated upon form submission with $app->verifyCSRFToken() or $app->requireValidCSRFToken()
+            $carry_args = is_array($carry_args) ? $carry_args : array();
+            $carry_args = array_merge($carry_args, array($this->getParam('csrf_token_name') => $this->getCSRFToken()));
         }
 
@@ -938,14 +944,15 @@
      *
      * @access  public
-     * @param   string  $url    Input URL to parse.
-     * @return  string          URL passed through $app->url() and then & turned to $amp;.
+     * @param   (see param reference for url() method)
+     * @return  string          URL passed through $app->url() with ampersamds transformed to $amp;
      * @author  Quinn Comendant <quinn@strangecode.com>
      * @since   09 Dec 2005 17:58:45
      */
-    public function oHREF($url, $carry_args=null, $always_include_sid=false)
-    {
-        $url = $this->url($url, $carry_args, $always_include_sid);
-
-        // Replace any & not followed by an html or unicode entity with it's &amp; equivalent.
+    public function oHREF($url, $carry_args=null, $always_include_sid=false, $include_csrf_token=false)
+    {
+        // Process the URL.
+        $url = $this->url($url, $carry_args, $always_include_sid, $include_csrf_token);
+
+        // Replace any & not followed by an html or unicode entity with its &amp; equivalent.
         $url = preg_replace('/&(?![\w\d#]{1,10};)/', '&amp;', $url);
 
@@ -1093,5 +1100,5 @@
             return false;
         }
-        $this->logMsg(sprintf('Verified CSRF token %s is in %s', $user_submitted_csrf_token, $csrf_token), LOG_DEBUG, __FILE__, __LINE__);
+        $this->logMsg(sprintf('Verified CSRF token %s', $user_submitted_csrf_token), LOG_DEBUG, __FILE__, __LINE__);
         return true;
     }
@@ -1142,5 +1149,5 @@
         }
 
-        if ('' == $url) {
+        if (!$url) {
             // If URL is not specified, use the redirect_home_url.
             $url = $this->getParam('redirect_home_url');
@@ -1295,11 +1302,11 @@
         }
 
-        $this->logMsg(sprintf('deleteBoomerangURL(%s): %s', $id, $this->getBoomerangURL($id)), LOG_DEBUG, __FILE__, __LINE__);
-
         if (isset($id) && isset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id])) {
+            $url = $this->getBoomerangURL($id);
             unset($_SESSION['_app'][$this->_ns]['boomerang']['url'][$id]);
         } else if (is_array($_SESSION['_app'][$this->_ns]['boomerang']['url'])) {
-            array_pop($_SESSION['_app'][$this->_ns]['boomerang']['url']);
-        }
+            $url = array_pop($_SESSION['_app'][$this->_ns]['boomerang']['url']);
+        }
+        $this->logMsg(sprintf('deleteBoomerangURL(%s): %s', $id, $url), LOG_DEBUG, __FILE__, __LINE__);
     }
 
Index: /trunk/lib/Auth_File.inc.php
===================================================================
--- /trunk/lib/Auth_File.inc.php	(revision 501)
+++ /trunk/lib/Auth_File.inc.php	(revision 502)
@@ -40,5 +40,6 @@
 // ));
 
-class Auth_File {
+class Auth_File
+{
 
     // Available encryption types for class Auth_File.
Index: /trunk/lib/Auth_SQL.inc.php
===================================================================
--- /trunk/lib/Auth_SQL.inc.php	(revision 501)
+++ /trunk/lib/Auth_SQL.inc.php	(revision 502)
@@ -30,5 +30,6 @@
 require_once dirname(__FILE__) . '/Email.inc.php';
 
-class Auth_SQL {
+class Auth_SQL
+{
 
     // Available hash types for class Auth_SQL.
@@ -181,22 +182,24 @@
                 userpass VARCHAR(255) NOT NULL DEFAULT '',
                 userpass_hashtype TINYINT UNSIGNED NOT NULL DEFAULT '0',
-                first_name VARCHAR(255) NOT NULL DEFAULT '',
-                last_name VARCHAR(255) NOT NULL DEFAULT '',
+                first_name VARCHAR(50) NOT NULL DEFAULT '',
+                last_name VARCHAR(50) NOT NULL DEFAULT '',
                 email VARCHAR(255) NOT NULL DEFAULT '',
-                login_abuse_exempt ENUM('TRUE') DEFAULT NULL,
-                blocked ENUM('TRUE') DEFAULT NULL,
+                login_abuse_exempt ENUM('true') DEFAULT NULL,
+                blocked ENUM('true') DEFAULT NULL,
                 blocked_reason VARCHAR(255) NOT NULL DEFAULT '',
-                abuse_warning_level TINYINT(4) NOT NULL DEFAULT '0',
-                seconds_online INT(11) NOT NULL DEFAULT '0',
+                abuse_warning_level TINYINT NOT NULL DEFAULT '0',
+                seconds_online INT NOT NULL DEFAULT '0',
                 last_login_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
                 last_access_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
-                last_login_ip VARCHAR(255) NOT NULL DEFAULT '0.0.0.0',
-                added_by_user_id SMALLINT(11) DEFAULT NULL,
-                modified_by_user_id SMALLINT(11) DEFAULT NULL,
+                last_login_ip VARCHAR(45) NOT NULL DEFAULT '0.0.0.0',
+                added_by_user_id SMALLINT DEFAULT NULL,
+                modified_by_user_id SMALLINT DEFAULT NULL,
                 added_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
                 modified_datetime DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
                 KEY " . $this->getParam('db_username_column') . " (" . $this->getParam('db_username_column') . "),
                 KEY userpass (userpass),
-                KEY email (email)
+                KEY email (email),
+                KEY last_login_datetime (last_login_datetime),
+                KEY last_access_datetime (last_access_datetime)
             )");
 
@@ -327,5 +330,5 @@
             $db->query("
                 UPDATE " . $this->_params['db_table'] . " SET
-                seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)),
+                seconds_online = seconds_online + ABS(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)),
                 last_login_datetime = '0000-00-00 00:00:00'
                 WHERE " . $this->_params['db_primary_key'] . " = '" . $this->get('user_id') . "'
@@ -635,5 +638,5 @@
             $db->query("
                 UPDATE " . $this->_params['db_table'] . " SET
-                seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)) + 1,
+                seconds_online = seconds_online + ABS(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)) + 1,
                 last_access_datetime = '" . $this->get('last_access_datetime') . "'
                 WHERE " . $this->_params['db_primary_key'] . " = '" . $this->get('user_id') . "'
@@ -981,7 +984,9 @@
         // Issue the password change query.
         $db->query("
-            UPDATE " . $this->_params['db_table'] . "
-            SET userpass = '" . $db->escapeString($this->encryptPassword($password, null, $hash_type)) . "'
-            $userpass_hashtype_clause
+            UPDATE " . $this->_params['db_table'] . " SET
+                userpass = '" . $db->escapeString($this->encryptPassword($password, null, $hash_type)) . "',
+                modified_datetime = NOW(),
+                modified_by_user_id = '" . $db->escapeString($user_id) . "'
+                $userpass_hashtype_clause
             WHERE " . $this->_params['db_primary_key'] . " = '" . $db->escapeString($user_id) . "'
         ");
Index: /trunk/lib/AuthorizeNet.inc.php
===================================================================
--- /trunk/lib/AuthorizeNet.inc.php	(revision 501)
+++ /trunk/lib/AuthorizeNet.inc.php	(revision 502)
@@ -59,5 +59,6 @@
 // }
 
-class AuthorizeNet {
+class AuthorizeNet
+{
 
     public $post_url = ''; // The URL to post data to.
Index: /trunk/lib/CSS.inc.php
===================================================================
--- /trunk/lib/CSS.inc.php	(revision 501)
+++ /trunk/lib/CSS.inc.php	(revision 502)
@@ -29,5 +29,6 @@
  * @version 1.2
  */
-class CSS {
+class CSS
+{
 
     // Include these style sheets.
Index: /trunk/lib/Cache.inc.php
===================================================================
--- /trunk/lib/Cache.inc.php	(revision 501)
+++ /trunk/lib/Cache.inc.php	(revision 502)
@@ -32,5 +32,6 @@
  */
 
-class Cache {
+class Cache
+{
 
     // A place to keep object instances for the singleton pattern.
Index: /trunk/lib/Captcha.inc.php
===================================================================
--- /trunk/lib/Captcha.inc.php	(revision 501)
+++ /trunk/lib/Captcha.inc.php	(revision 502)
@@ -52,5 +52,6 @@
 -------------------------------------------------------------------------------------
  */
-class Captcha {
+class Captcha
+{
 
     public $secret_key = 'some random seed text for the md5';
Index: /trunk/lib/Cart.inc.php
===================================================================
--- /trunk/lib/Cart.inc.php	(revision 501)
+++ /trunk/lib/Cart.inc.php	(revision 502)
@@ -68,5 +68,6 @@
 ---------------------------------------------------------------------
  */
-class Cart {
+class Cart
+{
 
     // Namespace of this instance.
Index: /trunk/lib/Currency.inc.php
===================================================================
--- /trunk/lib/Currency.inc.php	(revision 501)
+++ /trunk/lib/Currency.inc.php	(revision 502)
@@ -38,5 +38,6 @@
  */
 
-class Currency {
+class Currency
+{
 
     // Configuration parameters for this object.
Index: /trunk/lib/DB.inc.php
===================================================================
--- /trunk/lib/DB.inc.php	(revision 501)
+++ /trunk/lib/DB.inc.php	(revision 502)
@@ -30,5 +30,6 @@
  */
 
-class DB {
+class DB
+{
 
     // A place to keep an object instance for the singleton pattern.
Index: /trunk/lib/DBSessionHandler.inc.php
===================================================================
--- /trunk/lib/DBSessionHandler.inc.php	(revision 501)
+++ /trunk/lib/DBSessionHandler.inc.php	(revision 502)
@@ -30,5 +30,6 @@
  */
 
-class DBSessionHandler {
+class DBSessionHandler
+{
 
     public $db; // DB object.
Index: /trunk/lib/Email.inc.php
===================================================================
--- /trunk/lib/Email.inc.php	(revision 501)
+++ /trunk/lib/Email.inc.php	(revision 502)
@@ -53,5 +53,6 @@
 */
 
-class Email {
+class Email
+{
 
     // Default parameters, to be overwritten by setParam() and read with getParam()
@@ -244,4 +245,26 @@
     }
 
+    /*
+    * Returns the body of the current email. This can be used to store the message that is being sent.
+    * It will use the original template, or the replaced template if it has been processed.
+    *
+    * @access   public
+    * @return   string  Message body.
+    * @author   Quinn Comendant <quinn@strangecode.com>
+    * @version  1.0
+    * @since    18 Nov 2014 21:15:19
+    */
+    public function getBody()
+    {
+        $final_body = isset($this->_template_replaced) ? $this->_template_replaced : $this->_template;
+        // Ensure all placeholders have been replaced. Find anything with {...} characters.
+        if (preg_match('/({[^}]+})/', $final_body, $unreplaced_match)) {
+            unset($unreplaced_match[0]);
+            $app->logMsg(sprintf('Cannot get email body. Unreplaced variables in template: %s', getDump($unreplaced_match)), LOG_ERR, __FILE__, __LINE__);
+            return false;
+        }
+        return $final_body;
+    }
+
     /**
      * Send email using PHP's mail() function.
@@ -295,5 +318,6 @@
         // Ensure all placeholders have been replaced. Find anything with {...} characters.
         if (preg_match('/({[^}]+})/', $final_body, $unreplaced_match)) {
-            $app->logMsg(sprintf('Cannot send email. At least one variable left unreplaced in template: %s', (isset($unreplaced_match[1]) ? $unreplaced_match[1] : '')), LOG_ERR, __FILE__, __LINE__);
+            unset($unreplaced_match[0]);
+            $app->logMsg(sprintf('Cannot send email. Unreplaced variables in template: %s', getDump($unreplaced_match)), LOG_ERR, __FILE__, __LINE__);
             return false;
         }
Index: /trunk/lib/FormValidator.inc.php
===================================================================
--- /trunk/lib/FormValidator.inc.php	(revision 501)
+++ /trunk/lib/FormValidator.inc.php	(revision 502)
@@ -58,5 +58,6 @@
 require_once 'codebase/lib/Validator.inc.php';
 
-class FormValidator {
+class FormValidator
+{
 
     // Class parameters.
Index: /trunk/lib/HTML.inc.php
===================================================================
--- /trunk/lib/HTML.inc.php	(revision 501)
+++ /trunk/lib/HTML.inc.php	(revision 502)
@@ -38,5 +38,6 @@
 */
 
-class HTML {
+class HTML
+{
 
     // Browsers add names and ids of form controls as properties to the FORM. This results in the properties of the form being replaced.
Index: /trunk/lib/Hierarchy.inc.php
===================================================================
--- /trunk/lib/Hierarchy.inc.php	(revision 501)
+++ /trunk/lib/Hierarchy.inc.php	(revision 502)
@@ -42,5 +42,6 @@
  */
 
-class Hierarchy {
+class Hierarchy
+{
 
     /**
Index: /trunk/lib/Image.inc.php
===================================================================
--- /trunk/lib/Image.inc.php	(revision 501)
+++ /trunk/lib/Image.inc.php	(revision 502)
@@ -28,5 +28,6 @@
  * @since   14 Apr 2006 20:07:29
  */
-class Image {
+class Image
+{
 
     // Object parameters.
Index: /trunk/lib/ImageThumb.inc.php
===================================================================
--- /trunk/lib/ImageThumb.inc.php	(revision 501)
+++ /trunk/lib/ImageThumb.inc.php	(revision 502)
@@ -40,5 +40,6 @@
 define('IMAGETHUMB_METHOD_GD', 7);
 
-class ImageThumb {
+class ImageThumb
+{
 
     // General object parameters.
Index: /trunk/lib/JS.inc.php
===================================================================
--- /trunk/lib/JS.inc.php	(revision 501)
+++ /trunk/lib/JS.inc.php	(revision 502)
@@ -29,5 +29,6 @@
  * @version 1.2
  */
-class JS {
+class JS
+{
 
     // Include these style sheets.
Index: /trunk/lib/Lock.inc.php
===================================================================
--- /trunk/lib/Lock.inc.php	(revision 501)
+++ /trunk/lib/Lock.inc.php	(revision 502)
@@ -29,5 +29,6 @@
  * @version 2.1
  */
-class Lock {
+class Lock
+{
 
     // A place to keep an object instance for the singleton pattern.
Index: /trunk/lib/Navigation.inc.php
===================================================================
--- /trunk/lib/Navigation.inc.php	(revision 501)
+++ /trunk/lib/Navigation.inc.php	(revision 502)
@@ -34,5 +34,6 @@
  * @version 2.0
  */
-class Navigation {
+class Navigation
+{
 
     // Configuration parameters for this object.
Index: /trunk/lib/PEdit.inc.php
===================================================================
--- /trunk/lib/PEdit.inc.php	(revision 501)
+++ /trunk/lib/PEdit.inc.php	(revision 502)
@@ -67,5 +67,6 @@
 
  */
-class PEdit {
+class PEdit
+{
 
     // PEdit object parameters.
Index: /trunk/lib/PageNumbers.inc.php
===================================================================
--- /trunk/lib/PageNumbers.inc.php	(revision 501)
+++ /trunk/lib/PageNumbers.inc.php	(revision 502)
@@ -37,5 +37,6 @@
 require_once dirname(__FILE__) . '/Prefs.inc.php';
 
-class PageNumbers {
+class PageNumbers
+{
 
     public $total_items;       // Total quantity of items.
Index: /trunk/lib/PayPal.inc.php
===================================================================
--- /trunk/lib/PayPal.inc.php	(revision 501)
+++ /trunk/lib/PayPal.inc.php	(revision 502)
@@ -30,5 +30,6 @@
  * @version 1.0
  */
-class PayPal {
+class PayPal
+{
 
     // General object parameters.
Index: /trunk/lib/Prefs.inc.php
===================================================================
--- /trunk/lib/Prefs.inc.php	(revision 501)
+++ /trunk/lib/Prefs.inc.php	(revision 502)
@@ -52,5 +52,6 @@
 ---------------------------------------------------------------------
  */
-class Prefs {
+class Prefs
+{
 
     // Namespace of this instance of Prefs.
Index: /trunk/lib/ScriptTimer.inc.php
===================================================================
--- /trunk/lib/ScriptTimer.inc.php	(revision 501)
+++ /trunk/lib/ScriptTimer.inc.php	(revision 502)
@@ -24,5 +24,6 @@
  * ScriptTimer.inc.php
  */
-class ScriptTimer {
+class ScriptTimer
+{
 
     public $time_format = '%.3f';
Index: /trunk/lib/SortOrder.inc.php
===================================================================
--- /trunk/lib/SortOrder.inc.php	(revision 501)
+++ /trunk/lib/SortOrder.inc.php	(revision 502)
@@ -35,5 +35,6 @@
 require_once dirname(__FILE__) . '/Prefs.inc.php';
 
-class SortOrder {
+class SortOrder
+{
 
     protected $_columns;
Index: /trunk/lib/SpellCheck.inc.php
===================================================================
--- /trunk/lib/SpellCheck.inc.php	(revision 501)
+++ /trunk/lib/SpellCheck.inc.php	(revision 502)
@@ -59,5 +59,6 @@
 */
 
-class SpellCheck {
+class SpellCheck
+{
 
     protected $_params = array(
Index: /trunk/lib/Upload.inc.php
===================================================================
--- /trunk/lib/Upload.inc.php	(revision 501)
+++ /trunk/lib/Upload.inc.php	(revision 502)
@@ -38,5 +38,6 @@
 define('UPLOAD_USER_ERR_MOVE_FAILED', 104);
 
-class Upload {
+class Upload
+{
 
     // General object parameters.
Index: /trunk/lib/Utilities.inc.php
===================================================================
--- /trunk/lib/Utilities.inc.php	(revision 501)
+++ /trunk/lib/Utilities.inc.php	(revision 502)
@@ -941,11 +941,7 @@
 /**
  * Signs a value using md5 and a simple text key. In order for this
- * function to be useful (i.e. secure) the key must be kept secret, which
+ * function to be useful (i.e. secure) the salt must be kept secret, which
  * means keeping it as safe as database credentials. Putting it into an
  * environment variable set in httpd.conf is a good place.
- *
- * TODO: consider using more bits-per-character, such as done with:
- * http://www.php.net/manual/en/function.sha1.php#86239
- * http://blog.kevburnsjr.com/php-unique-hash
  *
  * @access  public
@@ -999,4 +995,5 @@
  * @param   string  $signed_val A value with appended signature.
  * @param   string  $salt       (Optional) A text key to use for computing the signature.
+ * @param   string  $length (Optional) The length of the added signature.
  * @return  bool    True if the signature matches the var.
  */
Index: /trunk/lib/Validator.inc.php
===================================================================
--- /trunk/lib/Validator.inc.php	(revision 501)
+++ /trunk/lib/Validator.inc.php	(revision 502)
@@ -31,5 +31,6 @@
  */
 
-class Validator {
+class Validator
+{
 
     // Known credit card types.
Index: /trunk/lib/Version.inc.php
===================================================================
--- /trunk/lib/Version.inc.php	(revision 501)
+++ /trunk/lib/Version.inc.php	(revision 502)
@@ -37,5 +37,6 @@
  * @version 2.1
  */
-class Version {
+class Version
+{
 
     // A place to keep an object instance for the singleton pattern.
@@ -290,12 +291,16 @@
         }
 
-        // Replace current record with specified versioned record.
+        // Disable foreign_key_checks to prevent ON DELETE triggers or restrictions.
+        $db->query("SET SESSION foreign_key_checks = 0");
+        // Replace current record with specified versioned record. Consider converting this SQL to use INSERT âŠ ON DUPLICATE KEY UPDATE âŠ
         $db->query("
-            REPLACE INTO " . $record['record_table'] . " (
+        REPLACE INTO " . $record['record_table'] . " (
                 $replace_keys
             ) VALUES (
                 $replace_values
-            )
-        ");
+            );
+        ");
+        // Re-enable foreign_key_checks.
+        $db->query("SET SESSION foreign_key_checks = 1");
 
         return $record;
@@ -468,6 +473,12 @@
     {
         $db =& DB::getInstance();
-
-        $this->initDB();
+        $app =& App::getInstance();
+
+        $this->initDB();
+
+        if (!$record_table || !$record_key || !$record_val) {
+            $app->logMsg(sprintf('Invalid current version args: %s, %s, %s.', $record_table, $record_key, $record_val), LOG_ERR, __FILE__, __LINE__);
+            return false;
+        }
 
         $qid = $db->query("
Index: /trunk/services/templates/versions_diff.ihtml
===================================================================
--- /trunk/services/templates/versions_diff.ihtml	(revision 501)
+++ /trunk/services/templates/versions_diff.ihtml	(revision 502)
@@ -45,7 +45,7 @@
             $action_links = array();
             if (!getFormData('current', false)) {
-                $action_links[] = array('href' => $app->oHREF($_SERVER['PHP_SELF'] . '?op=restore', array('version_id', 'version_title')), 'value' => _("Restore this saved version"), 'class' => 'small button alert', 'accesskey' => 'r');
+                $action_links[] = array('href' => $app->oHREF('?op=restore', array('version_id', 'version_title')), 'value' => _("Restore this saved version"), 'class' => 'small button alert', 'accesskey' => 'r');
             }
-            $action_links[] = array('href' => $app->ohref(oTxt($_SERVER['PHP_SELF'])), 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'b');
+            $action_links[] = array('href' => $app->ohref('?op=cancel'), 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c');
             HTML::printButtons($action_links);
             ?>
Index: /trunk/services/templates/versions_list.ihtml
===================================================================
--- /trunk/services/templates/versions_list.ihtml	(revision 501)
+++ /trunk/services/templates/versions_list.ihtml	(revision 502)
@@ -50,7 +50,8 @@
                 <div class="sc-help"><?php printf(_("When there are more than %s versions, those over %s days old are deleted."), $version->getParam('min_qty'), $version->getParam('min_days')); ?></div>
                 <?php
-                HTML::printButtons(array(
-                    array('name' => 'op', 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c'),
-                ));
+                // Buttons.
+                $action_links = array();
+                $action_links[] = array('href' => $app->ohref('?op=cancel'), 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c');
+                HTML::printButtons($action_links);
                 ?>
             </div>
Index: /trunk/services/templates/versions_view.ihtml
===================================================================
--- /trunk/services/templates/versions_view.ihtml	(revision 501)
+++ /trunk/services/templates/versions_view.ihtml	(revision 502)
@@ -28,7 +28,7 @@
             $action_links = array();
             if (!getFormData('current', false)) {
-                $action_links[] = array('href' => $app->oHREF($_SERVER['PHP_SELF'] . '?op=restore', array('version_id', 'version_title')), 'value' => _("Restore this saved version"), 'class' => 'small button alert', 'accesskey' => 'r');
+                $action_links[] = array('href' => $app->oHREF('?op=restore', array('version_id', 'version_title')), 'value' => _("Restore this saved version"), 'class' => 'small button alert', 'accesskey' => 'r');
             }
-            $action_links[] = array('href' => $app->ohref(oTxt($_SERVER['PHP_SELF'])), 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'b');
+            $action_links[] = array('href' => $app->ohref('?op=cancel'), 'value' => _("Cancel"), 'class' => 'small button secondary', 'accesskey' => 'c');
             HTML::printButtons($action_links);
             ?>
Index: /trunk/services/versions.php
===================================================================
--- /trunk/services/versions.php	(revision 501)
+++ /trunk/services/versions.php	(revision 502)
@@ -78,6 +78,11 @@
 switch (getFormData('op')) {
 
-case _("Cancel") :
-    $app->dieBoomerangURL('versions', false);
+case 'cancel' :
+    if ($app->validBoomerangURL('version')) {
+        // Display boomerang page.
+        $app->dieBoomerangURL('version');
+    }
+    // Display default page.
+    $app->dieURL(false, false);
     break;
 
