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