bug#3212720 Show error message on error.
[phpmyadmin/ayax.git] / libraries / Error.class.php
blobc499d8da0a0796b0800cb5f1d39558cc5994a9a2
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Holds class PMA_Error
6 * @package phpMyAdmin
7 */
9 /**
10 * base class
12 require_once './libraries/Message.class.php';
14 /**
15 * a single error
17 * @package phpMyAdmin
19 class PMA_Error extends PMA_Message
21 /**
22 * Error types
24 * @var array
26 static public $errortype = array (
27 E_ERROR => 'Error',
28 E_WARNING => 'Warning',
29 E_PARSE => 'Parsing Error',
30 E_NOTICE => 'Notice',
31 E_CORE_ERROR => 'Core Error',
32 E_CORE_WARNING => 'Core Warning',
33 E_COMPILE_ERROR => 'Compile Error',
34 E_COMPILE_WARNING => 'Compile Warning',
35 E_USER_ERROR => 'User Error',
36 E_USER_WARNING => 'User Warning',
37 E_USER_NOTICE => 'User Notice',
38 E_STRICT => 'Runtime Notice',
39 E_DEPRECATED => 'Deprecation Notice',
40 E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
43 /**
44 * Error levels
46 * @var array
48 static public $errorlevel = array (
49 E_ERROR => 'error',
50 E_WARNING => 'warning',
51 E_PARSE => 'error',
52 E_NOTICE => 'notice',
53 E_CORE_ERROR => 'error',
54 E_CORE_WARNING => 'warning',
55 E_COMPILE_ERROR => 'error',
56 E_COMPILE_WARNING => 'warning',
57 E_USER_ERROR => 'error',
58 E_USER_WARNING => 'warning',
59 E_USER_NOTICE => 'notice',
60 E_STRICT => 'notice',
61 E_DEPRECATED => 'notice',
62 E_RECOVERABLE_ERROR => 'error',
65 /**
66 * The file in which the error occured
68 * @var string
70 protected $_file = '';
72 /**
73 * The line in which the error occured
75 * @var integer
77 protected $_line = 0;
79 /**
80 * Holds the backtrace for this error
82 * @var array
84 protected $_backtrace = array();
86 /**
87 * Unique id
89 * @var string
91 protected $_hash = null;
93 /**
94 * Constructor
96 * @uses debug_backtrace()
97 * @uses PMA_Error::setNumber()
98 * @uses PMA_Error::setMessage()
99 * @uses PMA_Error::setFile()
100 * @uses PMA_Error::setLine()
101 * @uses PMA_Error::setBacktrace()
102 * @param integer $errno
103 * @param string $errstr
104 * @param string $errfile
105 * @param integer $errline
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 two calls: debug_backtrace() and handleError()
116 unset($backtrace[0]);
117 unset($backtrace[1]);
119 $this->setBacktrace($backtrace);
123 * sets PMA_Error::$_backtrace
125 * @uses PMA_Error::$_backtrace to set it
126 * @param array $backtrace
128 public function setBacktrace($backtrace)
130 $this->_backtrace = $backtrace;
134 * sets PMA_Error::$_line
136 * @uses PMA_Error::$_line to set it
137 * @param integer $line
139 public function setLine($line)
141 $this->_line = $line;
145 * sets PMA_Error::$_file
147 * @uses PMA_Error::$_file to set it
148 * @uses PMA_Error::relPath()
149 * @param string $file
151 public function setFile($file)
153 $this->_file = PMA_Error::relPath($file);
158 * returns unique PMA_Error::$_hash, if not exists it will be created
160 * @uses PMA_Error::$_hash as return value and to set it if required
161 * @uses PMA_Error::getNumber()
162 * @uses PMA_Error::getMessage()
163 * @uses PMA_Error::getFile()
164 * @uses PMA_Error::getLine()
165 * @uses PMA_Error::getBacktrace()
166 * @uses md5()
167 * @param string $file
168 * @return string PMA_Error::$_hash
170 public function getHash()
172 if (null === $this->_hash) {
173 $this->_hash = md5(
174 $this->getNumber() .
175 $this->getMessage() .
176 $this->getFile() .
177 $this->getLine() .
178 $this->getBacktrace()
182 return $this->_hash;
186 * returns PMA_Error::$_backtrace
188 * @uses PMA_Error::$_backtrace as return value
189 * @return array PMA_Error::$_backtrace
191 public function getBacktrace()
193 return $this->_backtrace;
197 * returns PMA_Error::$_file
199 * @uses PMA_Error::$_file as return value
200 * @return string PMA_Error::$_file
202 public function getFile()
204 return $this->_file;
208 * returns PMA_Error::$_line
210 * @uses PMA_Error::$_line as return value
211 * @return integer PMA_Error::$_line
213 public function getLine()
215 return $this->_line;
219 * returns type of error
221 * @uses PMA_Error::$errortype
222 * @uses PMA_Error::getNumber()
223 * @return string type of error
225 public function getType()
227 return PMA_Error::$errortype[$this->getNumber()];
231 * returns level of error
233 * @uses PMA_Error::$$errorlevel
234 * @uses PMA_Error::getNumber()
235 * @return string level of error
237 public function getLevel()
239 return PMA_Error::$errorlevel[$this->getNumber()];
243 * returns title prepared for HTML Title-Tag
245 * @uses PMA_Error::getTitle()
246 * @uses htmlspecialchars()
247 * @uses substr()
248 * @return string HTML escaped and truncated title
250 public function getHtmlTitle()
252 return htmlspecialchars(substr($this->getTitle(), 0, 100));
256 * returns title for error
258 * @uses PMA_Error::getType()
259 * @uses PMA_Error::getMessage()
260 * @return string
262 public function getTitle()
264 return $this->getType() . ': ' . $this->getMessage();
268 * Display HTML backtrace
270 * @uses PMA_Error::getBacktrace()
271 * @uses PMA_Error::relPath()
272 * @uses PMA_Error::displayArg()
273 * @uses count()
275 public function displayBacktrace()
277 foreach ($this->getBacktrace() as $step) {
278 echo PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
279 if (isset($step['class'])) {
280 echo $step['class'] . $step['type'];
282 echo $step['function'] . '(';
283 if (isset($step['args']) && (count($step['args']) > 1)) {
284 echo "<br />\n";
285 foreach ($step['args'] as $arg) {
286 echo "\t";
287 $this->displayArg($arg, $step['function']);
288 echo ',' . "<br />\n";
290 } elseif (isset($step['args']) && (count($step['args']) > 0)) {
291 foreach ($step['args'] as $arg) {
292 $this->displayArg($arg, $step['function']);
295 echo ')' . "<br />\n";
300 * Display a single function argument
301 * if $function is one of include/require the $arg is converted te relative path
303 * @uses PMA_Error::relPath()
304 * @uses in_array()
305 * @uses gettype()
306 * @param string $arg
307 * @param string $function
309 protected function displayArg($arg, $function)
311 $include_functions = array(
312 'include',
313 'include_once',
314 'require',
315 'require_once',
318 if (in_array($function, $include_functions)) {
319 echo PMA_Error::relPath($arg);
320 } elseif (is_scalar($arg)) {
321 echo gettype($arg) . ' ' . htmlspecialchars($arg);
322 } else {
323 echo gettype($arg);
328 * Displays the error in HTML
330 * @uses PMA_Error::getLevel()
331 * @uses PMA_Error::getType()
332 * @uses PMA_Error::getMessage()
333 * @uses PMA_Error::displayBacktrace()
334 * @uses PMA_Error::isDisplayed()
336 public function display()
338 echo '<div class="' . $this->getLevel() . '">';
339 if (! $this->isUserError()) {
340 echo '<strong>' . $this->getType() . '</strong>';
341 echo ' in ' . $this->getFile() . '#' . $this->getLine();
342 echo "<br />\n";
344 echo $this->getMessage();
345 if (! $this->isUserError()) {
346 echo "<br />\n";
347 echo "<br />\n";
348 echo "<strong>Backtrace</strong><br />\n";
349 echo "<br />\n";
350 echo $this->displayBacktrace();
352 echo '</div>';
353 $this->isDisplayed(true);
357 * whether this error is a user error
359 * @uses E_USER_WARNING
360 * @uses E_USER_ERROR
361 * @uses E_USER_NOTICE
362 * @uses PMA_Error::getNumber()
363 * @return boolean
365 public function isUserError()
367 return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
371 * return short relative path to phpMyAdmin basedir
373 * prevent path disclusore in error message,
374 * and make users feel save to submit error reports
376 * @static
377 * @uses PHP_OS()
378 * @uses __FILE__()
379 * @uses realpath()
380 * @uses substr()
381 * @uses explode()
382 * @uses dirname()
383 * @uses implode()
384 * @uses count()
385 * @uses array_pop()
386 * @uses str_replace()
387 * @param string $dest path to be shorten
388 * @return string shortened path
390 static function relPath($dest)
392 $dest = realpath($dest);
394 if (substr(PHP_OS, 0, 3) == 'WIN') {
395 $path_separator = '\\';
396 } else {
397 $path_separator = '/';
400 $Ahere = explode($path_separator, realpath(dirname(__FILE__) . $path_separator . '..'));
401 $Adest = explode($path_separator, $dest);
403 $result = '.';
404 // && count ($Adest)>0 && count($Ahere)>0 )
405 while (implode($path_separator, $Adest) != implode($path_separator, $Ahere)) {
406 if (count($Ahere) > count($Adest)) {
407 array_pop($Ahere);
408 $result .= $path_separator . '..';
409 } else {
410 array_pop($Adest);
413 $path = $result . str_replace(implode($path_separator, $Adest), '', $dest);
414 return str_replace($path_separator . $path_separator, $path_separator, $path);