PageRenderTime 52ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/Error.class.php

http://github.com/phpmyadmin/phpmyadmin
PHP | 397 lines | 212 code | 34 blank | 151 comment | 13 complexity | c17059ac2223ca5cc3320ebcccd794fa MD5 | raw file
Possible License(s): GPL-2.0, MIT, LGPL-3.0
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Holds class PMA_Error
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. /**
  9. * base class
  10. */
  11. require_once './libraries/Message.class.php';
  12. /**
  13. * a single error
  14. *
  15. * @package PhpMyAdmin
  16. */
  17. class PMA_Error extends PMA_Message
  18. {
  19. /**
  20. * Error types
  21. *
  22. * @var array
  23. */
  24. static public $errortype = array (
  25. E_ERROR => 'Error',
  26. E_WARNING => 'Warning',
  27. E_PARSE => 'Parsing Error',
  28. E_NOTICE => 'Notice',
  29. E_CORE_ERROR => 'Core Error',
  30. E_CORE_WARNING => 'Core Warning',
  31. E_COMPILE_ERROR => 'Compile Error',
  32. E_COMPILE_WARNING => 'Compile Warning',
  33. E_USER_ERROR => 'User Error',
  34. E_USER_WARNING => 'User Warning',
  35. E_USER_NOTICE => 'User Notice',
  36. E_STRICT => 'Runtime Notice',
  37. E_DEPRECATED => 'Deprecation Notice',
  38. E_RECOVERABLE_ERROR => 'Catchable Fatal Error',
  39. );
  40. /**
  41. * Error levels
  42. *
  43. * @var array
  44. */
  45. static public $errorlevel = array (
  46. E_ERROR => 'error',
  47. E_WARNING => 'error',
  48. E_PARSE => 'error',
  49. E_NOTICE => 'notice',
  50. E_CORE_ERROR => 'error',
  51. E_CORE_WARNING => 'error',
  52. E_COMPILE_ERROR => 'error',
  53. E_COMPILE_WARNING => 'error',
  54. E_USER_ERROR => 'error',
  55. E_USER_WARNING => 'error',
  56. E_USER_NOTICE => 'notice',
  57. E_STRICT => 'notice',
  58. E_DEPRECATED => 'notice',
  59. E_RECOVERABLE_ERROR => 'error',
  60. );
  61. /**
  62. * The file in which the error occured
  63. *
  64. * @var string
  65. */
  66. protected $file = '';
  67. /**
  68. * The line in which the error occured
  69. *
  70. * @var integer
  71. */
  72. protected $line = 0;
  73. /**
  74. * Holds the backtrace for this error
  75. *
  76. * @var array
  77. */
  78. protected $backtrace = array();
  79. /**
  80. * Unique id
  81. *
  82. * @var string
  83. */
  84. protected $hash = null;
  85. /**
  86. * Constructor
  87. *
  88. * @param integer $errno error number
  89. * @param string $errstr error message
  90. * @param string $errfile file
  91. * @param integer $errline line
  92. */
  93. public function __construct($errno, $errstr, $errfile, $errline)
  94. {
  95. $this->setNumber($errno);
  96. $this->setMessage($errstr, false);
  97. $this->setFile($errfile);
  98. $this->setLine($errline);
  99. $backtrace = debug_backtrace();
  100. // remove last two calls: debug_backtrace() and handleError()
  101. unset($backtrace[0]);
  102. unset($backtrace[1]);
  103. $this->setBacktrace($backtrace);
  104. }
  105. /**
  106. * sets PMA_Error::$_backtrace
  107. *
  108. * @param array $backtrace backtrace
  109. *
  110. * @return void
  111. */
  112. public function setBacktrace($backtrace)
  113. {
  114. $this->backtrace = $backtrace;
  115. }
  116. /**
  117. * sets PMA_Error::$_line
  118. *
  119. * @param integer $line the line
  120. *
  121. * @return void
  122. */
  123. public function setLine($line)
  124. {
  125. $this->line = $line;
  126. }
  127. /**
  128. * sets PMA_Error::$_file
  129. *
  130. * @param string $file the file
  131. *
  132. * @return void
  133. */
  134. public function setFile($file)
  135. {
  136. $this->file = PMA_Error::relPath($file);
  137. }
  138. /**
  139. * returns unique PMA_Error::$hash, if not exists it will be created
  140. *
  141. * @return string PMA_Error::$hash
  142. */
  143. public function getHash()
  144. {
  145. try {
  146. $backtrace = serialize($this->getBacktrace());
  147. } catch(Exception $e){
  148. $backtrace = '';
  149. }
  150. if ($this->hash === null) {
  151. $this->hash = md5(
  152. $this->getNumber() .
  153. $this->getMessage() .
  154. $this->getFile() .
  155. $this->getLine() .
  156. $backtrace
  157. );
  158. }
  159. return $this->hash;
  160. }
  161. /**
  162. * returns PMA_Error::$_backtrace
  163. *
  164. * @return array PMA_Error::$_backtrace
  165. */
  166. public function getBacktrace()
  167. {
  168. return $this->backtrace;
  169. }
  170. /**
  171. * returns PMA_Error::$file
  172. *
  173. * @return string PMA_Error::$file
  174. */
  175. public function getFile()
  176. {
  177. return $this->file;
  178. }
  179. /**
  180. * returns PMA_Error::$line
  181. *
  182. * @return integer PMA_Error::$line
  183. */
  184. public function getLine()
  185. {
  186. return $this->line;
  187. }
  188. /**
  189. * returns type of error
  190. *
  191. * @return string type of error
  192. */
  193. public function getType()
  194. {
  195. return PMA_Error::$errortype[$this->getNumber()];
  196. }
  197. /**
  198. * returns level of error
  199. *
  200. * @return string level of error
  201. */
  202. public function getLevel()
  203. {
  204. return PMA_Error::$errorlevel[$this->getNumber()];
  205. }
  206. /**
  207. * returns title prepared for HTML Title-Tag
  208. *
  209. * @return string HTML escaped and truncated title
  210. */
  211. public function getHtmlTitle()
  212. {
  213. return htmlspecialchars(substr($this->getTitle(), 0, 100));
  214. }
  215. /**
  216. * returns title for error
  217. *
  218. * @return string
  219. */
  220. public function getTitle()
  221. {
  222. return $this->getType() . ': ' . $this->getMessage();
  223. }
  224. /**
  225. * Get HTML backtrace
  226. *
  227. * @return void
  228. */
  229. public function getBacktraceDisplay()
  230. {
  231. $retval = '';
  232. foreach ($this->getBacktrace() as $step) {
  233. if (isset($step['file']) && isset($step['line'])) {
  234. $retval .= PMA_Error::relPath($step['file']) . '#' . $step['line'] . ': ';
  235. }
  236. if (isset($step['class'])) {
  237. $retval .= $step['class'] . $step['type'];
  238. }
  239. $retval .= $step['function'] . '(';
  240. if (isset($step['args']) && (count($step['args']) > 1)) {
  241. $retval .= "<br />\n";
  242. foreach ($step['args'] as $arg) {
  243. $retval .= "\t";
  244. $retval .= $this->getArg($arg, $step['function']);
  245. $retval .= ',' . "<br />\n";
  246. }
  247. } elseif (isset($step['args']) && (count($step['args']) > 0)) {
  248. foreach ($step['args'] as $arg) {
  249. $retval .= $this->getArg($arg, $step['function']);
  250. }
  251. }
  252. $retval .= ')' . "<br />\n";
  253. }
  254. return $retval;
  255. }
  256. /**
  257. * Get a single function argument
  258. *
  259. * if $function is one of include/require
  260. * the $arg is converted to a relative path
  261. *
  262. * @param string $arg
  263. * @param string $function
  264. *
  265. * @return string
  266. */
  267. protected function getArg($arg, $function)
  268. {
  269. $retval = '';
  270. $include_functions = array(
  271. 'include',
  272. 'include_once',
  273. 'require',
  274. 'require_once',
  275. );
  276. if (in_array($function, $include_functions)) {
  277. $retval .= PMA_Error::relPath($arg);
  278. } elseif (is_scalar($arg)) {
  279. $retval .= getType($arg) . ' ' . htmlspecialchars($arg);
  280. } else {
  281. $retval .= getType($arg);
  282. }
  283. return $retval;
  284. }
  285. /**
  286. * Gets the error as string of HTML
  287. *
  288. * @return string
  289. */
  290. public function getDisplay()
  291. {
  292. $this->isDisplayed(true);
  293. $retval = '<div class="' . $this->getLevel() . '">';
  294. if (! $this->isUserError()) {
  295. $retval .= '<strong>' . $this->getType() . '</strong>';
  296. $retval .= ' in ' . $this->getFile() . '#' . $this->getLine();
  297. $retval .= "<br />\n";
  298. }
  299. $retval .= $this->getMessage();
  300. if (! $this->isUserError()) {
  301. $retval .= "<br />\n";
  302. $retval .= "<br />\n";
  303. $retval .= "<strong>Backtrace</strong><br />\n";
  304. $retval .= "<br />\n";
  305. $retval .= $this->getBacktraceDisplay();
  306. }
  307. $retval .= '</div>';
  308. return $retval;
  309. }
  310. /**
  311. * whether this error is a user error
  312. *
  313. * @return boolean
  314. */
  315. public function isUserError()
  316. {
  317. return $this->getNumber() & (E_USER_WARNING | E_USER_ERROR | E_USER_NOTICE);
  318. }
  319. /**
  320. * return short relative path to phpMyAdmin basedir
  321. *
  322. * prevent path disclusore in error message,
  323. * and make users feel save to submit error reports
  324. *
  325. * @param string $dest path to be shorten
  326. *
  327. * @return string shortened path
  328. * @static
  329. */
  330. static function relPath($dest)
  331. {
  332. $dest = realpath($dest);
  333. if (substr(PHP_OS, 0, 3) == 'WIN') {
  334. $path_separator = '\\';
  335. } else {
  336. $path_separator = '/';
  337. }
  338. $Ahere = explode(
  339. $path_separator,
  340. realpath(dirname(__FILE__) . $path_separator . '..')
  341. );
  342. $Adest = explode($path_separator, $dest);
  343. $result = '.';
  344. // && count ($Adest)>0 && count($Ahere)>0 )
  345. while (implode($path_separator, $Adest) != implode($path_separator, $Ahere)) {
  346. if (count($Ahere) > count($Adest)) {
  347. array_pop($Ahere);
  348. $result .= $path_separator . '..';
  349. } else {
  350. array_pop($Adest);
  351. }
  352. }
  353. $path = $result . str_replace(implode($path_separator, $Adest), '', $dest);
  354. return str_replace(
  355. $path_separator . $path_separator,
  356. $path_separator,
  357. $path
  358. );
  359. }
  360. }
  361. ?>