Index: trunk/lib/App.inc.php
===================================================================
--- trunk/lib/App.inc.php	(revision 383)
+++ trunk/lib/App.inc.php	(revision 390)
@@ -62,5 +62,5 @@
         // Public name and email address for this application.
         'site_name' => null,
-        'site_email' => null,
+        'site_email' => '', // Set to no-reply@HTTP_HOST if not set here.
         'site_url' => '', // URL automatically determined by _SERVER['HTTP_HOST'] if not set here.
         'images_path' => '', // Location for codebase-generated interface widgets (ex: "/admin/i").
@@ -126,6 +126,6 @@
         'log_filename' => 'app_log',
 
-        // Don't email or sms duplicate messages that happen more often than this value (in seconds).
-        'log_multiple_timeout' => 300,
+        // Don't email or SMS duplicate messages that happen more often than this value (in seconds).
+        'log_multiple_timeout' => 3600, // Hourly
 
         // Logging priority can be any of the following, or false to deactivate:
@@ -143,5 +143,5 @@
         'log_screen_priority' => false,
 
-        // Email address to receive log event emails.
+        // Email address to receive log event emails. Use multiple addresses by separating them with commas.
         'log_to_email_address' => null,
 
@@ -357,4 +357,9 @@
             $this->setParam(array('site_url' => sprintf('%s://%s', ('on' == getenv('HTTPS') ? 'https' : 'http'), getenv('HTTP_HOST'))));
         }
+        
+        // In case site_email isn't set, use something halfway presentable.
+        if (isset($_SERVER['HTTP_HOST']) && '' != $_SERVER['HTTP_HOST'] && '' == $this->getParam('site_email')) {
+            $this->setParam(array('site_email' => sprintf('no-reply@%s', getenv('HTTP_HOST'))));
+        }
 
         // A key for calculating simple cryptographic signatures.
