Projet

Général

Profil

Télécharger (34,4 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / PEAR.inc @ c650b2f7

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: @package_version@
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 PEAR($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
     * Destructor (the emulated type of...).  Does nothing right now,
178
     * but is included for forward compatibility, so subclass
179
     * destructors should always call it.
180
     *
181
     * See the note in the class desciption about output from
182
     * destructors.
183
     *
184
     * @access public
185
     * @return void
186
     */
187
    function _PEAR() {
188
        if ($this->_debug) {
189
            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
190
        }
191
    }
192

    
193
    /**
194
    * If you have a class that's mostly/entirely static, and you need static
195
    * properties, you can use this method to simulate them. Eg. in your method(s)
196
    * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
197
    * You MUST use a reference, or they will not persist!
198
    *
199
    * @access public
200
    * @param  string $class  The calling classname, to prevent clashes
201
    * @param  string $var    The variable to retrieve.
202
    * @return mixed   A reference to the variable. If not set it will be
203
    *                 auto initialised to NULL.
204
    */
205
    function &getStaticProperty($class, $var)
206
    {
207
        static $properties;
208
        if (!isset($properties[$class])) {
209
            $properties[$class] = array();
210
        }
211

    
212
        if (!array_key_exists($var, $properties[$class])) {
213
            $properties[$class][$var] = null;
214
        }
215

    
216
        return $properties[$class][$var];
217
    }
218

    
219
    /**
220
    * Use this function to register a shutdown method for static
221
    * classes.
222
    *
223
    * @access public
224
    * @param  mixed $func  The function name (or array of class/method) to call
225
    * @param  mixed $args  The arguments to pass to the function
226
    * @return void
227
    */
228
    function registerShutdownFunc($func, $args = array())
229
    {
230
        // if we are called statically, there is a potential
231
        // that no shutdown func is registered.  Bug #6445
232
        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
233
            register_shutdown_function("_PEAR_call_destructors");
234
            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
235
        }
236
        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
237
    }
238

    
239
    /**
240
     * Tell whether a value is a PEAR error.
241
     *
242
     * @param   mixed $data   the value to test
243
     * @param   int   $code   if $data is an error object, return true
244
     *                        only if $code is a string and
245
     *                        $obj->getMessage() == $code or
246
     *                        $code is an integer and $obj->getCode() == $code
247
     * @access  public
248
     * @return  bool    true if parameter is an error
249
     */
250
    function isError($data, $code = null)
251
    {
252
        if (!is_object($data)) {
253
             return false;
254
        }
255
        if (!is_a($data, 'PEAR_Error')) {
256
            return false;
257
        }
258

    
259
        if (is_null($code)) {
260
            return true;
261
        } elseif (is_string($code)) {
262
            return $data->getMessage() == $code;
263
        }
264

    
265
        return $data->getCode() == $code;
266
    }
267

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

    
316
        switch ($mode) {
317
            case PEAR_ERROR_EXCEPTION:
318
            case PEAR_ERROR_RETURN:
319
            case PEAR_ERROR_PRINT:
320
            case PEAR_ERROR_TRIGGER:
321
            case PEAR_ERROR_DIE:
322
            case null:
323
                $setmode = $mode;
324
                $setoptions = $options;
325
                break;
326

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

    
337
            default:
338
                trigger_error("invalid error mode", E_USER_WARNING);
339
                break;
340
        }
341
    }
342

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

    
368
    /**
369
     * This method pops one element off the expected error codes
370
     * stack.
371
     *
372
     * @return array   the list of error codes that were popped
373
     */
374
    function popExpect()
375
    {
376
        return array_pop($this->_expected_errors);
377
    }
378

    
379
    /**
380
     * This method checks unsets an error code if available
381
     *
382
     * @param mixed error code
383
     * @return bool true if the error code was unset, false otherwise
384
     * @access private
385
     * @since PHP 4.3.0
386
     */
387
    function _checkDelExpect($error_code)
388
    {
389
        $deleted = false;
390
        foreach ($this->_expected_errors as $key => $error_array) {
391
            if (in_array($error_code, $error_array)) {
392
                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
393
                $deleted = true;
394
            }
395

    
396
            // clean up empty arrays
397
            if (0 == count($this->_expected_errors[$key])) {
398
                unset($this->_expected_errors[$key]);
399
            }
400
        }
401

    
402
        return $deleted;
403
    }
