Clear display on session timeout even when unsaved changes are pending.
[openemr.git] / phpmyadmin / libraries / Error.class.php
blobfddeceb8749d23b617a64f44dc44fe0cc2167c1d
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Holds class PMA_Error
6 * @package PhpMyAdmin
7 */
9 if (! defined('PHPMYADMIN')) {
10 exit;
13 /**
14 * base class
16 require_once './libraries/Message.class.php';
18 /**
19 * a single error
21 * @package PhpMyAdmin
23 class PMA_Error extends PMA_Message
25 /**
26 * Error types
28 * @var array
30 static public $errortype = array (
31 0 => 'Internal error',
32 E_ERROR => 'Error',
33 E_WARNING => 'Warning',
34 E_PARSE => 'Parsing Error',
35 E_NOTICE => 'Notice',
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',
48 /**
49 * Error levels
51 * @var array
53 static public $errorlevel = array (
54 0 => 'error',
55 E_ERROR => 'error',
56 E_WARNING => 'error',
57 E_PARSE => 'error',
58 E_NOTICE => 'notice',
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',
66 E_STRICT => 'notice',
67 E_DEPRECATED => 'notice',
68 E_RECOVERABLE_ERROR => 'error',
71 /**
72 * The file in which the error occurred
74 * @var string
76 protected $file = '';
78 /**
79 * The line in which the error occurred
81 * @var integer
83 protected $line = 0;
85 /**
86 * Holds the backtrace for this error
88 * @var array
90 protected $backtrace = array();
92 /**
93 * Unique id
95 * @var string
97 protected $hash = null;
99 /**
100 * Constructor
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
127 * @return void
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
133 * intermediate form.
135 public function setBacktrace($backtrace)
137 $this->backtrace = $backtrace;
141 * sets PMA_Error::$_line
143 * @param integer $line the line
145 * @return void
147 public function setLine($line)
149 $this->line = $line;
153 * sets PMA_Error::$_file
155 * @param string $file the file
157 * @return void
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()
172 try {
173 $backtrace = serialize($this->getBacktrace());
174 } catch(Exception $e) {
175 $backtrace = '';
177 if ($this->hash === null) {
178 $this->hash = md5(
179 $this->getNumber() .
180 $this->getMessage() .
181 $this->getFile() .
182 $this->getLine() .
183 $backtrace
187 return $this->hash;
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)
201 if ($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()
214 return $this->file;
218 * returns PMA_Error::$line
220 * @return integer PMA_Error::$line
222 public function getLine()
224 return $this->line;
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
262 * @return string
264 public function getTitle()
266 return $this->getType() . ': ' . $this->getMessage();
270 * Get HTML backtrace
272 * @return string
274 public function getBacktraceDisplay()
276 return PMA_Error::formatBacktrace(
277 $this->getBacktrace(),
278 "<br />\n",
279 "<br />\n"
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)
294 $retval = '';
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);
305 $retval .= $lines;
308 return $retval;
312 * Formats function call in a backtrace
314 * @param array $step backtrace step
315 * @param string $separator Arguments separator to use
317 * @return string
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) {
326 $retval .= "\t";
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']);
336 $retval .= ')';
337 return $retval;
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
349 * @return string
351 public static function getArg($arg, $function)
353 $retval = '';
354 $include_functions = array(
355 'include',
356 'include_once',
357 'require',
358 'require_once',
360 $connect_functions = array(
361 'mysql_connect',
362 'mysql_pconnect',
363 'mysqli_connect',
364 'mysqli_real_connect',
365 'connect',
366 '_realConnect'
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));
378 } else {
379 $retval .= getType($arg);
382 return $retval;
386 * Gets the error as string of HTML
388 * @return string
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();
407 $retval .= '</div>';
409 return $retval;
413 * whether this error is a user error
415 * @return boolean
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') {
437 $separator = '\\';
438 } else {
439 $separator = '/';
442 $Ahere = explode(
443 $separator,
444 realpath(__DIR__ . $separator . '..')
446 $Adest = explode($separator, $dest);
448 $result = '.';
449 // && count ($Adest)>0 && count($Ahere)>0 )
450 while (implode($separator, $Adest) != implode($separator, $Ahere)) {
451 if (count($Ahere) > count($Adest)) {
452 array_pop($Ahere);
453 $result .= $separator . '..';
454 } else {
455 array_pop($Adest);
458 $path = $result . str_replace(implode($separator, $Adest), '', $dest);
459 return str_replace(
460 $separator . $separator,
461 $separator,
462 $path