'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_DEPRECATED => 'Deprecated Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_USER_DEPRECATED => 'User Deprecated Warning', E_STRICT => 'Runtime Notice', E_RECOVERABLE_ERROR => 'Catchable Fatal Error', MYBB_SQL => 'MyBB SQL Error', MYBB_TEMPLATE => 'MyBB Template Error', MYBB_GENERAL => 'MyBB Error', MYBB_NOT_INSTALLED => 'MyBB Error', MYBB_NOT_UPGRADED => 'MyBB Error', MYBB_INSTALL_DIR_EXISTS => 'MyBB Error', MYBB_SQL_LOAD_ERROR => 'MyBB Error', MYBB_CACHE_NO_WRITE => 'MyBB Error', MYBB_CACHEHANDLER_LOAD_ERROR => 'MyBB Error', ); /** * Array of MyBB error types * * @var array */ public $mybb_error_types = array( MYBB_SQL, MYBB_TEMPLATE, MYBB_GENERAL, MYBB_NOT_INSTALLED, MYBB_NOT_UPGRADED, MYBB_INSTALL_DIR_EXISTS, MYBB_SQL_LOAD_ERROR, MYBB_CACHE_NO_WRITE, MYBB_CACHEHANDLER_LOAD_ERROR, ); /** * Array of all of the error types to ignore * * @var array */ public $ignore_types = array( E_DEPRECATED, E_NOTICE, E_USER_NOTICE, E_STRICT ); /** * String of all the warnings collected * * @var string */ public $warnings = ""; /** * Is MyBB in an errornous state? (Have we received an error?) * * @var boolean */ public $has_errors = false; /** * Initializes the error handler * */ function __construct() { // Lets set the error handler in here so we can just do $handler = new errorHandler() and be all set up. $error_types = E_ALL; foreach($this->ignore_types as $bit) { $error_types = $error_types & ~$bit; } error_reporting($error_types); set_error_handler(array(&$this, "error"), $error_types); } /** * Parses a error for processing. * * @param string The error type (i.e. E_ERROR, E_FATAL) * @param string The error message * @param string The error file * @param integer The error line * @return boolean True if parsing was a success, otherwise assume a error */ function error($type, $message, $file=null, $line=0) { global $mybb; // Error reporting turned off (either globally or by @ before erroring statement) if(error_reporting() == 0) { return true; } if(in_array($type, $this->ignore_types)) { return true; } $file = str_replace(MYBB_ROOT, "", $file); $this->has_errors = true; // For some reason in the installer this setting is set to "<" $accepted_error_types = array('both', 'error', 'warning', 'none'); if(!in_array($mybb->settings['errortypemedium'], $accepted_error_types)) { $mybb->settings['errortypemedium'] = "both"; } if(defined("IN_TASK")) { global $task; require_once MYBB_ROOT."inc/functions_task.php"; if($file) { $filestr = " - Line: $line - File: $file"; } add_task_log($task, "{$this->error_types[$type]} - [$type] ".var_export($message, true)."{$filestr}"); } // Saving error to log file. if($mybb->settings['errorlogmedium'] == "log" || $mybb->settings['errorlogmedium'] == "both") { $this->log_error($type, $message, $file, $line); } // Are we emailing the Admin a copy? if($mybb->settings['errorlogmedium'] == "mail" || $mybb->settings['errorlogmedium'] == "both") { $this->email_error($type, $message, $file, $line); } // SQL Error if($type == MYBB_SQL) { $this->output_error($type, $message, $file, $line); } else { // Do we have a PHP error? if(my_strpos(my_strtolower($this->error_types[$type]), 'warning') === false) { $this->output_error($type, $message, $file, $line); } // PHP Error else { if($mybb->settings['errortypemedium'] == "none" || $mybb->settings['errortypemedium'] == "error") { echo "
MyBB Internal: One or more warnings occured. Please contact your administrator for assistance.
"; } else { global $templates; $warning = "{$this->error_types[$type]} [$type] $message - Line: $line - File: $file PHP ".PHP_VERSION." (".PHP_OS.")
\n"; if(is_object($templates) && method_exists($templates, "get") && !defined("IN_ADMINCP")) { $this->warnings .= $warning; $this->warnings .= $this->generate_backtrace(); } else { echo "
{$warning}".$this->generate_backtrace()."
"; } } } } return true; } /** * Returns all the warnings * * @return string The warnings */ function show_warnings() { global $lang, $templates; if(empty($this->warnings)) { return false; } // Incase a template fails and we're recieving a blank page. if(MANUAL_WARNINGS) { echo $this->warnings."
"; } if(!$lang->warnings) { $lang->warnings = "The following warnings occured:"; } if(defined("IN_ADMINCP")) { $warning = makeacpphpwarning($this->warnings); } else { $template_exists = false; if(!is_object($templates) || !method_exists($templates, 'get')) { if(@file_exists(MYBB_ROOT."inc/class_templates.php")) { @require_once MYBB_ROOT."inc/class_templates.php"; $templates = new templates; $template_exists = true; } } else { $template_exists = true; } if($template_exists == true) { eval("\$warning = \"".$templates->get("php_warnings")."\";"); } } return $warning; } /** * Triggers a user created error * Example: $error_handler->trigger("Some Warning", E_USER_ERROR); * * @param string Message * @param string Type */ function trigger($message="", $type=E_USER_ERROR) { global $lang; if(!$message) { $message = $lang->unknown_user_trigger; } if(in_array($type, $this->mybb_error_types)) { $this->error($type, $message); } else { trigger_error($message, $type); } } /** * Logs the error in the specified error log file. * * @param string Warning type * @param string Warning message * @param string Warning file * @param integer Warning line */ function log_error($type, $message, $file, $line) { global $mybb; if($type == MYBB_SQL) { $message = "SQL Error: {$message['error_no']} - {$message['error']}\nQuery: {$message['query']}"; } $error_data = "\n"; $error_data .= "\t".TIME_NOW."\n"; $error_data .= "\t\n"; $error_data .= "\t".$line."\n"; $error_data .= "\t".$type."\n"; $error_data .= "\t".$this->error_types[$type]."\n"; $error_data .= "\t".$message."\n"; $error_data .= "\n\n"; if(trim($mybb->settings['errorloglocation']) != "") { @error_log($error_data, 3, $mybb->settings['errorloglocation']); } else { @error_log($error_data, 0); } } /** * Emails the error in the specified error log file. * * @param string Warning type * @param string Warning message * @param string Warning file * @param integer Warning line */ function email_error($type, $message, $file, $line) { global $mybb; if(!$mybb->settings['adminemail']) { return false; } if($type == MYBB_SQL) { $message = "SQL Error: {$message['error_no']} - {$message['error']}\nQuery: {$message['query']}"; } $message = "Your copy of MyBB running on {$mybb->settings['bbname']} ({$mybb->settings['bburl']}) has experienced an error. Details of the error include:\n---\nType: $type\nFile: $file (Line no. $line)\nMessage\n$message"; @my_mail($mybb->settings['adminemail'], "MyBB error on {$mybb->settings['bbname']}", $message, $mybb->settings['adminemail']); } function output_error($type, $message, $file, $line) { global $mybb, $parser; if(!$mybb->settings['bbname']) { $mybb->settings['bbname'] = "MyBB"; } if($type == MYBB_SQL) { $title = "MyBB SQL Error"; $error_message = "

MyBB has experienced an internal SQL error and cannot continue.

"; if($mybb->settings['errortypemedium'] == "both" || $mybb->settings['errortypemedium'] == "error" || defined("IN_INSTALL") || defined("IN_UPGRADE")) { $error_message .= "
\n"; $error_message .= "
SQL Error:
\n
{$message['error_no']} - {$message['error']}
\n"; if($message['query'] != "") { $error_message .= "
Query:
\n
{$message['query']}
\n"; } $error_message .= "
\n"; } } else { $title = "MyBB Internal Error"; $error_message = "

MyBB has experienced an internal error and cannot continue.

"; if($mybb->settings['errortypemedium'] == "both" || $mybb->settings['errortypemedium'] == "error" || defined("IN_INSTALL") || defined("IN_UPGRADE")) { $error_message .= "
\n"; $error_message .= "
Error Type:
\n
{$this->error_types[$type]} ($type)
\n"; $error_message .= "
Error Message:
\n
{$message}
\n"; if(!empty($file)) { $error_message .= "
Location:
File: {$file}
Line: {$line}
\n"; if(!@preg_match('#config\.php|settings\.php#', $file) && @file_exists($file)) { $code_pre = @file($file); $code = ""; if(isset($code_pre[$line-4])) { $code .= $line-3 . ". ".$code_pre[$line-4]; } if(isset($code_pre[$line-3])) { $code .= $line-2 . ". ".$code_pre[$line-3]; } if(isset($code_pre[$line-2])) { $code .= $line-1 . ". ".$code_pre[$line-2]; } $code .= $line . ". ".$code_pre[$line-1]; // The actual line. if(isset($code_pre[$line])) { $code .= $line+1 . ". ".$code_pre[$line]; } if(isset($code_pre[$line+1])) { $code .= $line+2 . ". ".$code_pre[$line+1]; } if(isset($code_pre[$line+2])) { $code .= $line+3 . ". ".$code_pre[$line+2]; } unset($code_pre); $parser_exists = false; if(!is_object($parser) || !method_exists($parser, 'mycode_parse_php')) { if(@file_exists(MYBB_ROOT."inc/class_parser.php")) { @require_once MYBB_ROOT."inc/class_parser.php"; $parser = new postParser; $parser_exists = true; } } else { $parser_exists = true; } if($parser_exists) { $code = $parser->mycode_parse_php($code, true); } else { $code = @nl2br($code); } $error_message .= "
Code:
{$code}
\n"; } } $backtrace = $this->generate_backtrace(); if($backtrace && !in_array($type, $this->mybb_error_types)) { $error_message .= "
Backtrace:
{$backtrace}
\n"; } $error_message .= "
\n"; } } if(isset($lang->settings['charset'])) { $charset = $lang->settings['charset']; } else { $charset = 'UTF-8'; } if(!headers_sent() && !defined("IN_INSTALL") && !defined("IN_UPGRADE")) { @header('HTTP/1.1 503 Service Temporarily Unavailable'); @header('Status: 503 Service Temporarily Unavailable'); @header('Retry-After: 1800'); @header("Content-type: text/html; charset={$charset}"); $_SERVER['PHP_SELF'] = htmlspecialchars_uni($_SERVER['PHP_SELF']); echo << {$mybb->settings['bbname']} - Internal Error

{$title}

{$error_message}
EOF; } else { echo << #mybb_error_content { border: 1px solid #B60101; background: #fff; } #mybb_error_content h2 { font-size: 12px; padding: 4px; background: #B60101; color: #fff; margin: 0; } #mybb_error_error { padding: 6px; } #mybb_error_footer { font-size: 11px; border-top: 1px solid #ccc; padding-top: 10px; } #mybb_error_content dt { font-weight: bold; }

{$title}

{$error_message}
EOF; } exit(1); } /** * Generates a backtrace if the server supports it. * * @return string The generated backtrace */ function generate_backtrace() { if(function_exists("debug_backtrace")) { $trace = debug_backtrace(); $backtrace = "\n"; $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n\n"; // Strip off this function from trace array_shift($trace); foreach($trace as $call) { if(empty($call['file'])) $call['file'] = "[PHP]"; if(empty($call['line'])) $call['line'] = " "; if(!empty($call['class'])) $call['function'] = $call['class'].$call['type'].$call['function']; $call['file'] = str_replace(MYBB_ROOT, "/", $call['file']); $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n"; $backtrace .= "\n"; } $backtrace .= "
FileLineFunction
{$call['file']}{$call['line']}{$call['function']}
\n"; } return $backtrace; } } ?>