@@ -525,17 +530,18 @@
     /**
      * Logs messages to defined channels: file, email, sms, and screen. Repeated messages are
-     * not repeated but printed once with count.
+     * not repeated but printed once with count. Log events that match a sendable channel (email or SMS)
+     * are sent once per 'log_multiple_timeout' setting (to avoid a flood of error emails).
      *
      * @access public
      * @param string $message   The text description of the message.
      * @param int    $priority  The type of message priority (in descending order):
-     *                          LOG_EMERG     system is unusable
-     *                          LOG_ALERT     action must be taken immediately
-     *                          LOG_CRIT      critical conditions
-     *                          LOG_ERR       error conditions
-     *                          LOG_WARNING   warning conditions
-     *                          LOG_NOTICE    normal, but significant, condition
-     *                          LOG_INFO      informational message
-     *                          LOG_DEBUG     debug-level message
+     *                          LOG_EMERG     0 system is unusable
+     *                          LOG_ALERT     1 action must be taken immediately
+     *                          LOG_CRIT      2 critical conditions
+     *                          LOG_ERR       3 error conditions
+     *                          LOG_WARNING   4 warning conditions
+     *                          LOG_NOTICE    5 normal, but significant, condition
+     *                          LOG_INFO      6 informational message
+     *                          LOG_DEBUG     7 debug-level message
      * @param string $file      The file where the log event occurs.
      * @param string $line      The line of the file where the log event occurs.
@@ -556,4 +562,13 @@
             // We must use trigger_error to report this problem rather than calling $app->logMsg, which might lead to an infinite loop.
             trigger_error(sprintf('Codebase error: log directory (%s) not found or writable.', $this->getParam('log_directory')), E_USER_NOTICE);
+        }
+        
+        // Before we get any further, let's see if ANY log events are configured to be reported.
+        if ((false === $this->getParam('log_file_priority') || $priority > $this->getParam('log_file_priority'))
+        && (false === $this->getParam('log_email_priority') || $priority > $this->getParam('log_email_priority'))
+        && (false === $this->getParam('log_sms_priority') || $priority > $this->getParam('log_sms_priority'))
+        && (false === $this->getParam('log_screen_priority') || $priority > $this->getParam('log_screen_priority'))) {
+            // This event would not be recorded, skip it entirely.
+            return false;
         }
 
@@ -578,28 +593,31 @@
         }
 
-        // Use "lock" files to prevent sending email and sms notices ad infinitum.
-        $site_hash = md5($_SERVER['SCRIPT_NAME']);
-        $temp_dir = $this->getParam('tmp_dir') . "/codebase_msgs_$site_hash/";
-        $temp_file = $temp_dir . md5($file . $line); // Just use the file and line for the msg_id to limit the number of possible messages.
-        if (!is_dir($temp_dir)) {
-            mkdir($temp_dir);
-        }
-        $send_notifications = true;
-        if (is_file($temp_file)) {
-            $msg_last_sent = filectime($temp_file);
-            // Has this message been sent more recently than the timeout?
-            if ((time() - $msg_last_sent) <= $this->getParam('log_multiple_timeout')) {
-                // This message was already sent recently.
-                $send_notifications = false;
+        // For email and SMS notification types use "lock" files to prevent sending email and SMS notices ad infinitum.
+        if ((false !== $this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority'))
+        || (false !== $this->getParam('log_sms_priority') && $priority <= $this->getParam('log_sms_priority'))) {
+            // This event will generate a "send" notification. Prepare lock file.
+            $site_hash = md5(empty($_SERVER['SERVER_NAME']) ? $_SERVER['SCRIPT_FILENAME'] : $_SERVER['SERVER_NAME']);
+            $lock_dir = $this->getParam('tmp_dir') . "/codebase_msgs_$site_hash/";
+            // Just use the file and line for the msg_id to limit the number of possible messages 
+            // (the message string itself shan't be used as it may contain innumerable combinations).
+            $lock_file = $lock_dir . md5($file . ':' . $line);
+            if (!is_dir($lock_dir)) {
+                mkdir($lock_dir);
+            }
+            $send_notifications = true;
+            if (is_file($lock_file)) {
+                $msg_last_sent = filectime($lock_file);
+                // Has this message been sent more recently than the timeout?
+                if ((time() - $msg_last_sent) <= $this->getParam('log_multiple_timeout')) {
+                    // This message was already sent recently.
+                    $send_notifications = false;
+                } else {
+                    // Timeout has expired; send notifications again and reset timeout.
+                    touch($lock_file);
+                }
             } else {
-                // Timeout has expired go ahead and send notifications again.
-                if (file_exists($temp_file)) {
-                    unlink($temp_file);
-                }
-            }
-        } else {
-            touch($temp_file);
-        }
-        
+                touch($lock_file);
+            }
+        }
         
         // Data to be stored for a log event.
@@ -615,33 +633,30 @@
 
         // FILE ACTION
-        if ($this->getParam('log_file_priority') && $priority <= $this->getParam('log_file_priority')) {
+        if (false !== $this->getParam('log_file_priority') && $priority <= $this->getParam('log_file_priority')) {
             $event_str = '[' . join('] [', $event) . ']';
             error_log(mb_substr($event_str, 0, 1024) . "\n", 3, $this->getParam('log_directory') . '/' . $this->getParam('log_filename'));
         }
 
-        // NOTIFY SOMEONE
-        if ($send_notifications) {
-            // EMAIL ACTION
-            if ($this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority')) {
-                $subject = sprintf('[%s %s] %s', getenv('HTTP_HOST'), $event['type'], $message);
-                $email_msg = sprintf("A %s log event occured on %s\n\n", $event['type'], getenv('HTTP_HOST'));
-                $headers = "From: codebase@strangecode.com";
-                foreach ($event as $k=>$v) {
-                    $email_msg .= sprintf("%-11s%s\n", $k, $v);
-                }
-                mb_send_mail($this->getParam('log_to_email_address'), $subject, $email_msg, $headers);
-            }
-    
-            // SMS ACTION
-            if ($this->getParam('log_sms_priority') && $priority <= $this->getParam('log_sms_priority')) {
-                $subject = sprintf('[%s %s]', getenv('HTTP_HOST'), $priority);
-                $sms_msg = sprintf('%s [%s:%s]', mb_substr($event['message'], 0, 64), basename($file), $line);
-                $headers = "From: codebase@strangecode.com";
-                mb_send_mail($this->getParam('log_to_sms_address'), $subject, $sms_msg, $headers);
-            }
+        // EMAIL ACTION
+        if (false !== $this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority') && $send_notifications) {
+            $subject = sprintf('[%s %s] %s', getenv('HTTP_HOST'), $event['type'], mb_substr($message, 0, 64));
+            $email_msg = sprintf("A %s log event occurred on %s\n\n", $event['type'], getenv('HTTP_HOST'));
+            $headers = 'From: ' . $this->getParam('site_email');
+            foreach ($event as $k=>$v) {
+                $email_msg .= sprintf("%-11s%s\n", $k, $v);
+            }
+            mb_send_mail($this->getParam('log_to_email_address'), $subject, $email_msg, $headers);
+        }
+
+        // SMS ACTION
+        if (false !== $this->getParam('log_sms_priority') && $priority <= $this->getParam('log_sms_priority') && $send_notifications) {
+            $subject = sprintf('[%s %s]', getenv('HTTP_HOST'), $priority);
+            $sms_msg = sprintf('%s [%s:%s]', mb_substr($event['message'], 0, 64), basename($file), $line);
+            $headers = 'From: ' . $this->getParam('site_email');
+            mb_send_mail($this->getParam('log_to_sms_address'), $subject, $sms_msg, $headers);
         }
     
         // SCREEN ACTION
-        if ($this->getParam('log_screen_priority') && $priority <= $this->getParam('log_screen_priority')) {
+        if (false !== $this->getParam('log_screen_priority') && $priority <= $this->getParam('log_screen_priority')) {
             echo "[{$event['type']}] [{$event['message']}]\n";
         }
@@ -649,4 +664,6 @@
         // Restore original locale.
         setlocale(LC_TIME, $locale);
+        
+        return true;
     }
 
Index: trunk/lib/Cart.inc.php
===================================================================
--- trunk/lib/Cart.inc.php	(revision 383)
+++ trunk/lib/Cart.inc.php	(revision 390)
@@ -279,6 +279,4 @@
     function sum($key='extended_price')
     {
-        global $app;
-
 		$sum = 0;
         switch ($key) {
@@ -294,5 +292,5 @@
 
         default :
-            // Retreive arbitrary values stored in the cart (shipping, air miles, etc).
+            // Retrieve arbitrary values stored in the cart (shipping, air miles, etc).
             foreach ($_SESSION['_cart'][$this->_ns]['items'] as $item_id => $specs) {
                 $sum += isset($specs[$key]) && is_numeric($specs[$key]) ? $specs[$key] * $specs['quantity'] : 0;
Index: trunk/lib/Hierarchy.inc.php
===================================================================
--- trunk/lib/Hierarchy.inc.php	(revision 383)
+++ trunk/lib/Hierarchy.inc.php	(revision 390)
@@ -122,5 +122,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("toStringID failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('toStringID failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -154,5 +154,5 @@
             return array('node_type' => $node_parts[1], 'node_id' => $node_parts[2]);
         } else {
-            $app->logMsg(_("Cannot parse node identifier, not formated correctly."), LOG_ERR, __FILE__, __LINE__);
+            $app->logMsg('Cannot parse node identifier, not formated correctly.'), LOG_ERR, __FILE__, __LINE__);
             return false;
         }
@@ -177,5 +177,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("insertNode failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('insertNode failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -256,5 +256,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("deleteNode failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('deleteNode failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -306,5 +306,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("moveNode failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('moveNode failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -383,5 +383,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("getParents failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('getParents failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -434,5 +434,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("getNode failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('getNode failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -478,5 +478,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("getChildren failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('getChildren failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -530,5 +530,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("getNumberChildren failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('getNumberChildren failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -570,5 +570,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("isLeaf failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('isLeaf failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -686,5 +686,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("nodeExists failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('nodeExists failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
@@ -740,5 +740,5 @@
                 $child_id =& $this->child_id;
             } else {
-                $app->logMsg(_("getNodeList failed. Arguments not specified properly."), LOG_ERR, __FILE__, __LINE__);
+                $app->logMsg('getNodeList failed. Arguments not specified properly.'), LOG_ERR, __FILE__, __LINE__);
                 return false;
             }
