PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/site/libraries/joomla/error/error.php

https://bitbucket.org/manchas/pperezm
PHP | 573 lines | 239 code | 49 blank | 285 comment | 38 complexity | ea5fb3995690d397e220868697105db6 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * @version $Id: error.php 10871 2008-08-30 07:30:33Z willebil $
  4. * @package Joomla.Framework
  5. * @subpackage Error
  6. * @copyright Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
  7. * @license GNU/GPL, see LICENSE.php
  8. * Joomla! is free software. This version may have been modified pursuant
  9. * to the GNU General Public License, and as distributed it includes or
  10. * is derivative of works licensed under the GNU General Public License or
  11. * other free or open source software licenses.
  12. * See COPYRIGHT.php for copyright notices and details.
  13. */
  14. // Check to ensure this file is within the rest of the framework
  15. defined('JPATH_BASE') or die();
  16. // Error Definition: Illegal Options
  17. define( 'JERROR_ILLEGAL_OPTIONS', 1 );
  18. // Error Definition: Callback does not exist
  19. define( 'JERROR_CALLBACK_NOT_CALLABLE', 2 );
  20. // Error Definition: Illegal Handler
  21. define( 'JERROR_ILLEGAL_MODE', 3 );
  22. /*
  23. * JError exception stack
  24. */
  25. $GLOBALS['_JERROR_STACK'] = array();
  26. /*
  27. * Default available error levels
  28. */
  29. $GLOBALS['_JERROR_LEVELS'] = array(
  30. E_NOTICE => 'Notice',
  31. E_WARNING => 'Warning',
  32. E_ERROR => 'Error'
  33. );
  34. /*
  35. * Default error handlers
  36. */
  37. $GLOBALS['_JERROR_HANDLERS'] = array(
  38. E_NOTICE => array( 'mode' => 'message' ),
  39. E_WARNING => array( 'mode' => 'message' ),
  40. E_ERROR => array( 'mode' => 'callback', 'options' => array('JError','customErrorPage') )
  41. );
  42. /**
  43. * Error Handling Class
  44. *
  45. * This class is inspired in design and concept by patErrorManager <http://www.php-tools.net>
  46. *
  47. * patErrorManager contributors include:
  48. * - gERD Schaufelberger <gerd@php-tools.net>
  49. * - Sebastian Mordziol <argh@php-tools.net>
  50. * - Stephan Schmidt <scst@php-tools.net>
  51. *
  52. * @static
  53. * @package Joomla.Framework
  54. * @subpackage Error
  55. * @since 1.5
  56. */
  57. class JError
  58. {
  59. /**
  60. * Method to determine if a value is an exception object. This check supports both JException and PHP5 Exception objects
  61. *
  62. * @static
  63. * @access public
  64. * @param mixed &$object Object to check
  65. * @return boolean True if argument is an exception, false otherwise.
  66. * @since 1.5
  67. */
  68. function isError(& $object)
  69. {
  70. if (!is_object($object)) {
  71. return false;
  72. }
  73. // supports PHP 5 exception handling
  74. return is_a($object, 'JException') || is_a($object, 'JError') || is_a($object, 'Exception');
  75. }
  76. /**
  77. * Method for retrieving the last exception object in the error stack
  78. *
  79. * @static
  80. * @access public
  81. * @return mixed Last exception object in the error stack or boolean false if none exist
  82. * @since 1.5
  83. */
  84. function & getError($unset = false)
  85. {
  86. if (!isset($GLOBALS['_JERROR_STACK'][0])) {
  87. $false = false;
  88. return $false;
  89. }
  90. if ($unset) {
  91. $error = array_shift($GLOBALS['_JERROR_STACK']);
  92. } else {
  93. $error = &$GLOBALS['_JERROR_STACK'][0];
  94. }
  95. return $error;
  96. }
  97. /**
  98. * Method for retrieving the exception stack
  99. *
  100. * @static
  101. * @access public
  102. * @return array Chronological array of errors that have been stored during script execution
  103. * @since 1.5
  104. */
  105. function & getErrors()
  106. {
  107. return $GLOBALS['_JERROR_STACK'];
  108. }
  109. /**
  110. * Create a new JException object given the passed arguments
  111. *
  112. * @static
  113. * @param int $level The error level - use any of PHP's own error levels for this: E_ERROR, E_WARNING, E_NOTICE, E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE.
  114. * @param string $code The application-internal error code for this error
  115. * @param string $msg The error message, which may also be shown the user if need be.
  116. * @param mixed $info Optional: Additional error information (usually only developer-relevant information that the user should never see, like a database DSN).
  117. * @return mixed The JException object
  118. * @since 1.5
  119. *
  120. * @see JException
  121. */
  122. function & raise($level, $code, $msg, $info = null, $backtrace = false)
  123. {
  124. jimport('joomla.error.exception');
  125. // build error object
  126. $exception = new JException($msg, $code, $level, $info, $backtrace);
  127. // see what to do with this kind of error
  128. $handler = JError::getErrorHandling($level);
  129. $function = 'handle'.ucfirst($handler['mode']);
  130. if (is_callable(array('JError', $function))) {
  131. $reference =& JError::$function ($exception, (isset($handler['options'])) ? $handler['options'] : array());
  132. } else {
  133. // This is required to prevent a very unhelpful white-screen-of-death
  134. jexit(
  135. 'JError::raise -> Static method JError::' . $function . ' does not exist.' .
  136. ' Contact a developer to debug' .
  137. '<br /><strong>Error was</strong> ' .
  138. '<br />' . $exception->getMessage()
  139. );
  140. }
  141. //store and return the error
  142. $GLOBALS['_JERROR_STACK'][] =& $reference;
  143. return $reference;
  144. }
  145. /**
  146. * Wrapper method for the {@link raise()} method with predefined error level of E_ERROR and backtrace set to true.
  147. *
  148. * @static
  149. * @param string $code The application-internal error code for this error
  150. * @param string $msg The error message, which may also be shown the user if need be.
  151. * @param mixed $info Optional: Additional error information (usually only developer-relevant information that the user should never see, like a database DSN).
  152. * @return object $error The configured JError object
  153. * @since 1.5
  154. */
  155. function & raiseError($code, $msg, $info = null)
  156. {
  157. $reference = & JError::raise(E_ERROR, $code, $msg, $info, true);
  158. return $reference;
  159. }
  160. /**
  161. * Wrapper method for the {@link raise()} method with predefined error level of E_WARNING and backtrace set to false.
  162. *
  163. * @static
  164. * @param string $code The application-internal error code for this error
  165. * @param string $msg The error message, which may also be shown the user if need be.
  166. * @param mixed $info Optional: Additional error information (usually only developer-relevant information that the user should never see, like a database DSN).
  167. * @return object $error The configured JError object
  168. * @since 1.5
  169. */
  170. function & raiseWarning($code, $msg, $info = null)
  171. {
  172. $reference = & JError::raise(E_WARNING, $code, $msg, $info);
  173. return $reference;
  174. }
  175. /**
  176. * Wrapper method for the {@link raise()} method with predefined error level of E_NOTICE and backtrace set to false.
  177. *
  178. * @static
  179. * @param string $code The application-internal error code for this error
  180. * @param string $msg The error message, which may also be shown the user if need be.
  181. * @param mixed $info Optional: Additional error information (usually only developer-relevant information that the user should never see, like a database DSN).
  182. * @return object $error The configured JError object
  183. * @since 1.5
  184. */
  185. function & raiseNotice($code, $msg, $info = null)
  186. {
  187. $reference = & JError::raise(E_NOTICE, $code, $msg, $info);
  188. return $reference;
  189. }
  190. /**
  191. * Method to get the current error handler settings for a specified error level.
  192. *
  193. * @static
  194. * @param int $level The error level to retrieve. This can be any of PHP's own error levels, e.g. E_ALL, E_NOTICE...
  195. * @return array All error handling details
  196. * @since 1.5
  197. */
  198. function getErrorHandling( $level )
  199. {
  200. return $GLOBALS['_JERROR_HANDLERS'][$level];
  201. }
  202. /**
  203. * Method to set the way the JError will handle different error levels. Use this if you want to override the default settings.
  204. *
  205. * Error handling modes:
  206. * - ignore
  207. * - echo
  208. * - verbose
  209. * - die
  210. * - message
  211. * - log
  212. * - callback
  213. *
  214. * You may also set the error handling for several modes at once using PHP's bit operations.
  215. * Examples:
  216. * - E_ALL = Set the handling for all levels
  217. * - E_ERROR | E_WARNING = Set the handling for errors and warnings
  218. * - E_ALL ^ E_ERROR = Set the handling for all levels except errors
  219. *
  220. * @static
  221. * @param int $level The error level for which to set the error handling
  222. * @param string $mode The mode to use for the error handling.
  223. * @param mixed $options Optional: Any options needed for the given mode.
  224. * @return mixed True on success, or a JException object if failed.
  225. * @since 1.5
  226. */
  227. function setErrorHandling($level, $mode, $options = null)
  228. {
  229. $levels = $GLOBALS['_JERROR_LEVELS'];
  230. $function = 'handle'.ucfirst($mode);
  231. if (!is_callable(array ('JError',$function))) {
  232. return JError::raiseError(E_ERROR, 'JError:'.JERROR_ILLEGAL_MODE, 'Error Handling mode is not known', 'Mode: '.$mode.' is not implemented.');
  233. }
  234. foreach ($levels as $eLevel => $eTitle) {
  235. if (($level & $eLevel) != $eLevel) {
  236. continue;
  237. }
  238. // set callback options
  239. if ($mode == 'callback') {
  240. if (!is_array($options)) {
  241. return JError::raiseError(E_ERROR, 'JError:'.JERROR_ILLEGAL_OPTIONS, 'Options for callback not valid');
  242. }
  243. if (!is_callable($options)) {
  244. $tmp = array ('GLOBAL');
  245. if (is_array($options)) {
  246. $tmp[0] = $options[0];
  247. $tmp[1] = $options[1];
  248. } else {
  249. $tmp[1] = $options;
  250. }
  251. return JError::raiseError(E_ERROR, 'JError:'.JERROR_CALLBACK_NOT_CALLABLE, 'Function is not callable', 'Function:'.$tmp[1].' scope '.$tmp[0].'.');
  252. }
  253. }
  254. // save settings
  255. $GLOBALS['_JERROR_HANDLERS'][$eLevel] = array ('mode' => $mode);
  256. if ($options != null) {
  257. $GLOBALS['_JERROR_HANDLERS'][$eLevel]['options'] = $options;
  258. }
  259. }
  260. return true;
  261. }
  262. /**
  263. * Method that attaches the error handler to JError
  264. *
  265. * @access public
  266. * @see set_error_handler
  267. */
  268. function attachHandler()
  269. {
  270. set_error_handler(array('JError', 'customErrorHandler'));
  271. }
  272. /**
  273. * Method that dettaches the error handler from JError
  274. *
  275. * @access public
  276. * @see restore_error_handler
  277. */
  278. function detachHandler()
  279. {
  280. restore_error_handler();
  281. }
  282. /**
  283. * Method to register a new error level for handling errors
  284. *
  285. * This allows you to add custom error levels to the built-in
  286. * - E_NOTICE
  287. * - E_WARNING
  288. * - E_NOTICE
  289. *
  290. * @static
  291. * @param int $level Error level to register
  292. * @param string $name Human readable name for the error level
  293. * @param string $handler Error handler to set for the new error level [optional]
  294. * @return boolean True on success; false if the level already has been registered
  295. * @since 1.5
  296. */
  297. function registerErrorLevel( $level, $name, $handler = 'ignore' )
  298. {
  299. if( isset($GLOBALS['_JERROR_LEVELS'][$level]) ) {
  300. return false;
  301. }
  302. $GLOBALS['_JERROR_LEVELS'][$level] = $name;
  303. JError::setErrorHandling($level, $handler);
  304. return true;
  305. }
  306. /**
  307. * Translate an error level integer to a human readable string
  308. * e.g. E_ERROR will be translated to 'Error'
  309. *
  310. * @static
  311. * @param int $level Error level to translate
  312. * @return mixed Human readable error level name or boolean false if it doesn't exist
  313. * @since 1.5
  314. */
  315. function translateErrorLevel( $level )
  316. {
  317. if( isset($GLOBALS['_JERROR_LEVELS'][$level]) ) {
  318. return $GLOBALS['_JERROR_LEVELS'][$level];
  319. }
  320. return false;
  321. }
  322. /**
  323. * Ignore error handler
  324. * - Ignores the error
  325. *
  326. * @static
  327. * @param object $error Exception object to handle
  328. * @param array $options Handler options
  329. * @return object The exception object
  330. * @since 1.5
  331. *
  332. * @see raise()
  333. */
  334. function & handleIgnore(&$error, $options)
  335. {
  336. return $error;
  337. }
  338. /**
  339. * Echo error handler
  340. * - Echos the error message to output
  341. *
  342. * @static
  343. * @param object $error Exception object to handle
  344. * @param array $options Handler options
  345. * @return object The exception object
  346. * @since 1.5
  347. *
  348. * @see raise()
  349. */
  350. function & handleEcho(&$error, $options)
  351. {
  352. $level_human = JError::translateErrorLevel($error->get('level'));
  353. if (isset ($_SERVER['HTTP_HOST'])) {
  354. // output as html
  355. echo "<br /><b>jos-$level_human</b>: ".$error->get('message')."<br />\n";
  356. } else {
  357. // output as simple text
  358. if (defined('STDERR')) {
  359. fwrite(STDERR, "J$level_human: ".$error->get('message')."\n");
  360. } else {
  361. echo "J$level_human: ".$error->get('message')."\n";
  362. }
  363. }
  364. return $error;
  365. }
  366. /**
  367. * Verbose error handler
  368. * - Echos the error message to output as well as related info
  369. *
  370. * @static
  371. * @param object $error Exception object to handle
  372. * @param array $options Handler options
  373. * @return object The exception object
  374. * @since 1.5
  375. *
  376. * @see raise()
  377. */
  378. function & handleVerbose(& $error, $options)
  379. {
  380. $level_human = JError::translateErrorLevel($error->get('level'));
  381. $info = $error->get('info');
  382. if (isset ($_SERVER['HTTP_HOST'])) {
  383. // output as html
  384. echo "<br /><b>J$level_human</b>: ".$error->get('message')."<br />\n";
  385. if ($info != null) {
  386. echo "&nbsp;&nbsp;&nbsp;".$info."<br />\n";
  387. }
  388. echo $error->getBacktrace(true);
  389. } else {
  390. // output as simple text
  391. echo "J$level_human: ".$error->get('message')."\n";
  392. if ($info != null) {
  393. echo "\t".$info."\n";
  394. }
  395. }
  396. return $error;
  397. }
  398. /**
  399. * Die error handler
  400. * - Echos the error message to output and then dies
  401. *
  402. * @static
  403. * @param object $error Exception object to handle
  404. * @param array $options Handler options
  405. * @return object The exception object
  406. * @since 1.5
  407. *
  408. * @see raise()
  409. */
  410. function & handleDie(& $error, $options)
  411. {
  412. $level_human = JError::translateErrorLevel($error->get('level'));
  413. if (isset ($_SERVER['HTTP_HOST'])) {
  414. // output as html
  415. jexit("<br /><b>J$level_human</b> ".$error->get('message')."<br />\n");
  416. } else {
  417. // output as simple text
  418. if (defined('STDERR')) {
  419. fwrite(STDERR, "J$level_human ".$error->get('message')."\n");
  420. } else {
  421. jexit("J$level_human ".$error->get('message')."\n");
  422. }
  423. }
  424. return $error;
  425. }
  426. /**
  427. * Message error handler
  428. * - Enqueues the error message into the system queue
  429. *
  430. * @static
  431. * @param object $error Exception object to handle
  432. * @param array $options Handler options
  433. * @return object The exception object
  434. * @since 1.5
  435. *
  436. * @see raise()
  437. */
  438. function & handleMessage(& $error, $options)
  439. {
  440. global $mainframe;
  441. $type = ($error->get('level') == E_NOTICE) ? 'notice' : 'error';
  442. $mainframe->enqueueMessage($error->get('message'), $type);
  443. return $error;
  444. }
  445. /**
  446. * Log error handler
  447. * - Logs the error message to a system log file
  448. *
  449. * @static
  450. * @param object $error Exception object to handle
  451. * @param array $options Handler options
  452. * @return object The exception object
  453. * @since 1.5
  454. *
  455. * @see raise()
  456. */
  457. function & handleLog(& $error, $options)
  458. {
  459. static $log;
  460. if ($log == null)
  461. {
  462. jimport('joomla.error.log');
  463. $fileName = date('Y-m-d').'.error.log';
  464. $options['format'] = "{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}";
  465. $log = & JLog::getInstance($fileName, $options);
  466. }
  467. $entry['level'] = $error->get('level');
  468. $entry['code'] = $error->get('code');
  469. $entry['message'] = str_replace(array ("\r","\n"), array ('','\\n'), $error->get('message'));
  470. $log->addEntry($entry);
  471. return $error;
  472. }
  473. /**
  474. * Callback error handler
  475. * - Send the error object to a callback method for error handling
  476. *
  477. * @static
  478. * @param object $error Exception object to handle
  479. * @param array $options Handler options
  480. * @return object The exception object
  481. * @since 1.5
  482. *
  483. * @see raise()
  484. */
  485. function &handleCallback( &$error, $options )
  486. {
  487. $result = call_user_func( $options, $error );
  488. return $result;
  489. }
  490. /**
  491. * Display a custom error page and exit gracefully
  492. *
  493. * @static
  494. * @param object $error Exception object
  495. * @return void
  496. * @since 1.5
  497. */
  498. function customErrorPage(& $error)
  499. {
  500. // Initialize variables
  501. jimport('joomla.document.document');
  502. $app = & JFactory::getApplication();
  503. $document = & JDocument::getInstance('error');
  504. $config = & JFactory::getConfig();
  505. // Get the current template from the application
  506. $template = $app->getTemplate();
  507. // Push the error object into the document
  508. $document->setError($error);
  509. @ob_end_clean();
  510. $document->setTitle(JText::_('Error').': '.$error->code);
  511. $data = $document->render(false, array (
  512. 'template' => $template,
  513. 'directory' => JPATH_THEMES,
  514. 'debug' => $config->getValue('config.debug')
  515. ));
  516. JResponse::setBody($data);
  517. echo JResponse::toString();
  518. $app->close(0);
  519. }
  520. function customErrorHandler($level, $msg)
  521. {
  522. JError::raise($level, '', $msg);
  523. }
  524. }