Project

General

Profile

Download (32.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	pfSense_MODULE:	utils
5
*/
6

    
7
//
8
// +--------------------------------------------------------------------+
9
// | PEAR, the PHP Extension and Application Repository                 |
10
// +--------------------------------------------------------------------+
11
// | Copyright (c) 1997-2004 The PHP Group                              |
12
// +--------------------------------------------------------------------+
13
// | This source file is subject to version 3.0 of the PHP license,     |
14
// | that is bundled with this package in the file LICENSE, and is      |
15
// | available through the world-wide-web at the following url:         |
16
// | http://www.php.net/license/3_0.txt.                                |
17
// | If you did not receive a copy of the PHP license and are unable to |
18
// | obtain it through the world-wide-web, please send a note to        |
19
// | license@php.net so we can mail you a copy immediately.             |
20
// +--------------------------------------------------------------------+
21
// | Authors: Sterling Hughes <sterling@php.net>                        |
22
// |          Stig Bakken <ssb@php.net>                                 |
23
// |          Tomas V.V.Cox <cox@idecnet.com>                           |
24
// +--------------------------------------------------------------------+
25
//
26
//
27

    
28
define('PEAR_ERROR_RETURN',     1);
29
define('PEAR_ERROR_PRINT',      2);
30
define('PEAR_ERROR_TRIGGER',    4);
31
define('PEAR_ERROR_DIE',        8);
32
define('PEAR_ERROR_CALLBACK',  16);
33
/**
34
 * WARNING: obsolete
35
 * @deprecated
36
 */
37
define('PEAR_ERROR_EXCEPTION', 32);
38
define('PEAR_ZE2', (function_exists('version_compare') &&
39
                    version_compare(zend_version(), "2-dev", "ge")));
40

    
41
if (substr(PHP_OS, 0, 3) == 'WIN') {
42
    define('OS_WINDOWS', true);
43
    define('OS_UNIX',    false);
44
    define('PEAR_OS',    'Windows');
45
} else {
46
    define('OS_WINDOWS', false);
47
    define('OS_UNIX',    true);
48
    define('PEAR_OS',    'Unix'); // blatant assumption
49
}
50

    
51
// instant backwards compatibility
52
if (!defined('PATH_SEPARATOR')) {
53
    if (OS_WINDOWS) {
54
        define('PATH_SEPARATOR', ';');
55
    } else {
56
        define('PATH_SEPARATOR', ':');
57
    }
58
}
59

    
60
$GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
61
$GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
62
$GLOBALS['_PEAR_destructor_object_list'] = array();
63
$GLOBALS['_PEAR_shutdown_funcs']         = array();
64
$GLOBALS['_PEAR_error_handler_stack']    = array();
65

    
66
@ini_set('track_errors', true);
67

    
68
/**
69
 * Base class for other PEAR classes.  Provides rudimentary
70
 * emulation of destructors.
71
 *
72
 * If you want a destructor in your class, inherit PEAR and make a
73
 * destructor method called _yourclassname (same name as the
74
 * constructor, but with a "_" prefix).  Also, in your constructor you
75
 * have to call the PEAR constructor: $this->PEAR();.
76
 * The destructor method will be called without parameters.  Note that
77
 * at in some SAPI implementations (such as Apache), any output during
78
 * the request shutdown (in which destructors are called) seems to be
79
 * discarded.  If you need to get any debug information from your
80
 * destructor, use error_log(), syslog() or something similar.
81
 *
82
 * IMPORTANT! To use the emulated destructors you need to create the
83
 * objects by reference: $obj =& new PEAR_child;
84
 *
85
 * @since PHP 4.0.2
86
 * @author Stig Bakken <ssb@php.net>
87
 * @see http://pear.php.net/manual/
88
 */
89
class PEAR
90
{
91
    // {{{ properties
92

    
93
    /**
94
     * Whether to enable internal debug messages.
95
     *
96
     * @var     bool
97
     * @access  private
98
     */
99
    var $_debug = false;
100

    
101
    /**
102
     * Default error mode for this object.
103
     *
104
     * @var     int
105
     * @access  private
106
     */
107
    var $_default_error_mode = null;
108

    
109
    /**
110
     * Default error options used for this object when error mode
111
     * is PEAR_ERROR_TRIGGER.
112
     *
113
     * @var     int
114
     * @access  private
115
     */
116
    var $_default_error_options = null;
117

    
118
    /**
119
     * Default error handler (callback) for this object, if error mode is
120
     * PEAR_ERROR_CALLBACK.
121
     *
122
     * @var     string
123
     * @access  private
124
     */
125
    var $_default_error_handler = '';
126

    
127
    /**
128
     * Which class to use for error objects.
129
     *
130
     * @var     string
131
     * @access  private
132
     */
133
    var $_error_class = 'PEAR_Error';
134

    
135
    /**
136
     * An array of expected errors.
137
     *
138
     * @var     array
139
     * @access  private
140
     */
141
    var $_expected_errors = array();
142

    
143
    // }}}
144

    
145
    // {{{ constructor
146

    
147
    /**
148
     * Constructor.  Registers this object in
149
     * $_PEAR_destructor_object_list for destructor emulation if a
150
     * destructor object exists.
151
     *
152
     * @param string $error_class  (optional) which class to use for
153
     *        error objects, defaults to PEAR_Error.
154
     * @access public
155
     * @return void
156
     */
157
    function PEAR($error_class = null)
158
    {
159
        $classname = strtolower(get_class($this));
160
        if ($this->_debug) {
161
            print "PEAR constructor called, class=$classname\n";
162
        }
163
        if ($error_class !== null) {
164
            $this->_error_class = $error_class;
165
        }
166
        while ($classname && strcasecmp($classname, "pear")) {
167
            $destructor = "_$classname";
168
            if (method_exists($this, $destructor)) {
169
                global $_PEAR_destructor_object_list;
170
                $_PEAR_destructor_object_list[] = &$this;
171
                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
172
                    register_shutdown_function("_PEAR_call_destructors");
173
                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
174
                }
175
                break;
176
            } else {
177
                $classname = get_parent_class($classname);
178
            }
179
        }
180
    }
181

    
182
    // }}}
183
    // {{{ destructor
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
    // {{{ getStaticProperty()
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
        return $properties[$class][$var];
221
    }
