Refactored ConfigFile class so that it is no longer a singleton
[phpmyadmin.git] / libraries / Error.class.php
blob5dfc3b9e4040efb87b6c6678fb4b413a7401f7c8
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 E_ERROR => 'Error',
32 E_WARNING => 'Warning',
33 E_PARSE => 'Parsing Error',
34 E_NOTICE => 'Notice',
35 E_CORE_ERROR => 'Core Error',
36 E_CORE_WARNING => 'Core Warning',
37 E_COMPILE_ERROR => 'Compile Error',
38 E_COMPILE_WARNING => 'Compile Warning',
39 E_USER_ERROR => 'User Error',
40 E_USER_WARNING => 'User Warning',
41 E_USER_NOTICE => 'User Notice',
42 E_STRICT => 'Runtime Notice',
43 E_DEPRECATED => 'Deprecation Notice',
44 E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
47 /**
48 * Error levels
50 * @var array
52 static public $errorlevel = array (
53 E_ERROR => 'error',
54 E_WARNING => 'error',
55 E_PARSE => 'error',
56 E_NOTICE => 'notice',
57 E_CORE_ERROR => 'error',
58 E_CORE_WARNING => 'error',
59 E_COMPILE_ERROR => 'error',
60 E_COMPILE_WARNING => 'error',
61 E_USER_ERROR => 'error',
62 E_USER_WARNING => 'error',
63 E_USER_NOTICE => 'notice',
64 E_STRICT => 'notice',
65 E_DEPRECATED => 'notice',
66 E_RECOVERABLE_ERROR => 'error',
69 /**
70 * The file in which the error occurred
72 * @var string
74 protected $file = '';
76 /**
77 * The line in which the error occurred
79 * @var integer
81 protected $line = 0;
83 /**
84 * Holds the backtrace for this error
86 * @var array
88 protected $backtrace = array();
90 /**
91 * Unique id
93 * @var string
95 protected $hash = null;
97 /**
98 * Constructor
100 * @param integer $errno error number
101 * @param string $errstr error message
102 * @param string $errfile file
103 * @param integer $errline line
105 public function __construct($errno, $errstr, $errfile, $errline)
107 $this->setNumber($errno);
108 $this->setMessage($errstr, false);
109 $this->setFile($errfile);
110 $this->setLine($errline);
112 $backtrace = debug_backtrace();
113 // remove last three calls:
114 // debug_backtrace(), handleError() and addError()
115 $backtrace = array_slice($backtrace, 3);
117 $this->setBacktrace($backtrace);
121 * sets PMA_Error::$_backtrace
123 * @param array $backtrace backtrace
125 * @return void
127 public function setBacktrace($backtrace)
129 $this->backtrace = $backtrace;
133 * sets PMA_Error::$_line
135 * @param integer $line the line
137 * @return void
139 public function setLine($line)
141 $this->line = $line;
145 * sets PMA_Error::$_file
147 * @param string $file the file
149 * @return void
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 * @return string PMA_Error::$hash
162 public function getHash()
164 try {
165 $backtrace = serialize($this->getBacktrace());
166 } catch(Exception $e) {
167 $backtrace = '';
169 if ($this->hash === null) {
170 $this->hash = md5(
171 $this->getNumber() .
172 $this->getMessage() .
173 $this->getFile() .
174 $this->getLine() .
175 $backtrace
179 return $this->hash;
183 * returns PMA_Error::$_backtrace
185 * @return array PMA_Error::$_backtrace
187 public function getBacktrace()
189 return $this->backtrace;
193 * returns PMA_Error::$file
195 * @return string PMA_Error::$file
197 public function getFile()
199 return $this->file;
203 * returns PMA_Error::$line
205 * @return integer PMA_Error::$line
207 public function getLine()
209 return $this->line;
213 * returns type of error
215 * @return string type of error
217 public function getType()
219 return PMA_Error::$errortype[$this->getNumber()];
223 * returns level of error
225 * @return string level of error
227 public function getLevel()
229 return PMA_Error::$errorlevel[$this->getNumber()];
233 * returns title prepared for HTML Title-Tag
235 * @return string HTML escaped and truncated title
237 public function getHtmlTitle()
239 return htmlspecialchars(substr($this->getTitle(), 0, 100));
243 * returns title for error
245 * @return string
247 public function getTitle()
249 return $this->getType() . ': ' . $this->getMessage();
253 * Get HTML backtrace
255 * @return string
257 public function getBacktraceDisplay()
259 $retval = '';
261 foreach ($this->getBacktrace() as $step) {
262 if (isset($step['file']) && isset($step['line'])) {
263 $retval .= PMA_Error::relPath($step['file'])
264 . '#' . $step['line'] . ': ';
266 if (isset($step['class'])) {
267 $retval .= $step['class'] . $step['type'];
269 $retval .= $step['function'] . '(';
270 if (isset($step['args']) && (count($step['args']) > 1)) {
271 $retval .= "<br />\n";
272 foreach ($step['args'] as $arg) {
273 $retval .= "\t";
274 $retval .= $this->getArg($arg, $step['function']);
275 $retval .= ',' . "<br />\n";
277 } elseif (isset($step['args']) && (count($step['args']) > 0)) {
278 foreach ($step['args'] as $arg) {
279 $retval .= $this->getArg($arg, $step['function']);
282 $retval .= ')' . "<br />\n";
285 return $retval;
289 * Get a single function argument
291 * if $function is one of include/require
292 * the $arg is converted to a relative path
294 * @param string $arg argument to process
295 * @param string $function function name
297 * @return string
299 protected function getArg($arg, $function)
301 $retval = '';
302 $include_functions = array(
303 'include',
304 'include_once',
305 'require',
306 'require_once',
308 $connect_functions = array(
309 'mysql_connect',
310 'mysql_pconnect',
311 'mysqli_connect',
312 'mysqli_real_connect',
313 'connect',
316 if (in_array($function, $include_functions)) {
317 $retval .= PMA_Error::relPath($arg);
318 } elseif (in_array($function, $connect_functions)
319 && getType($arg) === 'string'
321 $retval .= getType($arg) . ' ********';
322 } elseif (is_scalar($arg)) {
323 $retval .= getType($arg) . ' '
324 . htmlspecialchars(var_export($arg, true));
325 } else {
326 $retval .= getType($arg);
329 return $retval;
333 * Gets the error as string of HTML
335 * @return string
337 public function getDisplay()
339 $this->isDisplayed(true);
340 $retval = '<div class="' . $this->getLevel() . '">';
341 if (! $this->isUserError()) {
342 $retval .= '<strong>' . $this->getType() . '</strong>';
343 $retval .= ' in ' . $this->getFile() . '#' . $this->getLine();
344 $retval .= "<br />\n";
346 $retval .= $this->getMessage();
347 if (! $this->isUserError()) {
348 $retval .= "<br />\n";
349 $retval .= "<br />\n";
350 $retval .= "<strong>Backtrace</strong><br />\n";
351 $retval .= "<br />\n";
352 $retval .= $this->getBacktraceDisplay();
354 $retval .= '</div>';
356 return $retval;
360 * whether this error is a user error
362 * @return boolean
364 public function isUserError()
366 return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
370 * return short relative path to phpMyAdmin basedir
372 * prevent path disclosure in error message,
373 * and make users feel safe to submit error reports
375 * @param string $dest path to be shorten
377 * @return string shortened path
378 * @static
380 static function relPath($dest)
382 $dest = realpath($dest);
384 if (substr(PHP_OS, 0, 3) == 'WIN') {
385 $separator = '\\';
386 } else {
387 $separator = '/';
390 $Ahere = explode(
391 $separator,
392 realpath(__DIR__ . $separator . '..')
394 $Adest = explode($separator, $dest);
396 $result = '.';
397 // && count ($Adest)>0 && count($Ahere)>0 )
398 while (implode($separator, $Adest) != implode($separator, $Ahere)) {
399 if (count($Ahere) > count($Adest)) {
400 array_pop($Ahere);
401 $result .= $separator . '..';
402 } else {
403 array_pop($Adest);
406 $path = $result . str_replace(implode($separator, $Adest), '', $dest);
407 return str_replace(
408 $separator . $separator,
409 $separator,
410 $path