Commit c2a89e9bfa96fa5d4b49e38b2dd9a4a9ad35d3a7

Authored by Neil Blakey-Milner
1 parent a072566b

PEAR.php from PEAR-1.3.3.1


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@3008 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing 1 changed file with 1056 additions and 0 deletions
pear/PEAR.php 0 → 100644
  1 +<?php
  2 +//
  3 +// +--------------------------------------------------------------------+
  4 +// | PEAR, the PHP Extension and Application Repository |
  5 +// +--------------------------------------------------------------------+
  6 +// | Copyright (c) 1997-2004 The PHP Group |
  7 +// +--------------------------------------------------------------------+
  8 +// | This source file is subject to version 3.0 of the PHP license, |
  9 +// | that is bundled with this package in the file LICENSE, and is |
  10 +// | available through the world-wide-web at the following url: |
  11 +// | http://www.php.net/license/3_0.txt. |
  12 +// | If you did not receive a copy of the PHP license and are unable to |
  13 +// | obtain it through the world-wide-web, please send a note to |
  14 +// | license@php.net so we can mail you a copy immediately. |
  15 +// +--------------------------------------------------------------------+
  16 +// | Authors: Sterling Hughes <sterling@php.net> |
  17 +// | Stig Bakken <ssb@php.net> |
  18 +// | Tomas V.V.Cox <cox@idecnet.com> |
  19 +// +--------------------------------------------------------------------+
  20 +//
  21 +// $Id$
  22 +//
  23 +
  24 +define('PEAR_ERROR_RETURN', 1);
  25 +define('PEAR_ERROR_PRINT', 2);
  26 +define('PEAR_ERROR_TRIGGER', 4);
  27 +define('PEAR_ERROR_DIE', 8);
  28 +define('PEAR_ERROR_CALLBACK', 16);
  29 +/**
  30 + * WARNING: obsolete
  31 + * @deprecated
  32 + */
  33 +define('PEAR_ERROR_EXCEPTION', 32);
  34 +define('PEAR_ZE2', (function_exists('version_compare') &&
  35 + version_compare(zend_version(), "2-dev", "ge")));
  36 +
  37 +if (substr(PHP_OS, 0, 3) == 'WIN') {
  38 + define('OS_WINDOWS', true);
  39 + define('OS_UNIX', false);
  40 + define('PEAR_OS', 'Windows');
  41 +} else {
  42 + define('OS_WINDOWS', false);
  43 + define('OS_UNIX', true);
  44 + define('PEAR_OS', 'Unix'); // blatant assumption
  45 +}
  46 +
  47 +// instant backwards compatibility
  48 +if (!defined('PATH_SEPARATOR')) {
  49 + if (OS_WINDOWS) {
  50 + define('PATH_SEPARATOR', ';');
  51 + } else {
  52 + define('PATH_SEPARATOR', ':');
  53 + }
  54 +}
  55 +
  56 +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN;
  57 +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE;
  58 +$GLOBALS['_PEAR_destructor_object_list'] = array();
  59 +$GLOBALS['_PEAR_shutdown_funcs'] = array();
  60 +$GLOBALS['_PEAR_error_handler_stack'] = array();
  61 +
  62 +ini_set('track_errors', true);
  63 +
  64 +/**
  65 + * Base class for other PEAR classes. Provides rudimentary
  66 + * emulation of destructors.
  67 + *
  68 + * If you want a destructor in your class, inherit PEAR and make a
  69 + * destructor method called _yourclassname (same name as the
  70 + * constructor, but with a "_" prefix). Also, in your constructor you
  71 + * have to call the PEAR constructor: $this->PEAR();.
  72 + * The destructor method will be called without parameters. Note that
  73 + * at in some SAPI implementations (such as Apache), any output during
  74 + * the request shutdown (in which destructors are called) seems to be
  75 + * discarded. If you need to get any debug information from your
  76 + * destructor, use error_log(), syslog() or something similar.
  77 + *
  78 + * IMPORTANT! To use the emulated destructors you need to create the
  79 + * objects by reference: $obj =& new PEAR_child;
  80 + *
  81 + * @since PHP 4.0.2
  82 + * @author Stig Bakken <ssb@php.net>
  83 + * @see http://pear.php.net/manual/
  84 + */
  85 +class PEAR
  86 +{
  87 + // {{{ properties
  88 +
  89 + /**
  90 + * Whether to enable internal debug messages.
  91 + *
  92 + * @var bool
  93 + * @access private
  94 + */
  95 + var $_debug = false;
  96 +
  97 + /**
  98 + * Default error mode for this object.
  99 + *
  100 + * @var int
  101 + * @access private
  102 + */
  103 + var $_default_error_mode = null;
  104 +
  105 + /**
  106 + * Default error options used for this object when error mode
  107 + * is PEAR_ERROR_TRIGGER.
  108 + *
  109 + * @var int
  110 + * @access private
  111 + */
  112 + var $_default_error_options = null;
  113 +
  114 + /**
  115 + * Default error handler (callback) for this object, if error mode is
  116 + * PEAR_ERROR_CALLBACK.
  117 + *
  118 + * @var string
  119 + * @access private
  120 + */
  121 + var $_default_error_handler = '';
  122 +
  123 + /**
  124 + * Which class to use for error objects.
  125 + *
  126 + * @var string
  127 + * @access private
  128 + */
  129 + var $_error_class = 'PEAR_Error';
  130 +
  131 + /**
  132 + * An array of expected errors.
  133 + *
  134 + * @var array
  135 + * @access private
  136 + */
  137 + var $_expected_errors = array();
  138 +
  139 + // }}}
  140 +
  141 + // {{{ constructor
  142 +
  143 + /**
  144 + * Constructor. Registers this object in
  145 + * $_PEAR_destructor_object_list for destructor emulation if a
  146 + * destructor object exists.
  147 + *
  148 + * @param string $error_class (optional) which class to use for
  149 + * error objects, defaults to PEAR_Error.
  150 + * @access public
  151 + * @return void
  152 + */
  153 + function PEAR($error_class = null)
  154 + {
  155 + $classname = strtolower(get_class($this));
  156 + if ($this->_debug) {
  157 + print "PEAR constructor called, class=$classname\n";
  158 + }
  159 + if ($error_class !== null) {
  160 + $this->_error_class = $error_class;
  161 + }
  162 + while ($classname && strcasecmp($classname, "pear")) {
  163 + $destructor = "_$classname";
  164 + if (method_exists($this, $destructor)) {
  165 + global $_PEAR_destructor_object_list;
  166 + $_PEAR_destructor_object_list[] = &$this;
  167 + static $registered = false;
  168 + if (!$registered) {
  169 + register_shutdown_function("_PEAR_call_destructors");
  170 + $registered = true;
  171 + }
  172 + break;
  173 + } else {
  174 + $classname = get_parent_class($classname);
  175 + }
  176 + }
  177 + }
  178 +
  179 + // }}}
  180 + // {{{ destructor
  181 +
  182 + /**
  183 + * Destructor (the emulated type of...). Does nothing right now,
  184 + * but is included for forward compatibility, so subclass
  185 + * destructors should always call it.
  186 + *
  187 + * See the note in the class desciption about output from
  188 + * destructors.
  189 + *
  190 + * @access public
  191 + * @return void
  192 + */
  193 + function _PEAR() {
  194 + if ($this->_debug) {
  195 + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
  196 + }
  197 + }
  198 +
  199 + // }}}
  200 + // {{{ getStaticProperty()
  201 +
  202 + /**
  203 + * If you have a class that's mostly/entirely static, and you need static
  204 + * properties, you can use this method to simulate them. Eg. in your method(s)
  205 + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
  206 + * You MUST use a reference, or they will not persist!
  207 + *
  208 + * @access public
  209 + * @param string $class The calling classname, to prevent clashes
  210 + * @param string $var The variable to retrieve.
  211 + * @return mixed A reference to the variable. If not set it will be
  212 + * auto initialised to NULL.
  213 + */
  214 + function &getStaticProperty($class, $var)
  215 + {
  216 + static $properties;
  217 + return $properties[$class][$var];
  218 + }
  219 +
  220 + // }}}
  221 + // {{{ registerShutdownFunc()
  222 +
  223 + /**
  224 + * Use this function to register a shutdown method for static
  225 + * classes.
  226 + *
  227 + * @access public
  228 + * @param mixed $func The function name (or array of class/method) to call
  229 + * @param mixed $args The arguments to pass to the function
  230 + * @return void
  231 + */
  232 + function registerShutdownFunc($func, $args = array())
  233 + {
  234 + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
  235 + }
  236 +
  237 + // }}}
  238 + // {{{ isError()
  239 +
  240 + /**
  241 + * Tell whether a value is a PEAR error.
  242 + *
  243 + * @param mixed $data the value to test
  244 + * @param int $code if $data is an error object, return true
  245 + * only if $code is a string and
  246 + * $obj->getMessage() == $code or
  247 + * $code is an integer and $obj->getCode() == $code
  248 + * @access public
  249 + * @return bool true if parameter is an error
  250 + */
  251 + function isError($data, $code = null)
  252 + {
  253 + if (is_a($data, 'PEAR_Error')) {
  254 + if (is_null($code)) {
  255 + return true;
  256 + } elseif (is_string($code)) {
  257 + return $data->getMessage() == $code;
  258 + } else {
  259 + return $data->getCode() == $code;
  260 + }
  261 + }
  262 + return false;
  263 + }
  264 +
  265 + // }}}
  266 + // {{{ setErrorHandling()
  267 +
  268 + /**
  269 + * Sets how errors generated by this object should be handled.
  270 + * Can be invoked both in objects and statically. If called
  271 + * statically, setErrorHandling sets the default behaviour for all
  272 + * PEAR objects. If called in an object, setErrorHandling sets
  273 + * the default behaviour for that object.
  274 + *
  275 + * @param int $mode
  276 + * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  277 + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  278 + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
  279 + *
  280 + * @param mixed $options
  281 + * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
  282 + * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  283 + *
  284 + * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
  285 + * to be the callback function or method. A callback
  286 + * function is a string with the name of the function, a
  287 + * callback method is an array of two elements: the element
  288 + * at index 0 is the object, and the element at index 1 is
  289 + * the name of the method to call in the object.
  290 + *
  291 + * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
  292 + * a printf format string used when printing the error
  293 + * message.
  294 + *
  295 + * @access public
  296 + * @return void
  297 + * @see PEAR_ERROR_RETURN
  298 + * @see PEAR_ERROR_PRINT
  299 + * @see PEAR_ERROR_TRIGGER
  300 + * @see PEAR_ERROR_DIE
  301 + * @see PEAR_ERROR_CALLBACK
  302 + * @see PEAR_ERROR_EXCEPTION
  303 + *
  304 + * @since PHP 4.0.5
  305 + */
  306 +
  307 + function setErrorHandling($mode = null, $options = null)
  308 + {
  309 + if (isset($this) && is_a($this, 'PEAR')) {
  310 + $setmode = &$this->_default_error_mode;
  311 + $setoptions = &$this->_default_error_options;
  312 + } else {
  313 + $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  314 + $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  315 + }
  316 +
  317 + switch ($mode) {
  318 + case PEAR_ERROR_EXCEPTION:
  319 + case PEAR_ERROR_RETURN:
  320 + case PEAR_ERROR_PRINT:
  321 + case PEAR_ERROR_TRIGGER:
  322 + case PEAR_ERROR_DIE:
  323 + case null:
  324 + $setmode = $mode;
  325 + $setoptions = $options;
  326 + break;
  327 +
  328 + case PEAR_ERROR_CALLBACK:
  329 + $setmode = $mode;
  330 + // class/object method callback
  331 + if (is_callable($options)) {
  332 + $setoptions = $options;
  333 + } else {
  334 + trigger_error("invalid error callback", E_USER_WARNING);
  335 + }
  336 + break;
  337 +
  338 + default:
  339 + trigger_error("invalid error mode", E_USER_WARNING);
  340 + break;
  341 + }
  342 + }
  343 +
  344 + // }}}
  345 + // {{{ expectError()
  346 +
  347 + /**
  348 + * This method is used to tell which errors you expect to get.
  349 + * Expected errors are always returned with error mode
  350 + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack,
  351 + * and this method pushes a new element onto it. The list of
  352 + * expected errors are in effect until they are popped off the
  353 + * stack with the popExpect() method.
  354 + *
  355 + * Note that this method can not be called statically
  356 + *
  357 + * @param mixed $code a single error code or an array of error codes to expect
  358 + *
  359 + * @return int the new depth of the "expected errors" stack
  360 + * @access public
  361 + */
  362 + function expectError($code = '*')
  363 + {
  364 + if (is_array($code)) {
  365 + array_push($this->_expected_errors, $code);
  366 + } else {
  367 + array_push($this->_expected_errors, array($code));
  368 + }
  369 + return sizeof($this->_expected_errors);
  370 + }
  371 +
  372 + // }}}
  373 + // {{{ popExpect()
  374 +
  375 + /**
  376 + * This method pops one element off the expected error codes
  377 + * stack.
  378 + *
  379 + * @return array the list of error codes that were popped
  380 + */
  381 + function popExpect()
  382 + {
  383 + return array_pop($this->_expected_errors);
  384 + }
  385 +
  386 + // }}}
  387 + // {{{ _checkDelExpect()
  388 +
  389 + /**
  390 + * This method checks unsets an error code if available
  391 + *
  392 + * @param mixed error code
  393 + * @return bool true if the error code was unset, false otherwise
  394 + * @access private
  395 + * @since PHP 4.3.0
  396 + */
  397 + function _checkDelExpect($error_code)
  398 + {
  399 + $deleted = false;
  400 +
  401 + foreach ($this->_expected_errors AS $key => $error_array) {
  402 + if (in_array($error_code, $error_array)) {
  403 + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
  404 + $deleted = true;
  405 + }
  406 +
  407 + // clean up empty arrays
  408 + if (0 == count($this->_expected_errors[$key])) {
  409 + unset($this->_expected_errors[$key]);
  410 + }
  411 + }
  412 + return $deleted;
  413 + }
  414 +
  415 + // }}}
  416 + // {{{ delExpect()
  417 +
  418 + /**
  419 + * This method deletes all occurences of the specified element from
  420 + * the expected error codes stack.
  421 + *
  422 + * @param mixed $error_code error code that should be deleted
  423 + * @return mixed list of error codes that were deleted or error
  424 + * @access public
  425 + * @since PHP 4.3.0
  426 + */
  427 + function delExpect($error_code)
  428 + {
  429 + $deleted = false;
  430 +
  431 + if ((is_array($error_code) && (0 != count($error_code)))) {
  432 + // $error_code is a non-empty array here;
  433 + // we walk through it trying to unset all
  434 + // values
  435 + foreach($error_code as $key => $error) {
  436 + if ($this->_checkDelExpect($error)) {
  437 + $deleted = true;
  438 + } else {
  439 + $deleted = false;
  440 + }
  441 + }
  442 + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  443 + } elseif (!empty($error_code)) {
  444 + // $error_code comes alone, trying to unset it
  445 + if ($this->_checkDelExpect($error_code)) {
  446 + return true;
  447 + } else {
  448 + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
  449 + }
  450 + } else {
  451 + // $error_code is empty
  452 + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
  453 + }
  454 + }
  455 +
  456 + // }}}
  457 + // {{{ raiseError()
  458 +
  459 + /**
  460 + * This method is a wrapper that returns an instance of the
  461 + * configured error class with this object's default error
  462 + * handling applied. If the $mode and $options parameters are not
  463 + * specified, the object's defaults are used.
  464 + *
  465 + * @param mixed $message a text error message or a PEAR error object
  466 + *
  467 + * @param int $code a numeric error code (it is up to your class
  468 + * to define these if you want to use codes)
  469 + *
  470 + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
  471 + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
  472 + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
  473 + *
  474 + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
  475 + * specifies the PHP-internal error level (one of
  476 + * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
  477 + * If $mode is PEAR_ERROR_CALLBACK, this
  478 + * parameter specifies the callback function or
  479 + * method. In other error modes this parameter
  480 + * is ignored.
  481 + *
  482 + * @param string $userinfo If you need to pass along for example debug
  483 + * information, this parameter is meant for that.
  484 + *
  485 + * @param string $error_class The returned error object will be
  486 + * instantiated from this class, if specified.
  487 + *
  488 + * @param bool $skipmsg If true, raiseError will only pass error codes,
  489 + * the error message parameter will be dropped.
  490 + *
  491 + * @access public
  492 + * @return object a PEAR error object
  493 + * @see PEAR::setErrorHandling
  494 + * @since PHP 4.0.5
  495 + */
  496 + function raiseError($message = null,
  497 + $code = null,
  498 + $mode = null,
  499 + $options = null,
  500 + $userinfo = null,
  501 + $error_class = null,
  502 + $skipmsg = false)
  503 + {
  504 + // The error is yet a PEAR error object
  505 + if (is_object($message)) {
  506 + $code = $message->getCode();
  507 + $userinfo = $message->getUserInfo();
  508 + $error_class = $message->getType();
  509 + $message->error_message_prefix = '';
  510 + $message = $message->getMessage();
  511 + }
  512 +
  513 + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
  514 + if ($exp[0] == "*" ||
  515 + (is_int(reset($exp)) && in_array($code, $exp)) ||
  516 + (is_string(reset($exp)) && in_array($message, $exp))) {
  517 + $mode = PEAR_ERROR_RETURN;
  518 + }
  519 + }
  520 + // No mode given, try global ones
  521 + if ($mode === null) {
  522 + // Class error handler
  523 + if (isset($this) && isset($this->_default_error_mode)) {
  524 + $mode = $this->_default_error_mode;
  525 + $options = $this->_default_error_options;
  526 + // Global error handler
  527 + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
  528 + $mode = $GLOBALS['_PEAR_default_error_mode'];
  529 + $options = $GLOBALS['_PEAR_default_error_options'];
  530 + }
  531 + }
  532 +
  533 + if ($error_class !== null) {
  534 + $ec = $error_class;
  535 + } elseif (isset($this) && isset($this->_error_class)) {
  536 + $ec = $this->_error_class;
  537 + } else {
  538 + $ec = 'PEAR_Error';
  539 + }
  540 + if ($skipmsg) {
  541 + return new $ec($code, $mode, $options, $userinfo);
  542 + } else {
  543 + return new $ec($message, $code, $mode, $options, $userinfo);
  544 + }
  545 + }
  546 +
  547 + // }}}
  548 + // {{{ throwError()
  549 +
  550 + /**
  551 + * Simpler form of raiseError with fewer options. In most cases
  552 + * message, code and userinfo are enough.
  553 + *
  554 + * @param string $message
  555 + *
  556 + */
  557 + function throwError($message = null,
  558 + $code = null,
  559 + $userinfo = null)
  560 + {
  561 + if (isset($this) && is_a($this, 'PEAR')) {
  562 + return $this->raiseError($message, $code, null, null, $userinfo);
  563 + } else {
  564 + return PEAR::raiseError($message, $code, null, null, $userinfo);
  565 + }
  566 + }
  567 +
  568 + // }}}
  569 + function staticPushErrorHandling($mode, $options = null)
  570 + {
  571 + $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  572 + $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  573 + $def_options = &$GLOBALS['_PEAR_default_error_options'];
  574 + $stack[] = array($def_mode, $def_options);
  575 + switch ($mode) {
  576 + case PEAR_ERROR_EXCEPTION:
  577 + case PEAR_ERROR_RETURN:
  578 + case PEAR_ERROR_PRINT:
  579 + case PEAR_ERROR_TRIGGER:
  580 + case PEAR_ERROR_DIE:
  581 + case null:
  582 + $def_mode = $mode;
  583 + $def_options = $options;
  584 + break;
  585 +
  586 + case PEAR_ERROR_CALLBACK:
  587 + $def_mode = $mode;
  588 + // class/object method callback
  589 + if (is_callable($options)) {
  590 + $def_options = $options;
  591 + } else {
  592 + trigger_error("invalid error callback", E_USER_WARNING);
  593 + }
  594 + break;
  595 +
  596 + default:
  597 + trigger_error("invalid error mode", E_USER_WARNING);
  598 + break;
  599 + }
  600 + $stack[] = array($mode, $options);
  601 + return true;
  602 + }
  603 +
  604 + function staticPopErrorHandling()
  605 + {
  606 + $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  607 + $setmode = &$GLOBALS['_PEAR_default_error_mode'];
  608 + $setoptions = &$GLOBALS['_PEAR_default_error_options'];
  609 + array_pop($stack);
  610 + list($mode, $options) = $stack[sizeof($stack) - 1];
  611 + array_pop($stack);
  612 + switch ($mode) {
  613 + case PEAR_ERROR_EXCEPTION:
  614 + case PEAR_ERROR_RETURN:
  615 + case PEAR_ERROR_PRINT:
  616 + case PEAR_ERROR_TRIGGER:
  617 + case PEAR_ERROR_DIE:
  618 + case null:
  619 + $setmode = $mode;
  620 + $setoptions = $options;
  621 + break;
  622 +
  623 + case PEAR_ERROR_CALLBACK:
  624 + $setmode = $mode;
  625 + // class/object method callback
  626 + if (is_callable($options)) {
  627 + $setoptions = $options;
  628 + } else {
  629 + trigger_error("invalid error callback", E_USER_WARNING);
  630 + }
  631 + break;
  632 +
  633 + default:
  634 + trigger_error("invalid error mode", E_USER_WARNING);
  635 + break;
  636 + }
  637 + return true;
  638 + }
  639 +
  640 + // {{{ pushErrorHandling()
  641 +
  642 + /**
  643 + * Push a new error handler on top of the error handler options stack. With this
  644 + * you can easily override the actual error handler for some code and restore
  645 + * it later with popErrorHandling.
  646 + *
  647 + * @param mixed $mode (same as setErrorHandling)
  648 + * @param mixed $options (same as setErrorHandling)
  649 + *
  650 + * @return bool Always true
  651 + *
  652 + * @see PEAR::setErrorHandling
  653 + */
  654 + function pushErrorHandling($mode, $options = null)
  655 + {
  656 + $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  657 + if (isset($this) && is_a($this, 'PEAR')) {
  658 + $def_mode = &$this->_default_error_mode;
  659 + $def_options = &$this->_default_error_options;
  660 + } else {
  661 + $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
  662 + $def_options = &$GLOBALS['_PEAR_default_error_options'];
  663 + }
  664 + $stack[] = array($def_mode, $def_options);
  665 +
  666 + if (isset($this) && is_a($this, 'PEAR')) {
  667 + $this->setErrorHandling($mode, $options);
  668 + } else {
  669 + PEAR::setErrorHandling($mode, $options);
  670 + }
  671 + $stack[] = array($mode, $options);
  672 + return true;
  673 + }
  674 +
  675 + // }}}
  676 + // {{{ popErrorHandling()
  677 +
  678 + /**
  679 + * Pop the last error handler used
  680 + *
  681 + * @return bool Always true
  682 + *
  683 + * @see PEAR::pushErrorHandling
  684 + */
  685 + function popErrorHandling()
  686 + {
  687 + $stack = &$GLOBALS['_PEAR_error_handler_stack'];
  688 + array_pop($stack);
  689 + list($mode, $options) = $stack[sizeof($stack) - 1];
  690 + array_pop($stack);
  691 + if (isset($this) && is_a($this, 'PEAR')) {
  692 + $this->setErrorHandling($mode, $options);
  693 + } else {
  694 + PEAR::setErrorHandling($mode, $options);
  695 + }
  696 + return true;
  697 + }
  698 +
  699 + // }}}
  700 + // {{{ loadExtension()
  701 +
  702 + /**
  703 + * OS independant PHP extension load. Remember to take care
  704 + * on the correct extension name for case sensitive OSes.
  705 + *
  706 + * @param string $ext The extension name
  707 + * @return bool Success or not on the dl() call
  708 + */
  709 + function loadExtension($ext)
  710 + {
  711 + if (!extension_loaded($ext)) {
  712 + // if either returns true dl() will produce a FATAL error, stop that
  713 + if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
  714 + return false;
  715 + }
  716 + if (OS_WINDOWS) {
  717 + $suffix = '.dll';
  718 + } elseif (PHP_OS == 'HP-UX') {
  719 + $suffix = '.sl';
  720 + } elseif (PHP_OS == 'AIX') {
  721 + $suffix = '.a';
  722 + } elseif (PHP_OS == 'OSX') {
  723 + $suffix = '.bundle';
  724 + } else {
  725 + $suffix = '.so';
  726 + }
  727 + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
  728 + }
  729 + return true;
  730 + }
  731 +
  732 + // }}}
  733 +}
  734 +
  735 +// {{{ _PEAR_call_destructors()
  736 +
  737 +function _PEAR_call_destructors()
  738 +{
  739 + global $_PEAR_destructor_object_list;
  740 + if (is_array($_PEAR_destructor_object_list) &&
  741 + sizeof($_PEAR_destructor_object_list))
  742 + {
  743 + reset($_PEAR_destructor_object_list);
  744 + if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {
  745 + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
  746 + }
  747 + while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
  748 + $classname = get_class($objref);
  749 + while ($classname) {
  750 + $destructor = "_$classname";
  751 + if (method_exists($objref, $destructor)) {
  752 + $objref->$destructor();
  753 + break;
  754 + } else {
  755 + $classname = get_parent_class($classname);
  756 + }
  757 + }
  758 + }
  759 + // Empty the object list to ensure that destructors are
  760 + // not called more than once.
  761 + $_PEAR_destructor_object_list = array();
  762 + }
  763 +
  764 + // Now call the shutdown functions
  765 + if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
  766 + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
  767 + call_user_func_array($value[0], $value[1]);
  768 + }
  769 + }
  770 +}
  771 +
  772 +// }}}
  773 +
  774 +class PEAR_Error
  775 +{
  776 + // {{{ properties
  777 +
  778 + var $error_message_prefix = '';
  779 + var $mode = PEAR_ERROR_RETURN;
  780 + var $level = E_USER_NOTICE;
  781 + var $code = -1;
  782 + var $message = '';
  783 + var $userinfo = '';
  784 + var $backtrace = null;
  785 +
  786 + // }}}
  787 + // {{{ constructor
  788 +
  789 + /**
  790 + * PEAR_Error constructor
  791 + *
  792 + * @param string $message message
  793 + *
  794 + * @param int $code (optional) error code
  795 + *
  796 + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN,
  797 + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
  798 + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
  799 + *
  800 + * @param mixed $options (optional) error level, _OR_ in the case of
  801 + * PEAR_ERROR_CALLBACK, the callback function or object/method
  802 + * tuple.
  803 + *
  804 + * @param string $userinfo (optional) additional user/debug info
  805 + *
  806 + * @access public
  807 + *
  808 + */
  809 + function PEAR_Error($message = 'unknown error', $code = null,
  810 + $mode = null, $options = null, $userinfo = null)
  811 + {
  812 + if ($mode === null) {
  813 + $mode = PEAR_ERROR_RETURN;
  814 + }
  815 + $this->message = $message;
  816 + $this->code = $code;
  817 + $this->mode = $mode;
  818 + $this->userinfo = $userinfo;
  819 + if (function_exists("debug_backtrace")) {
  820 + if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
  821 + $this->backtrace = debug_backtrace();
  822 + }
  823 + }
  824 + if ($mode & PEAR_ERROR_CALLBACK) {
  825 + $this->level = E_USER_NOTICE;
  826 + $this->callback = $options;
  827 + } else {
  828 + if ($options === null) {
  829 + $options = E_USER_NOTICE;
  830 + }
  831 + $this->level = $options;
  832 + $this->callback = null;
  833 + }
  834 + if ($this->mode & PEAR_ERROR_PRINT) {
  835 + if (is_null($options) || is_int($options)) {
  836 + $format = "%s";
  837 + } else {
  838 + $format = $options;
  839 + }
  840 + printf($format, $this->getMessage());
  841 + }
  842 + if ($this->mode & PEAR_ERROR_TRIGGER) {
  843 + trigger_error($this->getMessage(), $this->level);
  844 + }
  845 + if ($this->mode & PEAR_ERROR_DIE) {
  846 + $msg = $this->getMessage();
  847 + if (is_null($options) || is_int($options)) {
  848 + $format = "%s";
  849 + if (substr($msg, -1) != "\n") {
  850 + $msg .= "\n";
  851 + }
  852 + } else {
  853 + $format = $options;
  854 + }
  855 + die(sprintf($format, $msg));
  856 + }
  857 + if ($this->mode & PEAR_ERROR_CALLBACK) {
  858 + if (is_callable($this->callback)) {
  859 + call_user_func($this->callback, $this);
  860 + }
  861 + }
  862 + if ($this->mode & PEAR_ERROR_EXCEPTION) {
  863 + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING);
  864 + eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);');
  865 + }
  866 + }
  867 +
  868 + // }}}
  869 + // {{{ getMode()
  870 +
  871 + /**
  872 + * Get the error mode from an error object.
  873 + *
  874 + * @return int error mode
  875 + * @access public
  876 + */
  877 + function getMode() {
  878 + return $this->mode;
  879 + }
  880 +
  881 + // }}}
  882 + // {{{ getCallback()
  883 +
  884 + /**
  885 + * Get the callback function/method from an error object.
  886 + *
  887 + * @return mixed callback function or object/method array
  888 + * @access public
  889 + */
  890 + function getCallback() {
  891 + return $this->callback;
  892 + }
  893 +
  894 + // }}}
  895 + // {{{ getMessage()
  896 +
  897 +
  898 + /**
  899 + * Get the error message from an error object.
  900 + *
  901 + * @return string full error message
  902 + * @access public
  903 + */
  904 + function getMessage()
  905 + {
  906 + return ($this->error_message_prefix . $this->message);
  907 + }
  908 +
  909 +
  910 + // }}}
  911 + // {{{ getCode()
  912 +
  913 + /**
  914 + * Get error code from an error object
  915 + *
  916 + * @return int error code
  917 + * @access public
  918 + */
  919 + function getCode()
  920 + {
  921 + return $this->code;
  922 + }
  923 +
  924 + // }}}
  925 + // {{{ getType()
  926 +
  927 + /**
  928 + * Get the name of this error/exception.
  929 + *
  930 + * @return string error/exception name (type)
  931 + * @access public
  932 + */
  933 + function getType()
  934 + {
  935 + return get_class($this);
  936 + }
  937 +
  938 + // }}}
  939 + // {{{ getUserInfo()
  940 +
  941 + /**
  942 + * Get additional user-supplied information.
  943 + *
  944 + * @return string user-supplied information
  945 + * @access public
  946 + */
  947 + function getUserInfo()
  948 + {
  949 + return $this->userinfo;
  950 + }
  951 +
  952 + // }}}
  953 + // {{{ getDebugInfo()
  954 +
  955 + /**
  956 + * Get additional debug information supplied by the application.
  957 + *
  958 + * @return string debug information
  959 + * @access public
  960 + */
  961 + function getDebugInfo()
  962 + {
  963 + return $this->getUserInfo();
  964 + }
  965 +
  966 + // }}}
  967 + // {{{ getBacktrace()
  968 +
  969 + /**
  970 + * Get the call backtrace from where the error was generated.
  971 + * Supported with PHP 4.3.0 or newer.
  972 + *
  973 + * @param int $frame (optional) what frame to fetch
  974 + * @return array Backtrace, or NULL if not available.
  975 + * @access public
  976 + */
  977 + function getBacktrace($frame = null)
  978 + {
  979 + if ($frame === null) {
  980 + return $this->backtrace;
  981 + }
  982 + return $this->backtrace[$frame];
  983 + }
  984 +
  985 + // }}}
  986 + // {{{ addUserInfo()
  987 +
  988 + function addUserInfo($info)
  989 + {
  990 + if (empty($this->userinfo)) {
  991 + $this->userinfo = $info;
  992 + } else {
  993 + $this->userinfo .= " ** $info";
  994 + }
  995 + }
  996 +
  997 + // }}}
  998 + // {{{ toString()
  999 +
  1000 + /**
  1001 + * Make a string representation of this object.
  1002 + *
  1003 + * @return string a string with an object summary
  1004 + * @access public
  1005 + */
  1006 + function toString() {
  1007 + $modes = array();
  1008 + $levels = array(E_USER_NOTICE => 'notice',
  1009 + E_USER_WARNING => 'warning',
  1010 + E_USER_ERROR => 'error');
  1011 + if ($this->mode & PEAR_ERROR_CALLBACK) {
  1012 + if (is_array($this->callback)) {
  1013 + $callback = (is_object($this->callback[0]) ?
  1014 + strtolower(get_class($this->callback[0])) :
  1015 + $this->callback[0]) . '::' .
  1016 + $this->callback[1];
  1017 + } else {
  1018 + $callback = $this->callback;
  1019 + }
  1020 + return sprintf('[%s: message="%s" code=%d mode=callback '.
  1021 + 'callback=%s prefix="%s" info="%s"]',
  1022 + strtolower(get_class($this)), $this->message, $this->code,
  1023 + $callback, $this->error_message_prefix,
  1024 + $this->userinfo);
  1025 + }
  1026 + if ($this->mode & PEAR_ERROR_PRINT) {
  1027 + $modes[] = 'print';
  1028 + }
  1029 + if ($this->mode & PEAR_ERROR_TRIGGER) {
  1030 + $modes[] = 'trigger';
  1031 + }
  1032 + if ($this->mode & PEAR_ERROR_DIE) {
  1033 + $modes[] = 'die';
  1034 + }
  1035 + if ($this->mode & PEAR_ERROR_RETURN) {
  1036 + $modes[] = 'return';
  1037 + }
  1038 + return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
  1039 + 'prefix="%s" info="%s"]',
  1040 + strtolower(get_class($this)), $this->message, $this->code,
  1041 + implode("|", $modes), $levels[$this->level],
  1042 + $this->error_message_prefix,
  1043 + $this->userinfo);
  1044 + }
  1045 +
  1046 + // }}}
  1047 +}
  1048 +
  1049 +/*
  1050 + * Local Variables:
  1051 + * mode: php
  1052 + * tab-width: 4
  1053 + * c-basic-offset: 4
  1054 + * End:
  1055 + */
  1056 +?>
... ...