404

    
405
    /**
406
     * This method deletes all occurences of the specified element from
407
     * the expected error codes stack.
408
     *
409
     * @param  mixed $error_code error code that should be deleted
410
     * @return mixed list of error codes that were deleted or error
411
     * @access public
412
     * @since PHP 4.3.0
413
     */
414
    function delExpect($error_code)
415
    {
416
        $deleted = false;
417
        if ((is_array($error_code) && (0 != count($error_code)))) {
418
            // $error_code is a non-empty array here; we walk through it trying
419
            // to unset all values
420
            foreach ($error_code as $key => $error) {
421
                $deleted =  $this->_checkDelExpect($error) ? true : false;
422
            }
423

    
424
            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
425
        } elseif (!empty($error_code)) {
426
            // $error_code comes alone, trying to unset it
427
            if ($this->_checkDelExpect($error_code)) {
428
                return true;
429
            }
430

    
431
            return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
432
        }
433

    
434
        // $error_code is empty
435
        return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
436
    }
437

    
438
    /**
439
     * This method is a wrapper that returns an instance of the
440
     * configured error class with this object's default error
441
     * handling applied.  If the $mode and $options parameters are not
442
     * specified, the object's defaults are used.
443
     *
444
     * @param mixed $message a text error message or a PEAR error object
445
     *
446
     * @param int $code      a numeric error code (it is up to your class
447
     *                  to define these if you want to use codes)
448
     *
449
     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
450
     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
451
     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
452
     *
453
     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
454
     *                  specifies the PHP-internal error level (one of
455
     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
456
     *                  If $mode is PEAR_ERROR_CALLBACK, this
457
     *                  parameter specifies the callback function or
458
     *                  method.  In other error modes this parameter
459
     *                  is ignored.
460
     *
461
     * @param string $userinfo If you need to pass along for example debug
462
     *                  information, this parameter is meant for that.
463
     *
464
     * @param string $error_class The returned error object will be
465
     *                  instantiated from this class, if specified.
466
     *
467
     * @param bool $skipmsg If true, raiseError will only pass error codes,
468
     *                  the error message parameter will be dropped.
469
     *
470
     * @access public
471
     * @return object   a PEAR error object
472
     * @see PEAR::setErrorHandling
473
     * @since PHP 4.0.5
474
     */
475
    function &raiseError($message = null,
476
                         $code = null,
477
                         $mode = null,
478
                         $options = null,
479
                         $userinfo = null,
480
                         $error_class = null,
481
                         $skipmsg = false)
482
    {
483
        // The error is yet a PEAR error object
484
        if (is_object($message)) {
485
            $code        = $message->getCode();
486
            $userinfo    = $message->getUserInfo();
487
            $error_class = $message->getType();
488
            $message->error_message_prefix = '';
489
            $message     = $message->getMessage();
490

    
491
            // Make sure right data gets passed.
492
            $r = new ReflectionClass($error_class);
493
            $c = $r->getConstructor();
494
            $p = array_shift($c->getParameters());
495
            $skipmsg = ($p->getName() != 'message');
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 (intval(PHP_VERSION) < 5) {
534
            // little non-eval hack to fix bug #12147
535
            include 'PEAR/FixPHP5PEARWarnings.php';
536
            return $a;
537
        }
538

    
539
        if ($skipmsg) {
540
            $a = new $ec($code, $mode, $options, $userinfo);
541
        } else {
542
            $a = new $ec($message, $code, $mode, $options, $userinfo);
543
        }
544

    
545
        return $a;
546
    }
547

    
548
    /**
549
     * Simpler form of raiseError with fewer options.  In most cases
550
     * message, code and userinfo are enough.
551
     *
552
     * @param mixed $message a text error message or a PEAR error object
553
     *
554
     * @param int $code      a numeric error code (it is up to your class
555
     *                  to define these if you want to use codes)
556
     *
557
     * @param string $userinfo If you need to pass along for example debug
558
     *                  information, this parameter is meant for that.
559
     *
560
     * @access public
561
     * @return object   a PEAR error object
562
     * @see PEAR::raiseError
563
     */
564
    function &throwError($message = null, $code = null, $userinfo = null)
565
    {
566
        if (isset($this) && is_a($this, 'PEAR')) {
567
            $a = &$this->raiseError($message, $code, null, null, $userinfo);
568
            return $a;
569
        }
570

    
571
        $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
572
        return $a;
573
    }
574

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

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

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

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

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

    
639
            default:
640
                trigger_error("invalid error mode", E_USER_WARNING);
641
                break;
642
        }