222

    
223
    // }}}
224
    // {{{ registerShutdownFunc()
225

    
226
    /**
227
    * Use this function to register a shutdown method for static
228
    * classes.
229
    *
230
    * @access public
231
    * @param  mixed $func  The function name (or array of class/method) to call
232
    * @param  mixed $args  The arguments to pass to the function
233
    * @return void
234
    */
235
    function registerShutdownFunc($func, $args = array())
236
    {
237
        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
238
    }
239

    
240
    // }}}
241
    // {{{ isError()
242

    
243
    /**
244
     * Tell whether a value is a PEAR error.
245
     *
246
     * @param   mixed $data   the value to test
247
     * @param   int   $code   if $data is an error object, return true
248
     *                        only if $code is a string and
249
     *                        $obj->getMessage() == $code or
250
     *                        $code is an integer and $obj->getCode() == $code
251
     * @access  public
252
     * @return  bool    true if parameter is an error
253
     */
254
    function isError($data, $code = null)
255
    {
256
        if (is_a($data, 'PEAR_Error')) {
257
            if (is_null($code)) {
258
                return true;
259
            } elseif (is_string($code)) {
260
                return $data->getMessage() == $code;
261
            } else {
262
                return $data->getCode() == $code;
263
            }
264
        }
265
        return false;
266
    }
267

    
268
    // }}}
269
    // {{{ setErrorHandling()
