Proyectos de Subversion Moodle

Rev

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