643
        return true;
644
    }
645

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

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

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

    
700
    /**
701
    * OS independant PHP extension load. Remember to take care
702
    * on the correct extension name for case sensitive OSes.
703
    *
704
    * @param string $ext The extension name
705
    * @return bool Success or not on the dl() call
706
    */
707
    function loadExtension($ext)
708
    {
709
        if (extension_loaded($ext)) {
710
            return true;
711
        }
712

    
713
        // if either returns true dl() will produce a FATAL error, stop that
714
        if (
715
            function_exists('dl') === false ||
716
            ini_get('enable_dl') != 1 ||
717
            ini_get('safe_mode') == 1
718
        ) {
719
            return false;
720
        }
721

    
722
        if (OS_WINDOWS) {
723
            $suffix = '.dll';
724
        } elseif (PHP_OS == 'HP-UX') {
725
            $suffix = '.sl';
726
        } elseif (PHP_OS == 'AIX') {
727
            $suffix = '.a';
728
        } elseif (PHP_OS == 'OSX') {
729
            $suffix = '.bundle';
730
        } else {
731
            $suffix = '.so';
732
        }
733

    
734
        return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
735
    }
736
}
737

    
738
if (PEAR_ZE2) {
739
    /**
740
	 * This is only meant for PHP 5 to get rid of certain strict warning
741
	 * that doesn't get hidden since it's in the shutdown function
742
	 */
743
	class PEAR5
744
	{
745
		/**
746
		* If you have a class that's mostly/entirely static, and you need static
747
		* properties, you can use this method to simulate them. Eg. in your method(s)
748
		* do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar');
749
		* You MUST use a reference, or they will not persist!
750
		*
751
		* @access public
752
		* @param  string $class  The calling classname, to prevent clashes
753
		* @param  string $var    The variable to retrieve.
754
		* @return mixed   A reference to the variable. If not set it will be
755
		*                 auto initialised to NULL.
756
		*/
757
		static function &getStaticProperty($class, $var)
758
		{
759
			static $properties;
760
			if (!isset($properties[$class])) {
761
				$properties[$class] = array();
762
			}
763

    
764
			if (!array_key_exists($var, $properties[$class])) {
765
				$properties[$class][$var] = null;
766
			}
767

    
768
			return $properties[$class][$var];
769
		}
770
	}
771
}
772

    
773
function _PEAR_call_destructors()
774
{
775
    global $_PEAR_destructor_object_list;
776
    if (is_array($_PEAR_destructor_object_list) &&
777
        sizeof($_PEAR_destructor_object_list))
778
    {
779
        reset($_PEAR_destructor_object_list);
780
        if (PEAR_ZE2) {
781
            $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
782
        } else {
783
            $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
784
        }
785

    
786
        if ($destructLifoExists) {
787
            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
788
        }
789

    
790
        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
791
            $classname = get_class($objref);
792
            while ($classname) {
793
                $destructor = "_$classname";
794
                if (method_exists($objref, $destructor)) {
795
                    $objref->$destructor();
796
                    break;
797
                } else {
798
                    $classname = get_parent_class($classname);
799
                }
800
            }
801
        }
802
        // Empty the object list to ensure that destructors are
803
        // not called more than once.
804
        $_PEAR_destructor_object_list = array();
805
    }
806

    
807
    // Now call the shutdown functions
808
    if (
809
        isset($GLOBALS['_PEAR_shutdown_funcs']) &&
810
        is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
811
        !empty($GLOBALS['_PEAR_shutdown_funcs'])
812
    ) {
813
        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
814
            call_user_func_array($value[0], $value[1]);
815
        }
816
    }
