PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/system/classes/error.php

https://github.com/HabariMag/habarimag-old
PHP | 262 lines | 173 code | 30 blank | 59 comment | 27 complexity | ef633b4685b07c7e0324c1da6a8e045a MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. /**
  3. * @package Habari
  4. *
  5. */
  6. /**
  7. * Contains error-related functions and Habari's error handler.
  8. *
  9. **/
  10. class Error extends Exception
  11. {
  12. protected $message = '';
  13. protected $is_error = false;
  14. /**
  15. * Constructor for the Error class
  16. *
  17. * @param string $message Exception to display
  18. * @param integer $code Code of the exception
  19. * @param boolean $is_error true if the exception represents an error handled by the Error class
  20. */
  21. public function __construct( $message = 'Generic Habari Error', $code = 0, $is_error = false )
  22. {
  23. parent::__construct( $message, $code );
  24. $this->is_error = $is_error;
  25. }
  26. /**
  27. * function handle_errors
  28. *
  29. * Configures the Error class to handle all errors.
  30. */
  31. public static function handle_errors()
  32. {
  33. set_error_handler( array( 'Error', 'error_handler' ) );
  34. set_exception_handler( array( 'Error', 'exception_handler' ) );
  35. }
  36. /**
  37. * Used to handle all uncaught exceptions.
  38. */
  39. public static function exception_handler( $exception )
  40. {
  41. if ( isset( $exception->is_error ) && $exception->is_error ) {
  42. return;
  43. }
  44. printf(
  45. "<pre class=\"error\">\n<b>%s:</b> %s in %s line %s\n</pre>",
  46. get_class( $exception ),
  47. $exception->getMessage(),
  48. $exception->file,
  49. $exception->line
  50. );
  51. if ( DEBUG ) {
  52. self::print_backtrace( $exception->getTrace() );
  53. }
  54. if ( Options::get( 'log_backtraces' ) || DEBUG ) {
  55. $backtrace = print_r( $exception->getTrace(), true );
  56. }
  57. else {
  58. $backtrace = null;
  59. }
  60. EventLog::log( $exception->getMessage() . ' in ' . $exception->file . ':' . $exception->line, 'err', 'default', null, $backtrace );
  61. }
  62. /**
  63. * Get the error text, file, and line number from the backtrace, which is more accurate
  64. *
  65. * @return string The contructed error string
  66. */
  67. public function humane_error()
  68. {
  69. $trace = $this->getTrace();
  70. $trace1 = reset( $trace );
  71. $file = isset( $trace1['file'] ) ? $trace1['file'] : $this->getFile();
  72. $line = isset( $trace1['line'] ) ? $trace1['line'] : $this->getLine();
  73. return sprintf( _t( '%1$s in %2$s line %3$s on request of "%4$s"' ), $this->getMessage(), $file, $line, $_SERVER['REQUEST_URI'] );
  74. }
  75. /**
  76. * Used to handle all PHP errors after Error::handle_errors() is called.
  77. */
  78. public static function error_handler( $errno, $errstr, $errfile, $errline, $errcontext )
  79. {
  80. if ( ( $errno & error_reporting() ) === 0 ) {
  81. return;
  82. }
  83. if ( !function_exists( '_t' ) ) {
  84. function _t( $v )
  85. {
  86. return $v;
  87. }
  88. }
  89. // Don't be fooled, we can't actually handle most of these.
  90. $error_names = array(
  91. E_ERROR => _t( 'Error' ),
  92. E_WARNING => _t( 'Warning' ),
  93. E_PARSE => _t( 'Parse Error' ),
  94. E_NOTICE => _t( 'Notice' ),
  95. E_CORE_ERROR => _t( 'Core Error' ),
  96. E_CORE_WARNING => _t( 'Core Warning' ),
  97. E_COMPILE_ERROR => _t( 'Compile Error' ),
  98. E_COMPILE_WARNING => _t( 'Compile Warning' ),
  99. E_USER_ERROR => _t( 'User Error' ),
  100. E_USER_WARNING => _t( 'User Warning' ),
  101. E_USER_NOTICE => _t( 'User Notice' ),
  102. E_STRICT => _t( 'Strict Notice' ),
  103. E_RECOVERABLE_ERROR => _t( 'Recoverable Error' ),
  104. );
  105. if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) {
  106. $error_names[E_DEPRECATED] = _t( 'Deprecated violation' );
  107. $error_names[E_USER_DEPRECATED] = _t( 'User deprecated violation' );
  108. }
  109. if ( strpos( $errfile, HABARI_PATH ) === 0 ) {
  110. $errfile = substr( $errfile, strlen( HABARI_PATH ) + 1 );
  111. }
  112. if ( ini_get( 'display_errors' ) || DEBUG ) {
  113. printf(
  114. "<pre class=\"error\">\n<b>%s:</b> %s in %s line %s\n</pre>",
  115. $error_names[$errno],
  116. $errstr,
  117. $errfile,
  118. $errline
  119. );
  120. if ( DEBUG ) {
  121. Error::print_backtrace();
  122. }
  123. if ( Options::get( 'log_backtraces' ) || DEBUG ) {
  124. $backtrace = print_r( debug_backtrace(), true );
  125. }
  126. else {
  127. $backtrace = null;
  128. }
  129. }
  130. if ( !isset( $backtrace ) ) {
  131. $backtrace= null;
  132. }
  133. EventLog::log( $errstr . ' in ' . $errfile . ':' . $errline, 'err', 'default', null, $backtrace );
  134. // throwing an Error make every error fatal!
  135. //throw new Error($errstr, 0, true);
  136. }
  137. /**
  138. * Print a backtrace in a format that looks reasonable in both rendered HTML and text
  139. *
  140. * @param array $trace An optional array of trace data
  141. */
  142. private static function print_backtrace( $trace = null )
  143. {
  144. if ( !isset( $trace ) ) {
  145. $trace = debug_backtrace();
  146. }
  147. print "<pre class=\"backtrace\">\n";
  148. $defaults = array(
  149. 'file' => '[core]',
  150. 'line' => '(eval)',
  151. 'class' => '',
  152. 'type' => '',
  153. 'args' => array(),
  154. );
  155. foreach ( $trace as $n => $a ) {
  156. $a = array_merge( $defaults, $a );
  157. if ( $a['class'] == 'Error' ) {
  158. continue;
  159. }
  160. if ( strpos( $a['file'], HABARI_PATH ) === 0 ) {
  161. $a['file'] = substr( $a['file'], strlen( HABARI_PATH ) + 1 );
  162. }
  163. if ( defined( 'DEBUG_ARGS' ) ) {
  164. $args = array();
  165. foreach ( $a['args'] as $arg ) {
  166. $args[] = htmlentities( str_replace(
  167. array( "\n", "\r" ),
  168. array( "\n ", '' ),
  169. var_export( $arg, true )
  170. ) );
  171. }
  172. $args = implode( ", ", $args );
  173. if ( strlen( $args ) > 1024 ) {
  174. $args = substr( $args, 0, 1021 ) . '&hellip;';
  175. }
  176. }
  177. else {
  178. $args = count( $a['args'] ) == 0 ? ' ' : sprintf( _n( ' &hellip;%d arg&hellip; ', ' &hellip;%d args&hellip; ', count( $a['args'] ) ), $a['args'] );
  179. }
  180. printf(
  181. _t( "%s line %d:\n %s(%s)\n" ),
  182. $a['file'],
  183. $a['line'],
  184. $a['class'].$a['type'].$a['function'],
  185. $args
  186. );
  187. }
  188. print "\n</pre>\n";
  189. }
  190. /**
  191. * function out
  192. *
  193. * Outputs the error message in plain text
  194. */
  195. public function out()
  196. {
  197. if ( is_scalar( $this->message ) ) {
  198. echo $this->message . "\n";
  199. }
  200. else {
  201. echo var_export( $this->message, true ) . "\n";
  202. }
  203. }
  204. /**
  205. * function get
  206. *
  207. * Returns the error message in plain text
  208. */
  209. public function get()
  210. {
  211. return $this->message;
  212. }
  213. /**
  214. * function raise
  215. *
  216. * Convenience method to create and return a new Error object
  217. */
  218. public static function raise( $error_message, $severity = E_USER_ERROR )
  219. {
  220. return new Error( $error_message, $severity );
  221. }
  222. /**
  223. * function is_error
  224. *
  225. * Returns true if the argument is an Error instance
  226. */
  227. public static function is_error( $obj )
  228. {
  229. return ($obj instanceof Error);
  230. }
  231. }
  232. ?>