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(substr($this->getTitle(), 0, 100));
258 * returns title for error
262 public function getTitle()
264 return $this->getType() . ': ' . $this->getMessage();
272 public function getBacktraceDisplay()
274 return PMA_Error
::formatBacktrace(
275 $this->getBacktrace(),
282 * return formatted backtrace field
284 * @param array $backtrace Backtrace data
285 * @param string $separator Arguments separator to use
286 * @param string $lines Lines separator to use
288 * @return string formatted backtrace
291 static function formatBacktrace($backtrace, $separator, $lines)
295 foreach ($backtrace as $step) {
296 if (isset($step['file']) && isset($step['line'])) {
297 $retval .= PMA_Error
::relPath($step['file'])
298 . '#' . $step['line'] . ': ';
300 if (isset($step['class'])) {
301 $retval .= $step['class'] . $step['type'];
303 $retval .= PMA_Error
::getFunctionCall($step, $separator);
311 * Formats function call in a backtrace
313 * @param array $step backtrace step
314 * @param string $separator Arguments separator to use
319 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
352 static function getArg($arg, $function)
355 $include_functions = array(
361 $connect_functions = array(
365 'mysqli_real_connect',
370 if (in_array($function, $include_functions)) {
371 $retval .= PMA_Error
::relPath($arg);
372 } elseif (in_array($function, $connect_functions)
373 && getType($arg) === 'string'
375 $retval .= getType($arg) . ' ********';
376 } elseif (is_scalar($arg)) {
377 $retval .= getType($arg) . ' '
378 . htmlspecialchars(var_export($arg, true));
380 $retval .= getType($arg);
387 * Gets the error as string of HTML
391 public function getDisplay()
393 $this->isDisplayed(true);
394 $retval = '<div class="' . $this->getLevel() . '">';
395 if (! $this->isUserError()) {
396 $retval .= '<strong>' . $this->getType() . '</strong>';
397 $retval .= ' in ' . $this->getFile() . '#' . $this->getLine();
398 $retval .= "<br />\n";
400 $retval .= $this->getMessage();
401 if (! $this->isUserError()) {
402 $retval .= "<br />\n";
403 $retval .= "<br />\n";
404 $retval .= "<strong>Backtrace</strong><br />\n";
405 $retval .= "<br />\n";
406 $retval .= $this->getBacktraceDisplay();
414 * whether this error is a user error
418 public function isUserError()
420 return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE
);
424 * return short relative path to phpMyAdmin basedir
426 * prevent path disclosure in error message,
427 * and make users feel safe to submit error reports
429 * @param string $dest path to be shorten
431 * @return string shortened path
434 static function relPath($dest)
436 $dest = realpath($dest);
438 if (substr(PHP_OS
, 0, 3) == 'WIN') {
446 realpath(__DIR__
. $separator . '..')
448 $Adest = explode($separator, $dest);
451 // && count ($Adest)>0 && count($Ahere)>0 )
452 while (implode($separator, $Adest) != implode($separator, $Ahere)) {
453 if (count($Ahere) > count($Adest)) {
455 $result .= $separator . '..';
460 $path = $result . str_replace(implode($separator, $Adest), '', $dest);
462 $separator . $separator,