0 && $this->getParam('display_errors') && isset($m['file']) && isset($m['line'])) {
echo "\n';
}
switch ($m['type']) {
case MSG_ERR:
echo '
';
break;
case MSG_WARNING:
echo '
';
break;
case MSG_SUCCESS:
echo '
';
break;
case MSG_NOTICE:
default:
echo '
';
break;
}
}
if ('' != $below) {
?>
clearRaisedMessages();
return true;
}
/**
* Logs messages to defined channels: file, email, sms, and screen. Repeated messages are
* 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 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.
* @param string $url The URL where the log event occurs ($_SERVER['REQUEST_URI'] will be used if left null).
*/
public function logMsg($message, $priority=LOG_INFO, $file=null, $line=null, $url=null)
{
static $previous_events = array();
// If priority is not specified, assume the worst.
if (!$this->logPriorityToString($priority)) {
$this->logMsg(sprintf('Log priority %s not defined. (Message: %s)', $priority, $message), LOG_EMERG, $file, $line);
$priority = LOG_EMERG;
}
// In case __FILE__ and __LINE__ are not provided, note that fact.
$file = '' == $file ? 'unknown-file' : $file;
$line = '' == $line ? 'unknown-line' : $line;
// Get the URL, or used the provided value.
if (!isset($url)) {
$url = isset($_SERVER['REQUEST_URI']) ? mb_substr($_SERVER['REQUEST_URI'], 0, $this->getParam('log_message_max_length')) : '';
}
// If log file is not specified, don't log to a file.
if (!$this->getParam('log_directory') || !$this->getParam('log_filename') || !is_dir($this->getParam('log_directory')) || !is_writable($this->getParam('log_directory'))) {
$this->setParam(array('log_file_priority' => false));
// 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;
}
if ($this->getParam('log_serialize')) {
// Serialize multi-line messages.
$message = preg_replace('/\s+/m', ' ', trim($message));
}
// Store this event under a unique key, counting each time it occurs so that it only gets reported a limited number of times.
$msg_id = md5($message . $priority . $file . $line);
if ($this->getParam('log_ignore_repeated_events') && isset($previous_events[$msg_id])) {
$previous_events[$msg_id]++;
if ($previous_events[$msg_id] == 2) {
$this->logMsg(sprintf('%s (Event repeated %s or more times)', $message, $previous_events[$msg_id]), $priority, $file, $line);
}
return false;
} else {
$previous_events[$msg_id] = 1;
}
// 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 {
touch($lock_file);
}
}
// Use the system's locale for log messages (return to previous setting below).
$locale = setlocale(LC_TIME, 0);
setlocale(LC_TIME, 'C');
// Logs should always be in UTC (return to previous setting below).
$tz = date_default_timezone_get();
date_default_timezone_set('UTC');
// Data to be stored for a log event.
$event = array(
'date' => date('Y-m-d H:i:s'),
'remote ip' => getRemoteAddr(),
'pid' => getmypid(),
'type' => $this->logPriorityToString($priority),
'file:line' => "$file : $line",
'url' => $url,
'message' => mb_substr($message, 0, $this->getParam('log_message_max_length')),
);
// Here's a shortened version of event data.
$event_short = $event;
$event_short['url'] = truncate($event_short['url'], 120);
// Email info.
$hostname = ('' != $this->getParam('site_hostname')) ? $this->getParam('site_hostname') : php_uname('n');
$hostname = preg_replace('/^ww+\./', '', $hostname);
$headers = sprintf("From: %s\nX-File: %s\nX-Line: %s", $this->getParam('site_email'), $file, $line);
// FILE ACTION
if (false !== $this->getParam('log_file_priority') && $priority <= $this->getParam('log_file_priority')) {
$event_str = '[' . join('] [', $event_short) . ']';
error_log("$event_str\n", 3, $this->getParam('log_directory') . '/' . $this->getParam('log_filename'));
}
// EMAIL ACTION
if (false !== $this->getParam('log_email_priority') && $priority <= $this->getParam('log_email_priority') && '' != $this->getParam('log_to_email_address') && $send_notifications) {
$subject = sprintf('[%s %s] %s', $hostname, $event['type'], mb_substr($event['message'], 0, 64));
$email_msg = sprintf("A log event of type '%s' occurred on %s\n\n", $event['type'], $hostname);
foreach ($event as $k=>$v) {
$email_msg .= sprintf("%-16s %s\n", $k, $v);
}
$email_msg .= sprintf("%-16s %s\n", 'codebase version', $this->getParam('codebase_version'));
$email_msg .= sprintf("%-16s %s\n", 'site version', $this->getParam('site_version'));
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') && '' != $this->getParam('log_to_sms_address') && $send_notifications) {
$subject = sprintf('[%s %s]', $hostname, $this->logPriorityToString($priority));
$sms_msg = sprintf('%s [%s:%s]', mb_substr($event_short['message'], 0, 64), basename($file), $line);
mb_send_mail($this->getParam('log_to_sms_address'), $subject, $sms_msg, $headers);
}
// SCREEN ACTION
if (false !== $this->getParam('log_screen_priority') && $priority <= $this->getParam('log_screen_priority')) {
file_put_contents('php://stderr', "[{$event['type']}] [{$event['message']}]\n", FILE_APPEND);
}
// Restore original locale.
setlocale(LC_TIME, $locale);
// Restore original timezone.
date_default_timezone_set($tz);
return true;
}
/**
* Returns the string representation of a LOG_* integer constant.
* Updated: also returns the LOG_* integer constant if passed a string log value ('info' returns 6).
*
* @param int $priority The LOG_* integer constant (to return the string name), or a string name of a log priority to return the integer LOG_* value..
*
* @return The string representation of $priority (if integer given), or integer representation (if string given).
*/
public function logPriorityToString($priority) {
$priorities = array(
LOG_EMERG => 'emergency',
LOG_ALERT => 'alert',
LOG_CRIT => 'critical',
LOG_ERR => 'error',
LOG_WARNING => 'warning',
LOG_NOTICE => 'notice',
LOG_INFO => 'info',
LOG_DEBUG => 'debug'
);
if (isset($priorities[$priority])) {
return $priorities[$priority];
} else if (is_string($priority) && false !== ($key = array_search($priority, $priorities))) {
return $key;
} else {
return false;
}
}
/**
* Forcefully set a query argument even if one currently exists in the request.
* Values in the _carry_queries array will be copied to URLs (via $app->url()) and
* to hidden input values (via printHiddenSession()).
*
* @access public
* @param mixed $query_key The key (or keys, as an array) of the query argument to save.
* @param mixed $val The new value of the argument key.
* @author Quinn Comendant