270

    
271
    /**
272
     * Sets how errors generated by this object should be handled.
273
     * Can be invoked both in objects and statically.  If called
274
     * statically, setErrorHandling sets the default behaviour for all
275
     * PEAR objects.  If called in an object, setErrorHandling sets
276
     * the default behaviour for that object.
277
     *
278
     * @param int $mode
279
     *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
280
     *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
281
     *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
282
     *
283
     * @param mixed $options
284
     *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
285
     *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
286
     *
287
     *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
288
     *        to be the callback function or method.  A callback
289
     *        function is a string with the name of the function, a
290
     *        callback method is an array of two elements: the element
291
     *        at index 0 is the object, and the element at index 1 is
292
     *        the name of the method to call in the object.
293
     *
294
     *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
295
     *        a printf format string used when printing the error
296
     *        message.
297
     *
298
     * @access public
299
     * @return void
300
     * @see PEAR_ERROR_RETURN
301
     * @see PEAR_ERROR_PRINT
302
     * @see PEAR_ERROR_TRIGGER
303
     * @see PEAR_ERROR_DIE
304
     * @see PEAR_ERROR_CALLBACK
305
     * @see PEAR_ERROR_EXCEPTION
306
     *
307
     * @since PHP 4.0.5
308
     */
309

    
310
    function setErrorHandling($mode = null, $options = null)
311
    {
312
        if (isset($this) && is_a($this, 'PEAR')) {
313
            $setmode     = &$this->_default_error_mode;
314
            $setoptions  = &$this->_default_error_options;
315
        } else {
316
            $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
317
            $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
318
        }
319

    
320
        switch ($mode) {
321
            case PEAR_ERROR_EXCEPTION:
322
            case PEAR_ERROR_RETURN:
323
            case PEAR_ERROR_PRINT:
324
            case PEAR_ERROR_TRIGGER:
325
            case PEAR_ERROR_DIE:
326
            case null:
327
                $setmode = $mode;
328
                $setoptions = $options;
329
                break;
330

    
331
            case PEAR_ERROR_CALLBACK:
332
                $setmode = $mode;
333
                // class/object method callback
334
                if (is_callable($options)) {
335
                    $setoptions = $options;
336
                } else {
337
                    trigger_error("invalid error callback", E_USER_WARNING);
338
                }
339
                break;
340

    
341
            default:
342
                trigger_error("invalid error mode", E_USER_WARNING);
343
                break;
344
        }
345
    }
346

    
347
    // }}}
348
    // {{{ expectError()
349

    
350
    /**
351
     * This method is used to tell which errors you expect to get.
352
     * Expected errors are always returned with error mode
353
     * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
354
     * and this method pushes a new element onto it.  The list of
355
     * expected errors are in effect until they are popped off the
356
     * stack with the popExpect() method.
357
     *
358
     * Note that this method can not be called statically
359
     *
360
     * @param mixed $code a single error code or an array of error codes to expect
361
     *
362
     * @return int     the new depth of the "expected errors" stack
363
     * @access public
364
     */
365
    function expectError($code = '*')
366
    {
367
        if (is_array($code)) {
368
            array_push($this->_expected_errors, $code);
369
        } else {
370
            array_push($this->_expected_errors, array($code));
371
        }
372
        return sizeof($this->_expected_errors);
373
    }
374

    
375
    // }}}
376
    // {{{ popExpect()
377

    
378
    /**
379
     * This method pops one element off the expected error codes
380
     * stack.
381
     *
382
     * @return array   the list of error codes that were popped
383
     */
384
    function popExpect()
385
    {
386
        return array_pop($this->_expected_errors);
387
    }
388

    
389
    // }}}
390
    // {{{ _checkDelExpect()
391

    
392
    /**
393
     * This method checks unsets an error code if available
394
     *
395
     * @param mixed error code
396
     * @return bool true if the error code was unset, false otherwise
397
     * @access private
398
     * @since PHP 4.3.0
399
     */
400
    function _checkDelExpect($error_code)
