2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Holds class PMA_Error
9 if (! defined('PHPMYADMIN')) {
16 require_once './libraries/Message.class.php';
23 class PMA_Error
extends PMA_Message
30 static public $errortype = array (
31 0 => 'Internal error',
33 E_WARNING
=> 'Warning',
34 E_PARSE
=> 'Parsing Error',
36 E_CORE_ERROR
=> 'Core Error',
37 E_CORE_WARNING
=> 'Core Warning',
38 E_COMPILE_ERROR
=> 'Compile Error',
39 E_COMPILE_WARNING
=> 'Compile Warning',
40 E_USER_ERROR
=> 'User Error',
41 E_USER_WARNING
=> 'User Warning',
42 E_USER_NOTICE
=> 'User Notice',
43 E_STRICT
=> 'Runtime Notice',
44 E_DEPRECATED
=> 'Deprecation Notice',
45 E_RECOVERABLE_ERROR
=> 'Catchable Fatal Error',
53 static public $errorlevel = array (
59 E_CORE_ERROR
=> 'error',
60 E_CORE_WARNING
=> 'error',
61 E_COMPILE_ERROR
=> 'error',
62 E_COMPILE_WARNING
=> 'error',
63 E_USER_ERROR
=> 'error',
64 E_USER_WARNING
=> 'error',
65 E_USER_NOTICE
=> 'notice',
67 E_DEPRECATED
=> 'notice',
68 E_RECOVERABLE_ERROR
=> 'error',
72 * The file in which the error occurred
79 * The line in which the error occurred
86 * Holds the backtrace for this error
90 protected $backtrace = array();
97 protected $hash = null;
102 * @param integer $errno error number
103 * @param string $errstr error message
104 * @param string $errfile file
105 * @param integer $errline line
107 public function __construct($errno, $errstr, $errfile, $errline)
109 $this->setNumber($errno);
110 $this->setMessage($errstr, false);
111 $this->setFile($errfile);
112 $this->setLine($errline);
114 $backtrace = debug_backtrace();
115 // remove last three calls:
116 // debug_backtrace(), handleError() and addError()
117 $backtrace = array_slice($backtrace, 3);
119 $this->setBacktrace($backtrace);
123 * sets PMA_Error::$_backtrace
125 * @param array $backtrace backtrace
129 * @todo This function should store only processed backtrace as full
130 * backtrace requires too much memory (especially with Response
131 * object included). It could probably store only printable
132 * representation as created by getBacktraceDisplay or some
135 public function setBacktrace($backtrace)
137 $this->backtrace
= $backtrace;
141 * sets PMA_Error::$_line
143 * @param integer $line the line
147 public function setLine($line)
153 * sets PMA_Error::$_file
155 * @param string $file the file
159 public function setFile($file)
161 $this->file
= PMA_Error
::relPath($file);
166 * returns unique PMA_Error::$hash, if not exists it will be created
168 * @return string PMA_Error::$hash
170 public function getHash()
173 $backtrace = serialize($this->getBacktrace());
174 } catch(Exception
$e) {
177 if ($this->hash
=== null) {
180 $this->getMessage() .
191 * returns PMA_Error::$_backtrace for first $count frames
192 * pass $count = -1 to get full backtrace.
193 * The same can be done by not passing $count at all.
195 * @param integer $count Number of stack frames.
197 * @return array PMA_Error::$_backtrace
199 public function getBacktrace($count = -1)
202 return array_slice($this->backtrace
, 0, $count);
204 return $this->backtrace
;
208 * returns PMA_Error::$file
210 * @return string PMA_Error::$file
212 public function getFile()
218 * returns PMA_Error::$line
220 * @return integer PMA_Error::$line
222 public function getLine()
228 * returns type of error
230 * @return string type of error
232 public function getType()
234 return PMA_Error
::$errortype[$this->getNumber()];
238 * returns level of error
240 * @return string level of error
242 public function getLevel()
244 return PMA_Error
::$errorlevel[$this->getNumber()];
248 * returns title prepared for HTML Title-Tag
250 * @return string HTML escaped and truncated title
252 public function getHtmlTitle()
254 return htmlspecialchars(
255 /*overload*/mb_substr($this->getTitle(), 0, 100)
260 * returns title for error
264 public function getTitle()
266 return $this->getType() . ': ' . $this->getMessage();
274 public function getBacktraceDisplay()
276 return PMA_Error
::formatBacktrace(
277 $this->getBacktrace(),
284 * return formatted backtrace field
286 * @param array $backtrace Backtrace data
287 * @param string $separator Arguments separator to use
288 * @param string $lines Lines separator to use
290 * @return string formatted backtrace
292 public static function formatBacktrace($backtrace, $separator, $lines)
296 foreach ($backtrace as $step) {
297 if (isset($step['file']) && isset($step['line'])) {
298 $retval .= PMA_Error
::relPath($step['file'])
299 . '#' . $step['line'] . ': ';
301 if (isset($step['class'])) {
302 $retval .= $step['class'] . $step['type'];
304 $retval .= PMA_Error
::getFunctionCall($step, $separator);
312 * Formats function call in a backtrace
314 * @param array $step backtrace step
315 * @param string $separator Arguments separator to use
319 public static function getFunctionCall($step, $separator)
321 $retval = $step['function'] . '(';
322 if (isset($step['args'])) {
323 if (count($step['args']) > 1) {
324 $retval .= $separator;
325 foreach ($step['args'] as $arg) {
327 $retval .= PMA_Error
::getArg($arg, $step['function']);
328 $retval .= ',' . $separator;
330 } elseif (count($step['args']) > 0) {
331 foreach ($step['args'] as $arg) {
332 $retval .= PMA_Error
::getArg($arg, $step['function']);
341 * Get a single function argument
343 * if $function is one of include/require
344 * the $arg is converted to a relative path
346 * @param string $arg argument to process
347 * @param string $function function name
351 public static function getArg($arg, $function)
354 $include_functions = array(
360 $connect_functions = array(
364 'mysqli_real_connect',
369 if (in_array($function, $include_functions)) {
370 $retval .= PMA_Error
::relPath($arg);
371 } elseif (in_array($function, $connect_functions)
372 && getType($arg) === 'string'
374 $retval .= getType($arg) . ' ********';
375 } elseif (is_scalar($arg)) {
376 $retval .= getType($arg) . ' '
377 . htmlspecialchars(var_export($arg, true));
379 $retval .= getType($arg);
386 * Gets the error as string of HTML
390 public function getDisplay()
392 $this->isDisplayed(true);
393 $retval = '<div class="' . $this->getLevel() . '">';
394 if (! $this->isUserError()) {
395 $retval .= '<strong>' . $this->getType() . '</strong>';
396 $retval .= ' in ' . $this->getFile() . '#' . $this->getLine();
397 $retval .= "<br />\n";
399 $retval .= $this->getMessage();
400 if (! $this->isUserError()) {
401 $retval .= "<br />\n";
402 $retval .= "<br />\n";
403 $retval .= "<strong>Backtrace</strong><br />\n";
404 $retval .= "<br />\n";
405 $retval .= $this->getBacktraceDisplay();
413 * whether this error is a user error
417 public function isUserError()
419 return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE
);
423 * return short relative path to phpMyAdmin basedir
425 * prevent path disclosure in error message,
426 * and make users feel safe to submit error reports
428 * @param string $dest path to be shorten
430 * @return string shortened path
432 public static function relPath($dest)
434 $dest = realpath($dest);
436 if (substr(PHP_OS
, 0, 3) == 'WIN') {
444 realpath(__DIR__
. $separator . '..')
446 $Adest = explode($separator, $dest);
449 // && count ($Adest)>0 && count($Ahere)>0 )
450 while (implode($separator, $Adest) != implode($separator, $Ahere)) {
451 if (count($Ahere) > count($Adest)) {
453 $result .= $separator . '..';
458 $path = $result . str_replace(implode($separator, $Adest), '', $dest);
460 $separator . $separator,