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