401
    {
402
        $deleted = false;
403

    
404
        foreach ($this->_expected_errors AS $key => $error_array) {
405
            if (in_array($error_code, $error_array)) {
406
                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
407
                $deleted = true;
408
            }
409

    
410
            // clean up empty arrays
411
            if (0 == count($this->_expected_errors[$key])) {
412
                unset($this->_expected_errors[$key]);
413
            }
414
        }
415
        return $deleted;
416
    }
417

    
418
    // }}}
419
    // {{{ delExpect()
420

    
421
    /**
422
     * This method deletes all occurences of the specified element from
423
     * the expected error codes stack.
424
     *
425
     * @param  mixed $error_code error code that should be deleted
426
     * @return mixed list of error codes that were deleted or error
427
     * @access public
428
     * @since PHP 4.3.0
429
     */
430
    function delExpect($error_code)
431
    {
432
        $deleted = false;
433

    
434
        if ((is_array($error_code) && (0 != count($error_code)))) {
435
            // $error_code is a non-empty array here;
436
            // we walk through it trying to unset all
437
            // values
438
            foreach($error_code as $key => $error) {
439
                if ($this->_checkDelExpect($error)) {
440
                    $deleted =  true;
441
                } else {
442
                    $deleted = false;
443
                }
444
            }
445
            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
446
        } elseif (!empty($error_code)) {
447
            // $error_code comes alone, trying to unset it
448
            if ($this->_checkDelExpect($error_code)) {
449
                return true;
450
            } else {
451
                return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
452
            }
453
        } else {
454
            // $error_code is empty
455
            return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
456
        }
457
    }
458

    
459
    // }}}
460
    // {{{ raiseError()
461

    
462
    /**
463
     * This method is a wrapper that returns an instance of the
464
     * configured error class with this object's default error
465
     * handling applied.  If the $mode and $options parameters are not
466
     * specified, the object's defaults are used.
467
     *
468
     * @param mixed $message a text error message or a PEAR error object
469
     *
470
     * @param int $code      a numeric error code (it is up to your class
471
     *                  to define these if you want to use codes)
472
     *
473
     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
474
     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
475
     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
476
     *
477
     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
478
     *                  specifies the PHP-internal error level (one of
479
     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
480
     *                  If $mode is PEAR_ERROR_CALLBACK, this
481
     *                  parameter specifies the callback function or
482
     *                  method.  In other error modes this parameter
483
     *                  is ignored.
484
     *
485
     * @param string $userinfo If you need to pass along for example debug
486
     *                  information, this parameter is meant for that.
487
     *
488
     * @param string $error_class The returned error object will be
489
     *                  instantiated from this class, if specified.
490
     *
491
     * @param bool $skipmsg If true, raiseError will only pass error codes,
492
     *                  the error message parameter will be dropped.
493
     *
494
     * @access public
495
     * @return object   a PEAR error object
496
     * @see PEAR::setErrorHandling
497
     * @since PHP 4.0.5
498
     */
499
    function raiseError($message = null,
500
                         $code = null,
501
                         $mode = null,
502
                         $options = null,
503
                         $userinfo = null,
504
                         $error_class = null,
505
                         $skipmsg = false)
506
    {
507
        // The error is yet a PEAR error object
508
        if (is_object($message)) {
509
            $code        = $message->getCode();
510
            $userinfo    = $message->getUserInfo();
511
            $error_class = $message->getType();
512
            $message->error_message_prefix = '';
513
            $message     = $message->getMessage();
514
        }
515

    
516
        if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
517
            if ($exp[0] == "*" ||
518
                (is_int(reset($exp)) && in_array($code, $exp)) ||
519
                (is_string(reset($exp)) && in_array($message, $exp))) {
520
                $mode = PEAR_ERROR_RETURN;
521
            }
522
        }
523
        // No mode given, try global ones
524
        if ($mode === null) {
525
            // Class error handler
526
            if (isset($this) && isset($this->_default_error_mode)) {
527
                $mode    = $this->_default_error_mode;
528
                $options = $this->_default_error_options;
529
            // Global error handler
530
            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
531
                $mode    = $GLOBALS['_PEAR_default_error_mode'];
532
                $options = $GLOBALS['_PEAR_default_error_options'];
533
            }
534
        }
