Update pear (#399)

This commit is contained in:
onli 2016-04-27 18:50:44 +00:00
parent 73ea0c4b1e
commit 51d88128f4
2 changed files with 241 additions and 131 deletions

View File

@ -14,17 +14,10 @@
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @copyright 1997-2010 The Authors * @copyright 1997-2010 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id$
* @link http://pear.php.net/package/PEAR * @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1 * @since File available since Release 0.1
*/ */
// Serendipity-Patch
if (defined('PEAR_ERROR_RETURN')) {
return false;
}
// Serendipity-Patch end
/**#@+ /**#@+
* ERROR constants * ERROR constants
*/ */
@ -39,8 +32,6 @@ define('PEAR_ERROR_CALLBACK', 16);
*/ */
define('PEAR_ERROR_EXCEPTION', 32); define('PEAR_ERROR_EXCEPTION', 32);
/**#@-*/ /**#@-*/
define('PEAR_ZE2', (function_exists('version_compare') &&
version_compare(zend_version(), "2-dev", "ge")));
if (substr(PHP_OS, 0, 3) == 'WIN') { if (substr(PHP_OS, 0, 3) == 'WIN') {
define('OS_WINDOWS', true); define('OS_WINDOWS', true);
@ -84,7 +75,7 @@ $GLOBALS['_PEAR_error_handler_stack'] = array();
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group * @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.5 * @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR * @link http://pear.php.net/package/PEAR
* @see PEAR_Error * @see PEAR_Error
* @since Class available since PHP 4.0.2 * @since Class available since PHP 4.0.2
@ -142,6 +133,18 @@ class PEAR
*/ */
var $_expected_errors = array(); var $_expected_errors = array();
/**
* List of methods that can be called both statically and non-statically.
* @var array
*/
protected static $bivalentMethods = array(
'setErrorHandling' => true,
'raiseError' => true,
'throwError' => true,
'pushErrorHandling' => true,
'popErrorHandling' => true,
);
/** /**
* Constructor. Registers this object in * Constructor. Registers this object in
* $_PEAR_destructor_object_list for destructor emulation if a * $_PEAR_destructor_object_list for destructor emulation if a
@ -152,7 +155,7 @@ class PEAR
* @access public * @access public
* @return void * @return void
*/ */
function PEAR($error_class = null) function __construct($error_class = null)
{ {
$classname = strtolower(get_class($this)); $classname = strtolower(get_class($this));
if ($this->_debug) { if ($this->_debug) {
@ -179,6 +182,18 @@ class PEAR
} }
} }
/**
* Only here for backwards compatibility.
* E.g. Archive_Tar calls $this->PEAR() in its constructor.
*
* @param string $error_class Which class to use for error objects,
* defaults to PEAR_Error.
*/
public function PEAR($error_class = null)
{
self::__construct($error_class);
}
/** /**
* Destructor (the emulated type of...). Does nothing right now, * Destructor (the emulated type of...). Does nothing right now,
* but is included for forward compatibility, so subclass * but is included for forward compatibility, so subclass
@ -196,19 +211,44 @@ class PEAR
} }
} }
public function __call($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array($this), $arguments)
);
}
public static function __callStatic($method, $arguments)
{
if (!isset(self::$bivalentMethods[$method])) {
trigger_error(
'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
);
}
return call_user_func_array(
array(get_class(), '_' . $method),
array_merge(array(null), $arguments)
);
}
/** /**
* If you have a class that's mostly/entirely static, and you need static * If you have a class that's mostly/entirely static, and you need static
* properties, you can use this method to simulate them. Eg. in your method(s) * properties, you can use this method to simulate them. Eg. in your method(s)
* do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
* You MUST use a reference, or they will not persist! * You MUST use a reference, or they will not persist!
* *
* @access public
* @param string $class The calling classname, to prevent clashes * @param string $class The calling classname, to prevent clashes
* @param string $var The variable to retrieve. * @param string $var The variable to retrieve.
* @return mixed A reference to the variable. If not set it will be * @return mixed A reference to the variable. If not set it will be
* auto initialised to NULL. * auto initialised to NULL.
*/ */
function &getStaticProperty($class, $var) public static function &getStaticProperty($class, $var)
{ {
static $properties; static $properties;
if (!isset($properties[$class])) { if (!isset($properties[$class])) {
@ -226,12 +266,12 @@ class PEAR
* Use this function to register a shutdown method for static * Use this function to register a shutdown method for static
* classes. * classes.
* *
* @access public
* @param mixed $func The function name (or array of class/method) to call * @param mixed $func The function name (or array of class/method) to call
* @param mixed $args The arguments to pass to the function * @param mixed $args The arguments to pass to the function
*
* @return void * @return void
*/ */
function registerShutdownFunc($func, $args = array()) public static function registerShutdownFunc($func, $args = array())
{ {
// if we are called statically, there is a potential // if we are called statically, there is a potential
// that no shutdown func is registered. Bug #6445 // that no shutdown func is registered. Bug #6445
@ -250,10 +290,10 @@ class PEAR
* only if $code is a string and * only if $code is a string and
* $obj->getMessage() == $code or * $obj->getMessage() == $code or
* $code is an integer and $obj->getCode() == $code * $code is an integer and $obj->getCode() == $code
* @access public *
* @return bool true if parameter is an error * @return bool true if parameter is an error
*/ */
static function isError($data, $code = null) public static function isError($data, $code = null)
{ {
if (!is_a($data, 'PEAR_Error')) { if (!is_a($data, 'PEAR_Error')) {
return false; return false;
@ -275,6 +315,9 @@ class PEAR
* PEAR objects. If called in an object, setErrorHandling sets * PEAR objects. If called in an object, setErrorHandling sets
* the default behaviour for that object. * the default behaviour for that object.
* *
* @param object $object
* Object the method was called on (non-static mode)
*
* @param int $mode * @param int $mode
* One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
* PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
@ -306,11 +349,12 @@ class PEAR
* *
* @since PHP 4.0.5 * @since PHP 4.0.5
*/ */
function setErrorHandling($mode = null, $options = null) protected static function _setErrorHandling(
{ $object, $mode = null, $options = null
if (isset($this) && is_a($this, 'PEAR')) { ) {
$setmode = &$this->_default_error_mode; if ($object !== null) {
$setoptions = &$this->_default_error_options; $setmode = &$object->_default_error_mode;
$setoptions = &$object->_default_error_options;
} else { } else {
$setmode = &$GLOBALS['_PEAR_default_error_mode']; $setmode = &$GLOBALS['_PEAR_default_error_mode'];
$setoptions = &$GLOBALS['_PEAR_default_error_options']; $setoptions = &$GLOBALS['_PEAR_default_error_options'];
@ -470,12 +514,12 @@ class PEAR
* @param bool $skipmsg If true, raiseError will only pass error codes, * @param bool $skipmsg If true, raiseError will only pass error codes,
* the error message parameter will be dropped. * the error message parameter will be dropped.
* *
* @access public
* @return object a PEAR error object * @return object a PEAR error object
* @see PEAR::setErrorHandling * @see PEAR::setErrorHandling
* @since PHP 4.0.5 * @since PHP 4.0.5
*/ */
static function &raiseError($message = null, protected static function _raiseError($object,
$message = null,
$code = null, $code = null,
$mode = null, $mode = null,
$options = null, $options = null,
@ -493,10 +537,10 @@ class PEAR
} }
if ( if (
isset($this) && $object !== null &&
isset($this->_expected_errors) && isset($object->_expected_errors) &&
count($this->_expected_errors) > 0 && count($object->_expected_errors) > 0 &&
count($exp = end($this->_expected_errors)) count($exp = end($object->_expected_errors))
) { ) {
if ($exp[0] == "*" || if ($exp[0] == "*" ||
(is_int(reset($exp)) && in_array($code, $exp)) || (is_int(reset($exp)) && in_array($code, $exp)) ||
@ -509,9 +553,9 @@ class PEAR
// No mode given, try global ones // No mode given, try global ones
if ($mode === null) { if ($mode === null) {
// Class error handler // Class error handler
if (isset($this) && isset($this->_default_error_mode)) { if ($object !== null && isset($object->_default_error_mode)) {
$mode = $this->_default_error_mode; $mode = $object->_default_error_mode;
$options = $this->_default_error_options; $options = $object->_default_error_options;
// Global error handler // Global error handler
} elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
$mode = $GLOBALS['_PEAR_default_error_mode']; $mode = $GLOBALS['_PEAR_default_error_mode'];
@ -521,18 +565,12 @@ class PEAR
if ($error_class !== null) { if ($error_class !== null) {
$ec = $error_class; $ec = $error_class;
} elseif (isset($this) && isset($this->_error_class)) { } elseif ($object !== null && isset($object->_error_class)) {
$ec = $this->_error_class; $ec = $object->_error_class;
} else { } else {
$ec = 'PEAR_Error'; $ec = 'PEAR_Error';
} }
if (intval(PHP_VERSION) < 5) {
// little non-eval hack to fix bug #12147
include 'PEAR/FixPHP5PEARWarnings.php';
return $a;
}
if ($skipmsg) { if ($skipmsg) {
$a = new $ec($code, $mode, $options, $userinfo); $a = new $ec($code, $mode, $options, $userinfo);
} else { } else {
@ -554,14 +592,13 @@ class PEAR
* @param string $userinfo If you need to pass along for example debug * @param string $userinfo If you need to pass along for example debug
* information, this parameter is meant for that. * information, this parameter is meant for that.
* *
* @access public
* @return object a PEAR error object * @return object a PEAR error object
* @see PEAR::raiseError * @see PEAR::raiseError
*/ */
function &throwError($message = null, $code = null, $userinfo = null) protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
{ {
if (isset($this) && is_a($this, 'PEAR')) { if ($object !== null) {
$a = &$this->raiseError($message, $code, null, null, $userinfo); $a = &$object->raiseError($message, $code, null, null, $userinfo);
return $a; return $a;
} }
@ -569,7 +606,7 @@ class PEAR
return $a; return $a;
} }
function staticPushErrorHandling($mode, $options = null) public static function staticPushErrorHandling($mode, $options = null)
{ {
$stack = &$GLOBALS['_PEAR_error_handler_stack']; $stack = &$GLOBALS['_PEAR_error_handler_stack'];
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
@ -604,7 +641,7 @@ class PEAR
return true; return true;
} }
function staticPopErrorHandling() public static function staticPopErrorHandling()
{ {
$stack = &$GLOBALS['_PEAR_error_handler_stack']; $stack = &$GLOBALS['_PEAR_error_handler_stack'];
$setmode = &$GLOBALS['_PEAR_default_error_mode']; $setmode = &$GLOBALS['_PEAR_default_error_mode'];
@ -652,20 +689,20 @@ class PEAR
* *
* @see PEAR::setErrorHandling * @see PEAR::setErrorHandling
*/ */
function pushErrorHandling($mode, $options = null) protected static function _pushErrorHandling($object, $mode, $options = null)
{ {
$stack = &$GLOBALS['_PEAR_error_handler_stack']; $stack = &$GLOBALS['_PEAR_error_handler_stack'];
if (isset($this) && is_a($this, 'PEAR')) { if ($object !== null) {
$def_mode = &$this->_default_error_mode; $def_mode = &$object->_default_error_mode;
$def_options = &$this->_default_error_options; $def_options = &$object->_default_error_options;
} else { } else {
$def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
$def_options = &$GLOBALS['_PEAR_default_error_options']; $def_options = &$GLOBALS['_PEAR_default_error_options'];
} }
$stack[] = array($def_mode, $def_options); $stack[] = array($def_mode, $def_options);
if (isset($this) && is_a($this, 'PEAR')) { if ($object !== null) {
$this->setErrorHandling($mode, $options); $object->setErrorHandling($mode, $options);
} else { } else {
PEAR::setErrorHandling($mode, $options); PEAR::setErrorHandling($mode, $options);
} }
@ -680,14 +717,14 @@ class PEAR
* *
* @see PEAR::pushErrorHandling * @see PEAR::pushErrorHandling
*/ */
function popErrorHandling() protected static function _popErrorHandling($object)
{ {
$stack = &$GLOBALS['_PEAR_error_handler_stack']; $stack = &$GLOBALS['_PEAR_error_handler_stack'];
array_pop($stack); array_pop($stack);
list($mode, $options) = $stack[sizeof($stack) - 1]; list($mode, $options) = $stack[sizeof($stack) - 1];
array_pop($stack); array_pop($stack);
if (isset($this) && is_a($this, 'PEAR')) { if ($object !== null) {
$this->setErrorHandling($mode, $options); $object->setErrorHandling($mode, $options);
} else { } else {
PEAR::setErrorHandling($mode, $options); PEAR::setErrorHandling($mode, $options);
} }
@ -701,7 +738,7 @@ class PEAR
* @param string $ext The extension name * @param string $ext The extension name
* @return bool Success or not on the dl() call * @return bool Success or not on the dl() call
*/ */
function loadExtension($ext) public static function loadExtension($ext)
{ {
if (extension_loaded($ext)) { if (extension_loaded($ext)) {
return true; return true;
@ -710,8 +747,7 @@ class PEAR
// if either returns true dl() will produce a FATAL error, stop that // if either returns true dl() will produce a FATAL error, stop that
if ( if (
function_exists('dl') === false || function_exists('dl') === false ||
ini_get('enable_dl') != 1 || ini_get('enable_dl') != 1
ini_get('safe_mode') == 1
) { ) {
return false; return false;
} }
@ -732,10 +768,6 @@ class PEAR
} }
} }
if (PEAR_ZE2) {
include_once S9Y_PEAR_PATH . 'PEAR5.php';
}
function _PEAR_call_destructors() function _PEAR_call_destructors()
{ {
global $_PEAR_destructor_object_list; global $_PEAR_destructor_object_list;
@ -743,11 +775,8 @@ function _PEAR_call_destructors()
sizeof($_PEAR_destructor_object_list)) sizeof($_PEAR_destructor_object_list))
{ {
reset($_PEAR_destructor_object_list); reset($_PEAR_destructor_object_list);
if (PEAR_ZE2) {
$destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
} else {
$destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
}
if ($destructLifoExists) { if ($destructLifoExists) {
$_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
@ -794,7 +823,7 @@ function _PEAR_call_destructors()
* @author Gregory Beaver <cellog@php.net> * @author Gregory Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group * @copyright 1997-2006 The PHP Group
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.5 * @version Release: 1.10.1
* @link http://pear.php.net/manual/en/core.pear.pear-error.php * @link http://pear.php.net/manual/en/core.pear.pear-error.php
* @see PEAR::raiseError(), PEAR::throwError() * @see PEAR::raiseError(), PEAR::throwError()
* @since Class available since PHP 4.0.2 * @since Class available since PHP 4.0.2
@ -829,7 +858,7 @@ class PEAR_Error
* @access public * @access public
* *
*/ */
function PEAR_Error($message = 'unknown error', $code = null, function __construct($message = 'unknown error', $code = null,
$mode = null, $options = null, $userinfo = null) $mode = null, $options = null, $userinfo = null)
{ {
if ($mode === null) { if ($mode === null) {
@ -840,11 +869,7 @@ class PEAR_Error
$this->mode = $mode; $this->mode = $mode;
$this->userinfo = $userinfo; $this->userinfo = $userinfo;
if (PEAR_ZE2) {
$skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
} else {
$skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
}
if (!$skiptrace) { if (!$skiptrace) {
$this->backtrace = debug_backtrace(); $this->backtrace = debug_backtrace();
@ -902,6 +927,24 @@ class PEAR_Error
} }
} }
/**
* Only here for backwards compatibility.
*
* Class "Cache_Error" still uses it, among others.
*
* @param string $message Message
* @param int $code Error code
* @param int $mode Error mode
* @param mixed $options See __construct()
* @param string $userinfo Additional user/debug info
*/
public function PEAR_Error(
$message = 'unknown error', $code = null, $mode = null,
$options = null, $userinfo = null
) {
self::__construct($message, $code, $mode, $options, $userinfo);
}
/** /**
* Get the error mode from an error object. * Get the error mode from an error object.
* *

View File

@ -3,19 +3,18 @@
/** /**
* PEAR_Exception * PEAR_Exception
* *
* PHP versions 4 and 5 * PHP version 5
* *
* @category pear * @category PEAR
* @package PEAR * @package PEAR_Exception
* @author Tomas V. V. Cox <cox@idecnet.com> * @author Tomas V. V. Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net> * @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com> * @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors * @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version CVS: $Id: Exception.php 313023 2011-07-06 19:17:11Z dufuz $ * @link http://pear.php.net/package/PEAR_Exception
* @link http://pear.php.net/package/PEAR * @since File available since Release 1.0.0
* @since File available since Release 1.3.3
*/ */
@ -81,18 +80,17 @@
* } * }
* </code> * </code>
* *
* @category pear * @category PEAR
* @package PEAR * @package PEAR_Exception
* @author Tomas V.V.Cox <cox@idecnet.com> * @author Tomas V.V.Cox <cox@idecnet.com>
* @author Hans Lellelid <hans@velum.net> * @author Hans Lellelid <hans@velum.net>
* @author Bertrand Mansion <bmansion@mamasam.com> * @author Bertrand Mansion <bmansion@mamasam.com>
* @author Greg Beaver <cellog@php.net> * @author Greg Beaver <cellog@php.net>
* @copyright 1997-2009 The Authors * @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License * @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.9.4 * @version Release: @package_version@
* @link http://pear.php.net/package/PEAR * @link http://pear.php.net/package/PEAR_Exception
* @since Class available since Release 1.3.3 * @since Class available since Release 1.0.0
*
*/ */
class PEAR_Exception extends Exception class PEAR_Exception extends Exception
{ {
@ -114,9 +112,10 @@ class PEAR_Exception extends Exception
* - PEAR_Exception(string $message, PEAR_Error $cause, int $code); * - PEAR_Exception(string $message, PEAR_Error $cause, int $code);
* - PEAR_Exception(string $message, array $causes); * - PEAR_Exception(string $message, array $causes);
* - PEAR_Exception(string $message, array $causes, int $code); * - PEAR_Exception(string $message, array $causes, int $code);
* @param string exception message *
* @param int|Exception|PEAR_Error|array|null exception cause * @param string $message exception message
* @param int|null exception code or null * @param int|Exception|PEAR_Error|array|null $p2 exception cause
* @param int|null $p3 exception code or null
*/ */
public function __construct($message, $p2 = null, $p3 = null) public function __construct($message, $p2 = null, $p3 = null)
{ {
@ -127,8 +126,10 @@ class PEAR_Exception extends Exception
// using is_object allows both Exception and PEAR_Error // using is_object allows both Exception and PEAR_Error
if (is_object($p2) && !($p2 instanceof Exception)) { if (is_object($p2) && !($p2 instanceof Exception)) {
if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) {
throw new PEAR_Exception('exception cause must be Exception, ' . throw new PEAR_Exception(
'array, or PEAR_Error'); 'exception cause must be Exception, ' .
'array, or PEAR_Error'
);
} }
} }
$code = $p3; $code = $p3;
@ -146,24 +147,37 @@ class PEAR_Exception extends Exception
} }
/** /**
* Add an exception observer
*
* @param mixed $callback - A valid php callback, see php func is_callable() * @param mixed $callback - A valid php callback, see php func is_callable()
* - A PEAR_Exception::OBSERVER_* constant * - A PEAR_Exception::OBSERVER_* constant
* - An array(const PEAR_Exception::OBSERVER_*, * - An array(const PEAR_Exception::OBSERVER_*,
* mixed $options) * mixed $options)
* @param string $label The name of the observer. Use this if you want * @param string $label The name of the observer. Use this if you want
* to remove it later with removeObserver() * to remove it later with removeObserver()
*
* @return void
*/ */
public static function addObserver($callback, $label = 'default') public static function addObserver($callback, $label = 'default')
{ {
self::$_observers[$label] = $callback; self::$_observers[$label] = $callback;
} }
/**
* Remove an exception observer
*
* @param string $label Name of the observer
*
* @return void
*/
public static function removeObserver($label = 'default') public static function removeObserver($label = 'default')
{ {
unset(self::$_observers[$label]); unset(self::$_observers[$label]);
} }
/** /**
* Generate a unique ID for an observer
*
* @return int unique identifier for an observer * @return int unique identifier for an observer
*/ */
public static function getUniqueId() public static function getUniqueId()
@ -171,7 +185,12 @@ class PEAR_Exception extends Exception
return self::$_uniqueid++; return self::$_uniqueid++;
} }
private function signal() /**
* Send a signal to all observers
*
* @return void
*/
protected function signal()
{ {
foreach (self::$_observers as $func) { foreach (self::$_observers as $func) {
if (is_callable($func)) { if (is_callable($func)) {
@ -210,6 +229,7 @@ class PEAR_Exception extends Exception
* <pre> * <pre>
* array('name' => $name, 'context' => array(...)) * array('name' => $name, 'context' => array(...))
* </pre> * </pre>
*
* @return array * @return array
*/ */
public function getErrorData() public function getErrorData()
@ -219,7 +239,7 @@ class PEAR_Exception extends Exception
/** /**
* Returns the exception that caused this exception to be thrown * Returns the exception that caused this exception to be thrown
* @access public *
* @return Exception|array The context of the exception * @return Exception|array The context of the exception
*/ */
public function getCause() public function getCause()
@ -229,7 +249,10 @@ class PEAR_Exception extends Exception
/** /**
* Function must be public to call on caused exceptions * Function must be public to call on caused exceptions
* @param array *
* @param array $causes Array that gets filled.
*
* @return void
*/ */
public function getCauseMessage(&$causes) public function getCauseMessage(&$causes)
{ {
@ -266,7 +289,9 @@ class PEAR_Exception extends Exception
'message' => $cause->getMessage(), 'message' => $cause->getMessage(),
'file' => $cause->getFile(), 'file' => $cause->getFile(),
'line' => $cause->getLine()); 'line' => $cause->getLine());
} elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { } elseif (class_exists('PEAR_Error')
&& $cause instanceof PEAR_Error
) {
$causes[] = array('class' => get_class($cause), $causes[] = array('class' => get_class($cause),
'message' => $cause->getMessage(), 'message' => $cause->getMessage(),
'file' => 'unknown', 'file' => 'unknown',
@ -288,6 +313,11 @@ class PEAR_Exception extends Exception
} }
} }
/**
* Build a backtrace and return it
*
* @return array Backtrace
*/
public function getTraceSafe() public function getTraceSafe()
{ {
if (!isset($this->_trace)) { if (!isset($this->_trace)) {
@ -300,18 +330,36 @@ class PEAR_Exception extends Exception
return $this->_trace; return $this->_trace;
} }
/**
* Gets the first class of the backtrace
*
* @return string Class name
*/
public function getErrorClass() public function getErrorClass()
{ {
$trace = $this->getTraceSafe(); $trace = $this->getTraceSafe();
return $trace[0]['class']; return $trace[0]['class'];
} }
/**
* Gets the first method of the backtrace
*
* @return string Method/function name
*/
public function getErrorMethod() public function getErrorMethod()
{ {
$trace = $this->getTraceSafe(); $trace = $this->getTraceSafe();
return $trace[0]['function']; return $trace[0]['function'];
} }
/**
* Converts the exception to a string (HTML or plain text)
*
* @return string String representation
*
* @see toHtml()
* @see toText()
*/
public function __toString() public function __toString()
{ {
if (isset($_SERVER['REQUEST_URI'])) { if (isset($_SERVER['REQUEST_URI'])) {
@ -320,6 +368,11 @@ class PEAR_Exception extends Exception
return $this->toText(); return $this->toText();
} }
/**
* Generates a HTML representation of the exception
*
* @return string HTML code
*/
public function toHtml() public function toHtml()
{ {
$trace = $this->getTraceSafe(); $trace = $this->getTraceSafe();
@ -329,7 +382,8 @@ class PEAR_Exception extends Exception
foreach ($causes as $i => $cause) { foreach ($causes as $i => $cause) {
$html .= '<tr><td colspan="3" style="background: #ff9999">' $html .= '<tr><td colspan="3" style="background: #ff9999">'
. str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: ' . str_repeat('-', $i) . ' <b>' . $cause['class'] . '</b>: '
. htmlspecialchars($cause['message']) . ' in <b>' . $cause['file'] . '</b> ' . htmlspecialchars($cause['message'])
. ' in <b>' . $cause['file'] . '</b> '
. 'on line <b>' . $cause['line'] . '</b>' . 'on line <b>' . $cause['line'] . '</b>'
. "</td></tr>\n"; . "</td></tr>\n";
} }
@ -348,20 +402,27 @@ class PEAR_Exception extends Exception
$args = array(); $args = array();
if (!empty($v['args'])) { if (!empty($v['args'])) {
foreach ($v['args'] as $arg) { foreach ($v['args'] as $arg) {
if (is_null($arg)) $args[] = 'null'; if (is_null($arg)) {
elseif (is_array($arg)) $args[] = 'Array'; $args[] = 'null';
elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; } else if (is_array($arg)) {
elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; $args[] = 'Array';
elseif (is_int($arg) || is_double($arg)) $args[] = $arg; } else if (is_object($arg)) {
else { $args[] = 'Object('.get_class($arg).')';
} else if (is_bool($arg)) {
$args[] = $arg ? 'true' : 'false';
} else if (is_int($arg) || is_double($arg)) {
$args[] = $arg;
} else {
$arg = (string)$arg; $arg = (string)$arg;
$str = htmlspecialchars(substr($arg, 0, 16)); $str = htmlspecialchars(substr($arg, 0, 16));
if (strlen($arg) > 16) $str .= '&hellip;'; if (strlen($arg) > 16) {
$str .= '&hellip;';
}
$args[] = "'" . $str . "'"; $args[] = "'" . $str . "'";
} }
} }
} }
$html .= '(' . implode(', ',$args) . ')' $html .= '(' . implode(', ', $args) . ')'
. '</td>' . '</td>'
. '<td>' . (isset($v['file']) ? $v['file'] : 'unknown') . '<td>' . (isset($v['file']) ? $v['file'] : 'unknown')
. ':' . (isset($v['line']) ? $v['line'] : 'unknown') . ':' . (isset($v['line']) ? $v['line'] : 'unknown')
@ -374,6 +435,11 @@ class PEAR_Exception extends Exception
return $html; return $html;
} }
/**
* Generates text representation of the exception and stack trace
*
* @return string
*/
public function toText() public function toText()
{ {
$causes = array(); $causes = array();
@ -387,3 +453,4 @@ class PEAR_Exception extends Exception
return $causeMsg . $this->getTraceAsString(); return $causeMsg . $this->getTraceAsString();
} }
} }
?>