/** * Logs a message at the given log level. This function should not be called by * any code outside of this module. * * @param string $message The message to display * @param int $loglevel The level to log the message at * @param bool $escape Whether to HTML escape the message * @param bool $backtrace Whether to provide a backtrace if the system is * configured to give backtraces at this level. * @param string $file The file the error occurred in * @param int $line The line number the error occurred on * @param array $trace The backtrace for the error * @access private */ function log_message($message, $loglevel, $escape, $backtrace, $file = null, $line = null, $trace = null) { global $SESSION, $CFG; if (!$SESSION && function_exists('get_config') && $CFG) { require_once get_config('docroot') . 'auth/lib.php'; $SESSION = Session::singleton(); } static $requestprefix = ''; if (!$requestprefix) { $requestprefix = substr(md5(microtime()), 0, 2) . ' '; } static $loglevelnames = array(LOG_LEVEL_ENVIRON => 'environ', LOG_LEVEL_DBG => 'dbg', LOG_LEVEL_INFO => 'info', LOG_LEVEL_WARN => 'warn'); if (!function_exists('get_config') || null === ($targets = get_config('log_' . $loglevelnames[$loglevel] . '_targets'))) { $targets = LOG_TARGET_SCREEN | LOG_TARGET_ERRORLOG; } // Get nice backtrace information if required $trace = $trace ? $trace : debug_backtrace(); // If the last caller was the 'error' function then it came from a PHP warning if (!is_null($file)) { $filename = $file; $linenum = $line; } else { $filename = $trace[1]['file']; $linenum = $trace[1]['line']; } if (!function_exists('get_config') || get_config('log_backtrace_levels') & $loglevel) { list($textbacktrace, $htmlbacktrace) = log_build_backtrace($trace); } else { $textbacktrace = $htmlbacktrace = ''; } if (is_bool($message)) { $loglines = array($message ? 'bool(true)' : 'bool(false)'); } else { if (is_null($message)) { $loglines = array('NULL'); } else { $loglines = explode("\n", print_r($message, true)); } } // Make a prefix for each line, if we are logging a normal debug/info/warn message $prefix = $requestprefix; if ($loglevel != LOG_LEVEL_ENVIRON && function_exists('get_config')) { $docroot = get_config('docroot'); $prefixfilename = substr($filename, 0, strlen($docroot)) == $docroot ? substr($filename, strlen($docroot)) : $filename; $prefix .= '(' . $prefixfilename . ':' . $linenum . ') '; } $prefix = '[' . str_pad(substr(strtoupper($loglevelnames[$loglevel]), 0, 3), 3) . '] ' . $prefix; if ($targets & LOG_TARGET_SCREEN || defined('ADMIN') && $targets & LOG_TARGET_ADMIN) { // Work out which method to call for displaying the message if ($loglevel == LOG_LEVEL_DBG || $loglevel == LOG_LEVEL_INFO) { $method = 'add_info_msg'; } else { $method = 'add_error_msg'; } $message = implode("\n", $loglines); if ($escape) { $message = htmlspecialchars($message, ENT_COMPAT, 'UTF-8'); $message = str_replace(' ', ' ', $message); } $message = nl2br($message); $message = '<div class="backtrace">' . $prefix . $message . "</div>\n"; if (is_a($SESSION, 'Session')) { $SESSION->{$method}($message, false); } else { if (!function_exists('get_config') || get_config('installed')) { // Don't output when we are not installed, since this will cause the // redirect to the install page to fail. echo $message; } } if ($backtrace && $htmlbacktrace) { if (is_a($SESSION, 'Session')) { $SESSION->add_info_msg($htmlbacktrace, false); } else { if (!function_exists('get_config') || get_config('installed')) { echo $htmlbacktrace; } } } } if ($targets & LOG_TARGET_ERRORLOG) { foreach ($loglines as $line) { error_log($prefix . $line); } if ($backtrace && $textbacktrace) { $lines = explode("\n", $textbacktrace); foreach ($lines as $line) { error_log($line); } } } if ($targets & LOG_TARGET_STDOUT) { foreach ($loglines as $line) { echo $prefix . $line . "\n"; } if ($backtrace && $textbacktrace) { echo $textbacktrace; } } if (function_exists('get_config')) { if (!($logfilename = get_config('log_file'))) { $logfilename = get_config('dataroot') . 'error.log'; } if ($targets & LOG_TARGET_FILE && $logfilename) { global $LOGFILE_FH; static $logfile_open_attempted = null; if (!$logfile_open_attempted) { $logfile_open_attempted = true; $LOGFILE_FH = fopen($logfilename, 'wb'); if ($LOGFILE_FH !== false) { function _close_logfile() { global $LOGFILE_FH; fclose($LOGFILE_FH); } register_shutdown_function('_close_logfile'); } else { error_log("Could not open your custom log file ({$logfilename})"); } } if (is_resource($LOGFILE_FH)) { foreach ($loglines as $line) { fwrite($LOGFILE_FH, $prefix . $line . "\n"); } if ($backtrace && $textbacktrace) { $lines = explode("\n", $textbacktrace); foreach ($lines as $line) { fwrite($LOGFILE_FH, $line . "\n"); } } } } } }
if (isset($upgrade->install)) { $data['install'] = $upgrade->install; log_info('- ' . str_pad($data['key'], 30, ' ') . ' ' . $data['newversion']); } else { $data['upgrade'] = true; log_info('Upgraded ' . $data['key'] . ' to ' . $data['newversion']); } $data['error'] = false; $data['feedback'] = $SESSION->render_messages(); if (param_boolean('last', false)) { delete_records('config', 'field', '_upgrade'); } json_reply(false, $data); exit; } catch (Exception $e) { list($texttrace, $htmltrace) = log_build_backtrace($e->getTrace()); $data['errormessage'] = $e->getMessage() . '<br>' . $htmltrace; $data['error'] = true; if (table_exists(new XMLDBTable('config'))) { delete_records('config', 'field', '_upgrade'); } json_reply('local', $data); exit; } } else { // Nothing to upgrade. This can happen when a plugin upgrade was found // in the original list of upgrades generated on admin/upgrade.php, but // the core upgrade has already upgraded that plugin, so we're trying to // upgrade it again. // It seems a bit wrong. For one thing, the core upgrade probably // shouldn't upgrade plugins past the version that was current at the