535

    
536
        if ($error_class !== null) {
537
            $ec = $error_class;
538
        } elseif (isset($this) && isset($this->_error_class)) {
539
            $ec = $this->_error_class;
540
        } else {
541
            $ec = 'PEAR_Error';
542
        }
543
        if ($skipmsg) {
544
            return new $ec($code, $mode, $options, $userinfo);
545
        } else {
546
            return new $ec($message, $code, $mode, $options, $userinfo);
547
        }
548
    }
549

    
550
    // }}}
551
    // {{{ throwError()
552

    
553
    /**
554
     * Simpler form of raiseError with fewer options.  In most cases
555
     * message, code and userinfo are enough.
556
     *
557
     * @param string $message
558
     *
559
     */
560
    function throwError($message = null,
561
                         $code = null,
562
                         $userinfo = null)
563
    {
564
        if (isset($this) && is_a($this, 'PEAR')) {
565
            return $this->raiseError($message, $code, null, null, $userinfo);
566
        } else {
567
            return PEAR::raiseError($message, $code, null, null, $userinfo);
568
        }
569
    }
570

    
571
    // }}}
572
    function staticPushErrorHandling($mode, $options = null)
573
    {
574
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
575
        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
576
        $def_options = &$GLOBALS['_PEAR_default_error_options'];
577
        $stack[] = array($def_mode, $def_options);
578
        switch ($mode) {
579
            case PEAR_ERROR_EXCEPTION:
580
            case PEAR_ERROR_RETURN:
581
            case PEAR_ERROR_PRINT:
582
            case PEAR_ERROR_TRIGGER:
583
            case PEAR_ERROR_DIE:
584
            case null:
585
                $def_mode = $mode;
586
                $def_options = $options;
587
                break;
588

    
589
            case PEAR_ERROR_CALLBACK:
590
                $def_mode = $mode;
591
                // class/object method callback
592
                if (is_callable($options)) {
593
                    $def_options = $options;
594
                } else {
595
                    trigger_error("invalid error callback", E_USER_WARNING);
596
                }
597
                break;
598

    
599
            default:
600
                trigger_error("invalid error mode", E_USER_WARNING);
601
                break;
602
        }
603
        $stack[] = array($mode, $options);
604
        return true;
605
    }
606

    
607
    function staticPopErrorHandling()
608
    {
609
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
610
        $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
611
        $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
612
        array_pop($stack);
613
        list($mode, $options) = $stack[sizeof($stack) - 1];
614
        array_pop($stack);
615
        switch ($mode) {
616
            case PEAR_ERROR_EXCEPTION:
617
            case PEAR_ERROR_RETURN:
618
            case PEAR_ERROR_PRINT:
619
            case PEAR_ERROR_TRIGGER:
620
            case PEAR_ERROR_DIE:
621
            case null:
622
                $setmode = $mode;
623
                $setoptions = $options;
624
                break;
625

    
626
            case PEAR_ERROR_CALLBACK:
627
                $setmode = $mode;
628
                // class/object method callback
629
                if (is_callable($options)) {
630
                    $setoptions = $options;
631
                } else {
632
                    trigger_error("invalid error callback", E_USER_WARNING);
633
                }
634
                break;
635

    
636
            default:
637
                trigger_error("invalid error mode", E_USER_WARNING);
638
                break;
639
        }
640
        return true;
641
    }
642

    
643
    // {{{ pushErrorHandling()
644

    
645
    /**
646
     * Push a new error handler on top of the error handler options stack. With this
647
     * you can easily override the actual error handler for some code and restore
648
     * it later with popErrorHandling.
649
     *
650
     * @param mixed $mode (same as setErrorHandling)
651
     * @param mixed $options (same as setErrorHandling)
652
     *
653
     * @return bool Always true
654
     *
655
     * @see PEAR::setErrorHandling
656
     */
657
    function pushErrorHandling($mode, $options = null)
