'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_STRICT => 'Runtime Notice',
E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
MYBB_SQL => 'MyBB SQL Error',
MYBB_TEMPLATE => 'MyBB Template Error',
MYBB_GENERAL => 'MyBB Error',
);
/**
* Array of all of the error types to ignore
*
* @var array
*/
var $ignore_types = array(
E_DEPRECATED,
E_NOTICE,
E_USER_NOTICE,
E_STRICT
);
/**
* String of all the warnings collected
*
* @var string
*/
var $warnings = "";
/**
* Is MyBB in an errornous state? (Have we received an error?)
*
* @var boolean
*/
var $has_errors = false;
/**
* Initializes the error handler
*
*/
function errorHandler()
{
// Lets set the error handler in here so we can just do $handler = new errorHandler() and be all set up.
if(version_compare(PHP_VERSION, ">=", "5"))
{
set_error_handler(array(&$this, "error"), array_diff($this->error_types, $this->ignore_types));
}
else
{
set_error_handler(array(&$this, "error"));
}
}
/**
* 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;
}
if(in_array($type, $this->ignore_types))
{
return;
}
$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');
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 Warning
else
{
if($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($type == MYBB_SQL || $type == MYBB_TEMPLATE || $type == MYBB_GENERAL)
{
$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";
$error = @my_mail($mybb->settings['adminemail'], "MyBB error on {$mybb->settings['bbname']}", $message, $mybb->settings['adminemail']);
if($error)
{
$this->output_error(MYBB_GENERAL, $error, $file, $line);
}
}
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")
{
$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")
{
$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 && $type != MYBB_GENERAL)
{
$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"))
{
@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 .= "File | \n";
$backtrace .= "Line | \n";
$backtrace .= "Function | \n";
$backtrace .= "
\n\n";
// Strip off this function from trace
array_shift($trace);
foreach($trace as $call)
{
if(!$call['file']) $call['file'] = "[PHP]";
if(!$call['line']) $call['line'] = " ";
if($call['class']) $call['function'] = $call['class'].$call['type'].$call['function'];
$call['file'] = str_replace(MYBB_ROOT, "/", $call['file']);
$backtrace .= "\n";
$backtrace .= "{$call['file']} | \n";
$backtrace .= "{$call['line']} | \n";
$backtrace .= "{$call['function']} | \n";
$backtrace .= "
\n";
}
$backtrace .= "
\n";
}
return $backtrace;
}
}
?>