817
}
818

    
819
/**
820
 * Standard PEAR error class for PHP 4
821
 *
822
 * This class is supserseded by {@link PEAR_Exception} in PHP 5
823
 *
824
 * @category   pear
825
 * @package    PEAR
826
 * @author     Stig Bakken <ssb@php.net>
827
 * @author     Tomas V.V. Cox <cox@idecnet.com>
828
 * @author     Gregory Beaver <cellog@php.net>
829
 * @copyright  1997-2006 The PHP Group
830
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
831
 * @version    Release: @package_version@
832
 * @link       http://pear.php.net/manual/en/core.pear.pear-error.php
833
 * @see        PEAR::raiseError(), PEAR::throwError()
834
 * @since      Class available since PHP 4.0.2
835
 */
836
class PEAR_Error
837
{
838
    var $error_message_prefix = '';
839
    var $mode                 = PEAR_ERROR_RETURN;
840
    var $level                = E_USER_NOTICE;
841
    var $code                 = -1;
842
    var $message              = '';
843
    var $userinfo             = '';
844
    var $backtrace            = null;
845

    
846
    /**
847
     * PEAR_Error constructor
848
     *
849
     * @param string $message  message
850
     *
851
     * @param int $code     (optional) error code
852
     *
853
     * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,
854
     * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
855
     * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
856
     *
857
     * @param mixed $options   (optional) error level, _OR_ in the case of
858
     * PEAR_ERROR_CALLBACK, the callback function or object/method
859
     * tuple.
860
     *
861
     * @param string $userinfo (optional) additional user/debug info
862
     *
863
     * @access public
864
     *
865
     */
866
    function PEAR_Error($message = 'unknown error', $code = null,
867
                        $mode = null, $options = null, $userinfo = null)
868
    {
869
        if ($mode === null) {
870
            $mode = PEAR_ERROR_RETURN;
871
        }
872
        $this->message   = $message;
873
        $this->code      = $code;
874
        $this->mode      = $mode;
875
        $this->userinfo  = $userinfo;
876

    
877
        if (PEAR_ZE2) {
878
            $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
879
        } else {
880
            $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
881
        }
882

    
883
        if (!$skiptrace) {
884
            $this->backtrace = debug_backtrace();
885
            if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
886
                unset($this->backtrace[0]['object']);
887
            }
888
        }
889

    
890
        if ($mode & PEAR_ERROR_CALLBACK) {
891
            $this->level = E_USER_NOTICE;
892
            $this->callback = $options;
893
        } else {
894
            if ($options === null) {
895
                $options = E_USER_NOTICE;
896
            }
897

    
898
            $this->level = $options;
899
            $this->callback = null;
900
        }
901

    
902
        if ($this->mode & PEAR_ERROR_PRINT) {
903
            if (is_null($options) || is_int($options)) {
904
                $format = "%s";
905
            } else {
906
                $format = $options;
907
            }
908

    
909
            printf($format, $this->getMessage());
910
        }
911

    
912
        if ($this->mode & PEAR_ERROR_TRIGGER) {
913
            trigger_error($this->getMessage(), $this->level);
914
        }
915

    
916
        if ($this->mode & PEAR_ERROR_DIE) {
917
            $msg = $this->getMessage();
918
            if (is_null($options) || is_int($options)) {
919
                $format = "%s";
920
                if (substr($msg, -1) != "\n") {
921
                    $msg .= "\n";
922
                }
923
            } else {
924
                $format = $options;
925
            }
926
            die(sprintf($format, $msg));
927
        }
928

    
929
        if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
930
            call_user_func($this->callback, $this);
931
        }
932

    
933
        if ($this->mode & PEAR_ERROR_EXCEPTION) {
934
            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
935
            eval('$e = new Exception($this->message, $this->code);throw($e);');
936
        }
937
    }
938

    
939
    /**
940
     * Get the error mode from an error object.
941
     *
942
     * @return int error mode
943
     * @access public
944
     */
945
    function getMode()
946
    {
947
        return $this->mode;
948
    }
949

    
950
    /**
951
     * Get the callback function/method from an error object.
952
     *
953
     * @return mixed callback function or object/method array
954
     * @access public
955
     */
956
    function getCallback()
957
    {
958
        return $this->callback;
959
    }
960

    
961
    /**
962
     * Get the error message from an error object.
963
     *
964
     * @return  string  full error message
965
     * @access public
966
     */