658
    {
659
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
660
        if (isset($this) && is_a($this, 'PEAR')) {
661
            $def_mode    = &$this->_default_error_mode;
662
            $def_options = &$this->_default_error_options;
663
        } else {
664
            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
665
            $def_options = &$GLOBALS['_PEAR_default_error_options'];
666
        }
667
        $stack[] = array($def_mode, $def_options);
668

    
669
        if (isset($this) && is_a($this, 'PEAR')) {
670
            $this->setErrorHandling($mode, $options);
671
        } else {
672
            PEAR::setErrorHandling($mode, $options);
673
        }
674
        $stack[] = array($mode, $options);
675
        return true;
676
    }
677

    
678
    // }}}
679
    // {{{ popErrorHandling()
680

    
681
    /**
682
    * Pop the last error handler used
683
    *
684
    * @return bool Always true
685
    *
686
    * @see PEAR::pushErrorHandling
687
    */
688
    function popErrorHandling()
689
    {
690
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
691
        array_pop($stack);
692
        list($mode, $options) = $stack[sizeof($stack) - 1];
693
        array_pop($stack);
694
        if (isset($this) && is_a($this, 'PEAR')) {
695
            $this->setErrorHandling($mode, $options);
696
        } else {
697
            PEAR::setErrorHandling($mode, $options);
698
        }
699
        return true;
700
    }
701

    
702
    // }}}
703
    // {{{ loadExtension()
704

    
705
    /**
706
    * OS independant PHP extension load. Remember to take care
707
    * on the correct extension name for case sensitive OSes.
708
    *
709
    * @param string $ext The extension name
710
    * @return bool Success or not on the dl() call
711
    */
712
    function loadExtension($ext)
713
    {
714
        if (!extension_loaded($ext)) {
715
            // if either returns true dl() will produce a FATAL error, stop that
716
            if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
717
                return false;
718
            }
719
            if (OS_WINDOWS) {
720
                $suffix = '.dll';
721
            } elseif (PHP_OS == 'HP-UX') {
722
                $suffix = '.sl';
723
            } elseif (PHP_OS == 'AIX') {
724
                $suffix = '.a';
725
            } elseif (PHP_OS == 'OSX') {
726
                $suffix = '.bundle';
727
            } else {
728
                $suffix = '.so';
729
            }
730
            return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
731
        }
732
        return true;
733
    }
734

    
735
    // }}}
736
}
737

    
738
// {{{ _PEAR_call_destructors()
739

    
740
function _PEAR_call_destructors()
741
{
742
    global $_PEAR_destructor_object_list;
743
    if (is_array($_PEAR_destructor_object_list) &&
744
        sizeof($_PEAR_destructor_object_list))
745
    {
746
        reset($_PEAR_destructor_object_list);
747
        if (@PEAR::getStaticProperty('PEAR', 'destructlifo')) {
748
            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
749
        }
750
        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
751
            $classname = get_class($objref);
752
            while ($classname) {
753
                $destructor = "_$classname";
754
                if (method_exists($objref, $destructor)) {
755
                    $objref->$destructor();
756
                    break;
757
                } else {
758
                    $classname = get_parent_class($classname);
759
                }
760
            }
761
        }
762
        // Empty the object list to ensure that destructors are
763
        // not called more than once.
764
        $_PEAR_destructor_object_list = array();
765
    }
766

    
767
    // Now call the shutdown functions
768
    if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
769
        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
770
            call_user_func_array($value[0], $value[1]);
771
        }
772
    }
