PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/libraries/Error.class.php

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