Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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