773
}
774

    
775
// }}}
776

    
777
class PEAR_Error
778
{
779
    // {{{ properties
780

    
781
    var $error_message_prefix = '';
782
    var $mode                 = PEAR_ERROR_RETURN;
783
    var $level                = E_USER_NOTICE;
784
    var $code                 = -1;
785
    var $message              = '';
786
    var $userinfo             = '';
787
    var $backtrace            = null;
788

    
789
    // }}}
790
    // {{{ constructor
791

    
792
    /**
793
     * PEAR_Error constructor
794
     *
795
     * @param string $message  message
796
     *
797
     * @param int $code     (optional) error code
798
     *
799
     * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,
800
     * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
801
     * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
802
     *
803
     * @param mixed $options   (optional) error level, _OR_ in the case of
804
     * PEAR_ERROR_CALLBACK, the callback function or object/method
805
     * tuple.
806
     *
807
     * @param string $userinfo (optional) additional user/debug info
808
     *
809
     * @access public
810
     *
811
     */
812
    function PEAR_Error($message = 'unknown error', $code = null,
813
                        $mode = null, $options = null, $userinfo = null)
814
    {
815
        if ($mode === null) {
816
            $mode = PEAR_ERROR_RETURN;
817
        }
818
        $this->message   = $message;
819
        $this->code      = $code;
820
        $this->mode      = $mode;
821
        $this->userinfo  = $userinfo;
822
        if (function_exists("debug_backtrace")) {
823
            if (@!PEAR::getStaticProperty('PEAR_Error', 'skiptrace')) {
824
                $this->backtrace = debug_backtrace();
825
            }
826
        }
827
        if ($mode & PEAR_ERROR_CALLBACK) {
828
            $this->level = E_USER_NOTICE;
829
            $this->callback = $options;
830
        } else {
831
            if ($options === null) {
832
                $options = E_USER_NOTICE;
833
            }
834
            $this->level = $options;
835
            $this->callback = null;
836
        }
837
        if ($this->mode & PEAR_ERROR_PRINT) {
838
            if (is_null($options) || is_int($options)) {
839
                $format = "%s";
840
            } else {
841
                $format = $options;
842
            }
843
            printf($format, $this->getMessage());
844
        }
845
        if ($this->mode & PEAR_ERROR_TRIGGER) {
846
            trigger_error($this->getMessage(), $this->level);
847
        }
848
        if ($this->mode & PEAR_ERROR_DIE) {
849
            $msg = $this->getMessage();
850
            if (is_null($options) || is_int($options)) {
851
                $format = "%s";
852
                if (substr($msg, -1) != "\n") {
853
                    $msg .= "\n";
854
                }
855
            } else {
856
                $format = $options;
857
            }
858
            die(sprintf($format, $msg));
859
        }
860
        if ($this->mode & PEAR_ERROR_CALLBACK) {
861
            if (is_callable($this->callback)) {
862
                call_user_func($this->callback, $this);
863
            }
864
        }
865
        if ($this->mode & PEAR_ERROR_EXCEPTION) {
866
            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_ErrorStack for exceptions", E_USER_WARNING);
867
            eval('$e = new Exception($this->message, $this->code);$e->PEAR_Error = $this;throw($e);');
868
        }
869
    }
870

    
871
    // }}}
872
    // {{{ getMode()
873

    
874
    /**
875
     * Get the error mode from an error object.
876
     *
877
     * @return int error mode
878
     * @access public
879
     */
880
    function getMode() {
881
        return $this->mode;
882
    }
883

    
884
    // }}}
885
    // {{{ getCallback()
886

    
887
    /**
888
     * Get the callback function/method from an error object.
889
     *
890
     * @return mixed callback function or object/method array
891
     * @access public
892
     */
893
    function getCallback() {
894
        return $this->callback;
895
    }
896

    
897
    // }}}
898
    // {{{ getMessage()
899

    
900

    
901
    /**
902
     * Get the error message from an error object.
903
     *
904
     * @return  string  full error message
905
     * @access public
906
     */
907
    function getMessage()
908
    {
909
        return ($this->error_message_prefix . $this->message);
910
    }
911

    
912

    
913
    // }}}
914
    // {{{ getCode()
915

    
916
    /**
917
     * Get error code from an error object
918
     *
919
     * @return int error code
920
     * @access public
921
     */
922
     function getCode()
923
     {
924
        return $this->code;
925
     }
926

    
927
    // }}}
928
    // {{{ getType()
929

    
930
    /**
931
     * Get the name of this error/exception.
932
     *
933
     * @return string error/exception name (type)
934
     * @access public
935
     */
936
    function getType()
937
    {
938
        return get_class($this);
939
    }
940

    
941
    // }}}
942
    // {{{ getUserInfo()
943

    
944
    /**
945
     * Get additional user-supplied information.
946
     *
947
     * @return string user-supplied information
948
     * @access public
949
     */
950
    function getUserInfo()
951
    {
952
        return $this->userinfo;
953
    }
954

    
955
    // }}}
956
    // {{{ getDebugInfo()
957

    
958
    /**
959
     * Get additional debug information supplied by the application.
960
     *
961
     * @return string debug information
962
     * @access public
963
     */
964
    function getDebugInfo()
965
    {
966
        return $this->getUserInfo();
967
    }
968

    
969
    // }}}
970
    // {{{ getBacktrace()
971

    
972
    /**
973
     * Get the call backtrace from where the error was generated.
974
     * Supported with PHP 4.3.0 or newer.
975
     *
976
     * @param int $frame (optional) what frame to fetch
977
     * @return array Backtrace, or NULL if not available.
978
     * @access public
979
     */
980
    function getBacktrace($frame = null)
981
    {
982
        if ($frame === null) {
983
            return $this->backtrace;
984
        }
985
        return $this->backtrace[$frame];
986
    }
987

    
988
    // }}}
989
    // {{{ addUserInfo()
990

    
991
    function addUserInfo($info)
992
    {
993
        if (empty($this->userinfo)) {
994
            $this->userinfo = $info;
995
        } else {
996
            $this->userinfo .= " ** $info";
997
        }
998
    }
999

    
1000
    // }}}
1001
    // {{{ toString()
1002

    
1003
    /**
1004
     * Make a string representation of this object.
1005
     *
1006
     * @return string a string with an object summary
1007
     * @access public
1008
     */
1009
    function toString() {
1010
        $modes = array();
1011
        $levels = array(E_USER_NOTICE  => 'notice',
1012
                        E_USER_WARNING => 'warning',
1013
                        E_USER_ERROR   => 'error');
1014
        if ($this->mode & PEAR_ERROR_CALLBACK) {
1015
            if (is_array($this->callback)) {
1016
                $callback = (is_object($this->callback[0]) ?
1017
                    strtolower(get_class($this->callback[0])) :
1018
                    $this->callback[0]) . '::' .
1019
                    $this->callback[1];
1020
            } else {
1021
                $callback = $this->callback;
1022
            }
1023
            return sprintf('[%s: message="%s" code=%d mode=callback '.
1024
                           'callback=%s prefix="%s" info="%s"]',
1025
                           strtolower(get_class($this)), $this->message, $this->code,
1026
                           $callback, $this->error_message_prefix,
1027
                           $this->userinfo);
1028
        }
1029
        if ($this->mode & PEAR_ERROR_PRINT) {
1030
            $modes[] = 'print';
1031
        }
1032
        if ($this->mode & PEAR_ERROR_TRIGGER) {
1033
            $modes[] = 'trigger';
1034
        }
1035
        if ($this->mode & PEAR_ERROR_DIE) {
1036
            $modes[] = 'die';
1037
        }
1038
        if ($this->mode & PEAR_ERROR_RETURN) {
1039
            $modes[] = 'return';
1040
        }
1041
        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
1042
                       'prefix="%s" info="%s"]',
1043
                       strtolower(get_class($this)), $this->message, $this->code,
1044
                       implode("|", $modes), $levels[$this->level],
1045
                       $this->error_message_prefix,
1046
                       $this->userinfo);
1047
    }
1048

    
1049
    // }}}
1050
}
1051

    
1052
/*
1053
 * Local Variables:
1054
 * mode: php
1055
 * tab-width: 4
1056
 * c-basic-offset: 4
1057
 * End:
1058
 */
1059

    
1060
?>
(2-2/54)