967
    function getMessage()
968
    {
969
        return ($this->error_message_prefix . $this->message);
970
    }
971

    
972
    /**
973
     * Get error code from an error object
974
     *
975
     * @return int error code
976
     * @access public
977
     */
978
     function getCode()
979
     {
980
        return $this->code;
981
     }
982

    
983
    /**
984
     * Get the name of this error/exception.
985
     *
986
     * @return string error/exception name (type)
987
     * @access public
988
     */
989
    function getType()
990
    {
991
        return get_class($this);
992
    }
993

    
994
    /**
995
     * Get additional user-supplied information.
996
     *
997
     * @return string user-supplied information
998
     * @access public
999
     */
1000
    function getUserInfo()
1001
    {
1002
        return $this->userinfo;
1003
    }
1004

    
1005
    /**
1006
     * Get additional debug information supplied by the application.
1007
     *
1008
     * @return string debug information
1009
     * @access public
1010
     */
1011
    function getDebugInfo()
1012
    {
1013
        return $this->getUserInfo();
1014
    }
1015

    
1016
    /**
1017
     * Get the call backtrace from where the error was generated.
1018
     * Supported with PHP 4.3.0 or newer.
1019
     *
1020
     * @param int $frame (optional) what frame to fetch
1021
     * @return array Backtrace, or NULL if not available.
1022
     * @access public
1023
     */
1024
    function getBacktrace($frame = null)
1025
    {
1026
        if (defined('PEAR_IGNORE_BACKTRACE')) {
1027
            return null;
1028
        }
1029
        if ($frame === null) {
1030
            return $this->backtrace;
1031
        }
1032
        return $this->backtrace[$frame];
1033
    }
1034

    
1035
    function addUserInfo($info)
1036
    {
1037
        if (empty($this->userinfo)) {
1038
            $this->userinfo = $info;
1039
        } else {
1040
            $this->userinfo .= " ** $info";
1041
        }
1042
    }
1043

    
1044
    function __toString()
1045
    {
1046
        return $this->getMessage();
1047
    }
1048

    
1049
    /**
1050
     * Make a string representation of this object.
1051
     *
1052
     * @return string a string with an object summary
1053
     * @access public
1054
     */
1055
    function toString()
1056
    {
1057
        $modes = array();
1058
        $levels = array(E_USER_NOTICE  => 'notice',
1059
                        E_USER_WARNING => 'warning',
1060
                        E_USER_ERROR   => 'error');
1061
        if ($this->mode & PEAR_ERROR_CALLBACK) {
1062
            if (is_array($this->callback)) {
1063
                $callback = (is_object($this->callback[0]) ?
1064
                    strtolower(get_class($this->callback[0])) :
1065
                    $this->callback[0]) . '::' .
1066
                    $this->callback[1];
1067
            } else {
1068
                $callback = $this->callback;
1069
            }
1070
            return sprintf('[%s: message="%s" code=%d mode=callback '.
1071
                           'callback=%s prefix="%s" info="%s"]',
1072
                           strtolower(get_class($this)), $this->message, $this->code,
1073
                           $callback, $this->error_message_prefix,
1074
                           $this->userinfo);
1075
        }
1076
        if ($this->mode & PEAR_ERROR_PRINT) {
1077
            $modes[] = 'print';
1078
        }
1079
        if ($this->mode & PEAR_ERROR_TRIGGER) {
1080
            $modes[] = 'trigger';
1081
        }
1082
        if ($this->mode & PEAR_ERROR_DIE) {
1083
            $modes[] = 'die';
1084
        }
1085
        if ($this->mode & PEAR_ERROR_RETURN) {
1086
            $modes[] = 'return';
1087
        }
1088
        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
1089
                       'prefix="%s" info="%s"]',
1090
                       strtolower(get_class($this)), $this->message, $this->code,
1091
                       implode("|", $modes), $levels[$this->level],
1092
                       $this->error_message_prefix,
1093
                       $this->userinfo);
1094
    }
1095
}
1096

    
1097
/*
1098
 * Local Variables:
1099
 * mode: php
1100
 * tab-width: 4
1101
 * c-basic-offset: 4
1102
 * End:
1103
 */
(3-3/68)