PageRenderTime 227ms CodeModel.GetById 58ms app.highlight 15ms RepoModel.GetById 139ms app.codeStats 0ms

/libraries/joomla/error/error.php

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