Completed
Push — 1.10.x ( 06fcbe...fb838b )
by
unknown
114:44 queued 66:54
created

PEAR::setErrorHandling()   C

Complexity

Conditions 11
Paths 18

Size

Total Lines 36
Code Lines 27

Duplication

Lines 32
Ratio 88.89 %

Importance

Changes 0
Metric Value
cc 11
eloc 27
nc 18
nop 2
dl 32
loc 36
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 <[email protected]>
12
 * @author     Stig Bakken <[email protected]>
13
 * @author     Tomas V.V.Cox <[email protected]>
14
 * @author     Greg Beaver <[email protected]>
15
 * @copyright  1997-2009 The Authors
16
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
17
 * @version    CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $
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 <[email protected]>
77
 * @author     Tomas V.V. Cox <[email protected]>
78
 * @author     Greg Beaver <[email protected]>
79
 * @copyright  1997-2006 The PHP Group
80
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
81
 * @version    Release: 1.9.0
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
    // {{{ properties
90
91
    /**
92
     * Whether to enable internal debug messages.
93
     *
94
     * @var     bool
95
     * @access  private
96
     */
97
    var $_debug = false;
98
99
    /**
100
     * Default error mode for this object.
101
     *
102
     * @var     int
103
     * @access  private
104
     */
105
    var $_default_error_mode = null;
106
107
    /**
108
     * Default error options used for this object when error mode
109
     * is PEAR_ERROR_TRIGGER.
110
     *
111
     * @var     int
112
     * @access  private
113
     */
114
    var $_default_error_options = null;
115
116
    /**
117
     * Default error handler (callback) for this object, if error mode is
118
     * PEAR_ERROR_CALLBACK.
119
     *
120
     * @var     string
121
     * @access  private
122
     */
123
    var $_default_error_handler = '';
124
125
    /**
126
     * Which class to use for error objects.
127
     *
128
     * @var     string
129
     * @access  private
130
     */
131
    var $_error_class = 'PEAR_Error';
132
133
    /**
134
     * An array of expected errors.
135
     *
136
     * @var     array
137
     * @access  private
138
     */
139
    var $_expected_errors = array();
140
141
    // }}}
142
143
    // {{{ constructor
144
145
    /**
146
     * Constructor.  Registers this object in
147
     * $_PEAR_destructor_object_list for destructor emulation if a
148
     * destructor object exists.
149
     *
150
     * @param string $error_class  (optional) which class to use for
151
     *        error objects, defaults to PEAR_Error.
152
     * @access public
153
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
154
     */
155
    public function __construct($error_class = null)
156
    {
157
        $classname = strtolower(get_class($this));
158
        if ($this->_debug) {
159
            print "PEAR constructor called, class=$classname\n";
160
        }
161
        if ($error_class !== null) {
162
            $this->_error_class = $error_class;
163
        }
164
        while ($classname && strcasecmp($classname, "pear")) {
165
            $destructor = "_$classname";
166
            if (method_exists($this, $destructor)) {
167
                global $_PEAR_destructor_object_list;
168
                $_PEAR_destructor_object_list[] = &$this;
169
                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
170
                    register_shutdown_function("_PEAR_call_destructors");
171
                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
172
                }
173
                break;
174
            } else {
175
                $classname = get_parent_class($classname);
176
            }
177
        }
178
    }
179
180
    // }}}
181
    // {{{ destructor
182
183
    /**
184
     * Destructor (the emulated type of...).  Does nothing right now,
185
     * but is included for forward compatibility, so subclass
186
     * destructors should always call it.
187
     *
188
     * See the note in the class desciption about output from
189
     * destructors.
190
     *
191
     * @access public
192
     * @return void
193
     */
194
    function _PEAR() {
195
        if ($this->_debug) {
196
            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
197
        }
198
    }
199
200
    // }}}
201
    // {{{ getStaticProperty()
202
203
    /**
204
    * If you have a class that's mostly/entirely static, and you need static
205
    * properties, you can use this method to simulate them. Eg. in your method(s)
206
    * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
207
    * You MUST use a reference, or they will not persist!
208
    *
209
    * @access public
210
    * @param  string $class  The calling classname, to prevent clashes
211
    * @param  string $var    The variable to retrieve.
212
    * @return mixed   A reference to the variable. If not set it will be
213
    *                 auto initialised to NULL.
214
    */
215 View Code Duplication
    function &getStaticProperty($class, $var)
216
    {
217
        static $properties;
218
        if (!isset($properties[$class])) {
219
            $properties[$class] = array();
220
        }
221
222
        if (!array_key_exists($var, $properties[$class])) {
223
            $properties[$class][$var] = null;
224
        }
225
226
        return $properties[$class][$var];
227
    }
228
229
    // }}}
230
    // {{{ registerShutdownFunc()
231
232
    /**
233
    * Use this function to register a shutdown method for static
234
    * classes.
235
    *
236
    * @access public
237
    * @param  mixed $func  The function name (or array of class/method) to call
238
    * @param  mixed $args  The arguments to pass to the function
239
    * @return void
240
    */
241
    function registerShutdownFunc($func, $args = array())
242
    {
243
        // if we are called statically, there is a potential
244
        // that no shutdown func is registered.  Bug #6445
245
        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
246
            register_shutdown_function("_PEAR_call_destructors");
247
            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
248
        }
249
        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
250
    }
251
252
    // }}}
253
    // {{{ isError()
254
255
    /**
256
     * Tell whether a value is a PEAR error.
257
     *
258
     * @param   mixed $data   the value to test
259
     * @param   int   $code   if $data is an error object, return true
260
     *                        only if $code is a string and
261
     *                        $obj->getMessage() == $code or
262
     *                        $code is an integer and $obj->getCode() == $code
263
     * @access  public
264
     * @return  bool    true if parameter is an error
265
     */
266
    static function isError($data, $code = null)
267
    {
268
        if (!is_a($data, 'PEAR_Error')) {
269
            return false;
270
        }
271
272
        if (is_null($code)) {
273
            return true;
274
        } elseif (is_string($code)) {
275
            return $data->getMessage() == $code;
276
        }
277
278
        return $data->getCode() == $code;
279
    }
280
281
    // }}}
282
    // {{{ setErrorHandling()
283
284
    /**
285
     * Sets how errors generated by this object should be handled.
286
     * Can be invoked both in objects and statically.  If called
287
     * statically, setErrorHandling sets the default behaviour for all
288
     * PEAR objects.  If called in an object, setErrorHandling sets
289
     * the default behaviour for that object.
290
     *
291
     * @param int $mode
292
     *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
293
     *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
294
     *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
295
     *
296
     * @param mixed $options
297
     *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
298
     *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
299
     *
300
     *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
301
     *        to be the callback function or method.  A callback
302
     *        function is a string with the name of the function, a
303
     *        callback method is an array of two elements: the element
304
     *        at index 0 is the object, and the element at index 1 is
305
     *        the name of the method to call in the object.
306
     *
307
     *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
308
     *        a printf format string used when printing the error
309
     *        message.
310
     *
311
     * @access public
312
     * @return void
313
     * @see PEAR_ERROR_RETURN
314
     * @see PEAR_ERROR_PRINT
315
     * @see PEAR_ERROR_TRIGGER
316
     * @see PEAR_ERROR_DIE
317
     * @see PEAR_ERROR_CALLBACK
318
     * @see PEAR_ERROR_EXCEPTION
319
     *
320
     * @since PHP 4.0.5
321
     */
322
323
    function setErrorHandling($mode = null, $options = null)
324
    {
325 View Code Duplication
        if (isset($this) && is_a($this, 'PEAR')) {
326
            $setmode     = &$this->_default_error_mode;
327
            $setoptions  = &$this->_default_error_options;
328
        } else {
329
            $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
330
            $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
331
        }
332
333 View Code Duplication
        switch ($mode) {
334
            case PEAR_ERROR_EXCEPTION:
0 ignored issues
show
Deprecated Code introduced by
The constant PEAR_ERROR_EXCEPTION has been deprecated.

This constant has been deprecated.

Loading history...
335
            case PEAR_ERROR_RETURN:
336
            case PEAR_ERROR_PRINT:
337
            case PEAR_ERROR_TRIGGER:
338
            case PEAR_ERROR_DIE:
339
            case null:
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $mode of type integer|null against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
340
                $setmode = $mode;
341
                $setoptions = $options;
342
                break;
343
344
            case PEAR_ERROR_CALLBACK:
345
                $setmode = $mode;
346
                // class/object method callback
347
                if (is_callable($options)) {
348
                    $setoptions = $options;
349
                } else {
350
                    trigger_error("invalid error callback", E_USER_WARNING);
351
                }
352
                break;
353
354
            default:
355
                trigger_error("invalid error mode", E_USER_WARNING);
356
                break;
357
        }
358
    }
359
360
    // }}}
361
    // {{{ expectError()
362
363
    /**
364
     * This method is used to tell which errors you expect to get.
365
     * Expected errors are always returned with error mode
366
     * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
367
     * and this method pushes a new element onto it.  The list of
368
     * expected errors are in effect until they are popped off the
369
     * stack with the popExpect() method.
370
     *
371
     * Note that this method can not be called statically
372
     *
373
     * @param mixed $code a single error code or an array of error codes to expect
374
     *
375
     * @return int     the new depth of the "expected errors" stack
376
     * @access public
377
     */
378
    function expectError($code = '*')
379
    {
380
        if (is_array($code)) {
381
            array_push($this->_expected_errors, $code);
382
        } else {
383
            array_push($this->_expected_errors, array($code));
384
        }
385
        return sizeof($this->_expected_errors);
386
    }
387
388
    // }}}
389
    // {{{ popExpect()
390
391
    /**
392
     * This method pops one element off the expected error codes
393
     * stack.
394
     *
395
     * @return array   the list of error codes that were popped
396
     */
397
    function popExpect()
398
    {
399
        return array_pop($this->_expected_errors);
400
    }
401
402
    // }}}
403
    // {{{ _checkDelExpect()
404
405
    /**
406
     * This method checks unsets an error code if available
407
     *
408
     * @param mixed error code
409
     * @return bool true if the error code was unset, false otherwise
410
     * @access private
411
     * @since PHP 4.3.0
412
     */
413
    function _checkDelExpect($error_code)
414
    {
415
        $deleted = false;
416
417
        foreach ($this->_expected_errors AS $key => $error_array) {
418
            if (in_array($error_code, $error_array)) {
419
                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
420
                $deleted = true;
421
            }
422
423
            // clean up empty arrays
424
            if (0 == count($this->_expected_errors[$key])) {
425
                unset($this->_expected_errors[$key]);
426
            }
427
        }
428
        return $deleted;
429
    }
430
431
    // }}}
432
    // {{{ delExpect()
433
434
    /**
435
     * This method deletes all occurences of the specified element from
436
     * the expected error codes stack.
437
     *
438
     * @param  mixed $error_code error code that should be deleted
439
     * @return mixed list of error codes that were deleted or error
440
     * @access public
441
     * @since PHP 4.3.0
442
     */
443
    function delExpect($error_code)
444
    {
445
        $deleted = false;
446
        if ((is_array($error_code) && (0 != count($error_code)))) {
447
            // $error_code is a non-empty array here;
448
            // we walk through it trying to unset all
449
            // values
450
            foreach($error_code as $key => $error) {
451
                if ($this->_checkDelExpect($error)) {
452
                    $deleted =  true;
453
                } else {
454
                    $deleted = false;
455
                }
456
            }
457
            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
458
        } elseif (!empty($error_code)) {
459
            // $error_code comes alone, trying to unset it
460
            if ($this->_checkDelExpect($error_code)) {
461
                return true;
462
            } else {
463
                return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
464
            }
465
        }
466
467
        // $error_code is empty
468
        return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
469
    }
470
471
    // }}}
472
    // {{{ raiseError()
473
474
    /**
475
     * This method is a wrapper that returns an instance of the
476
     * configured error class with this object's default error
477
     * handling applied.  If the $mode and $options parameters are not
478
     * specified, the object's defaults are used.
479
     *
480
     * @param mixed $message a text error message or a PEAR error object
481
     *
482
     * @param int $code      a numeric error code (it is up to your class
483
     *                  to define these if you want to use codes)
484
     *
485
     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
486
     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
487
     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
488
     *
489
     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
490
     *                  specifies the PHP-internal error level (one of
491
     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
492
     *                  If $mode is PEAR_ERROR_CALLBACK, this
493
     *                  parameter specifies the callback function or
494
     *                  method.  In other error modes this parameter
495
     *                  is ignored.
496
     *
497
     * @param string $userinfo If you need to pass along for example debug
498
     *                  information, this parameter is meant for that.
499
     *
500
     * @param string $error_class The returned error object will be
501
     *                  instantiated from this class, if specified.
502
     *
503
     * @param bool $skipmsg If true, raiseError will only pass error codes,
504
     *                  the error message parameter will be dropped.
505
     *
506
     * @access public
507
     * @return object   a PEAR error object
508
     * @see PEAR::setErrorHandling
509
     * @since PHP 4.0.5
510
     */
511
    function &raiseError($message = null,
512
                         $code = null,
513
                         $mode = null,
514
                         $options = null,
515
                         $userinfo = null,
516
                         $error_class = null,
517
                         $skipmsg = false)
518
    {
519
        // The error is yet a PEAR error object
520
        if (is_object($message)) {
521
            $code        = $message->getCode();
522
            $userinfo    = $message->getUserInfo();
523
            $error_class = $message->getType();
524
            $message->error_message_prefix = '';
525
            $message     = $message->getMessage();
526
        }
527
528
        if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) {
529
            if ($exp[0] == "*" ||
530
                (is_int(reset($exp)) && in_array($code, $exp)) ||
531
                (is_string(reset($exp)) && in_array($message, $exp))) {
532
                $mode = PEAR_ERROR_RETURN;
533
            }
534
        }
535
536
        // No mode given, try global ones
537
        if ($mode === null) {
538
            // Class error handler
539
            if (isset($this) && isset($this->_default_error_mode)) {
540
                $mode    = $this->_default_error_mode;
541
                $options = $this->_default_error_options;
542
            // Global error handler
543
            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
544
                $mode    = $GLOBALS['_PEAR_default_error_mode'];
545
                $options = $GLOBALS['_PEAR_default_error_options'];
546
            }
547
        }
548
549
        if ($error_class !== null) {
550
            $ec = $error_class;
551
        } elseif (isset($this) && isset($this->_error_class)) {
552
            $ec = $this->_error_class;
553
        } else {
554
            $ec = 'PEAR_Error';
555
        }
556
557
        if ($skipmsg) {
558
            $a = new $ec($code, $mode, $options, $userinfo);
559
        } else {
560
            $a = new $ec($message, $code, $mode, $options, $userinfo);
561
        }
562
563
        return $a;
564
    }
565
566
    // }}}
567
    // {{{ throwError()
568
569
    /**
570
     * Simpler form of raiseError with fewer options.  In most cases
571
     * message, code and userinfo are enough.
572
     *
573
     * @param string $message
574
     *
575
     */
576
    function &throwError($message = null,
577
                         $code = null,
578
                         $userinfo = null)
579
    {
580
        if (isset($this) && is_a($this, 'PEAR')) {
581
            $a = &$this->raiseError($message, $code, null, null, $userinfo);
582
            return $a;
583
        }
584
585
        $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
586
        return $a;
587
    }
588
589
    // }}}
590
    function staticPushErrorHandling($mode, $options = null)
591
    {
592
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
593
        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
594
        $def_options = &$GLOBALS['_PEAR_default_error_options'];
595
        $stack[] = array($def_mode, $def_options);
596 View Code Duplication
        switch ($mode) {
597
            case PEAR_ERROR_EXCEPTION:
0 ignored issues
show
Deprecated Code introduced by
The constant PEAR_ERROR_EXCEPTION has been deprecated.

This constant has been deprecated.

Loading history...
598
            case PEAR_ERROR_RETURN:
599
            case PEAR_ERROR_PRINT:
600
            case PEAR_ERROR_TRIGGER:
601
            case PEAR_ERROR_DIE:
602
            case null:
603
                $def_mode = $mode;
604
                $def_options = $options;
605
                break;
606
607
            case PEAR_ERROR_CALLBACK:
608
                $def_mode = $mode;
609
                // class/object method callback
610
                if (is_callable($options)) {
611
                    $def_options = $options;
612
                } else {
613
                    trigger_error("invalid error callback", E_USER_WARNING);
614
                }
615
                break;
616
617
            default:
618
                trigger_error("invalid error mode", E_USER_WARNING);
619
                break;
620
        }
621
        $stack[] = array($mode, $options);
622
        return true;
623
    }
624
625
    function staticPopErrorHandling()
626
    {
627
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
628
        $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
629
        $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
630
        array_pop($stack);
631
        list($mode, $options) = $stack[sizeof($stack) - 1];
632
        array_pop($stack);
633 View Code Duplication
        switch ($mode) {
634
            case PEAR_ERROR_EXCEPTION:
0 ignored issues
show
Deprecated Code introduced by
The constant PEAR_ERROR_EXCEPTION has been deprecated.

This constant has been deprecated.

Loading history...
635
            case PEAR_ERROR_RETURN:
636
            case PEAR_ERROR_PRINT:
637
            case PEAR_ERROR_TRIGGER:
638
            case PEAR_ERROR_DIE:
639
            case null:
640
                $setmode = $mode;
641
                $setoptions = $options;
642
                break;
643
644
            case PEAR_ERROR_CALLBACK:
645
                $setmode = $mode;
646
                // class/object method callback
647
                if (is_callable($options)) {
648
                    $setoptions = $options;
649
                } else {
650
                    trigger_error("invalid error callback", E_USER_WARNING);
651
                }
652
                break;
653
654
            default:
655
                trigger_error("invalid error mode", E_USER_WARNING);
656
                break;
657
        }
658
        return true;
659
    }
660
661
    // {{{ pushErrorHandling()
662
663
    /**
664
     * Push a new error handler on top of the error handler options stack. With this
665
     * you can easily override the actual error handler for some code and restore
666
     * it later with popErrorHandling.
667
     *
668
     * @param mixed $mode (same as setErrorHandling)
669
     * @param mixed $options (same as setErrorHandling)
670
     *
671
     * @return bool Always true
672
     *
673
     * @see PEAR::setErrorHandling
674
     */
675
    function pushErrorHandling($mode, $options = null)
676
    {
677
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
678 View Code Duplication
        if (isset($this) && is_a($this, 'PEAR')) {
679
            $def_mode    = &$this->_default_error_mode;
680
            $def_options = &$this->_default_error_options;
681
        } else {
682
            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
683
            $def_options = &$GLOBALS['_PEAR_default_error_options'];
684
        }
685
        $stack[] = array($def_mode, $def_options);
686
687 View Code Duplication
        if (isset($this) && is_a($this, 'PEAR')) {
688
            $this->setErrorHandling($mode, $options);
689
        } else {
690
            PEAR::setErrorHandling($mode, $options);
691
        }
692
        $stack[] = array($mode, $options);
693
        return true;
694
    }
695
696
    // }}}
697
    // {{{ popErrorHandling()
698
699
    /**
700
    * Pop the last error handler used
701
    *
702
    * @return bool Always true
703
    *
704
    * @see PEAR::pushErrorHandling
705
    */
706
    function popErrorHandling()
707
    {
708
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
709
        array_pop($stack);
710
        list($mode, $options) = $stack[sizeof($stack) - 1];
711
        array_pop($stack);
712 View Code Duplication
        if (isset($this) && is_a($this, 'PEAR')) {
713
            $this->setErrorHandling($mode, $options);
714
        } else {
715
            PEAR::setErrorHandling($mode, $options);
716
        }
717
        return true;
718
    }
719
720
    // }}}
721
    // {{{ loadExtension()
722
723
    /**
724
    * OS independant PHP extension load. Remember to take care
725
    * on the correct extension name for case sensitive OSes.
726
    *
727
    * @param string $ext The extension name
728
    * @return bool Success or not on the dl() call
729
    */
730
    function loadExtension($ext)
731
    {
732
        if (!extension_loaded($ext)) {
733
            // if either returns true dl() will produce a FATAL error, stop that
734
            if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) {
735
                return false;
736
            }
737
738
            if (OS_WINDOWS) {
739
                $suffix = '.dll';
740
            } elseif (PHP_OS == 'HP-UX') {
741
                $suffix = '.sl';
742
            } elseif (PHP_OS == 'AIX') {
743
                $suffix = '.a';
744
            } elseif (PHP_OS == 'OSX') {
745
                $suffix = '.bundle';
746
            } else {
747
                $suffix = '.so';
748
            }
749
750
            return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
751
        }
752
753
        return true;
754
    }
755
756
    // }}}
757
}
758
759
if (PEAR_ZE2) {
760
    include_once 'PEAR5.php';
761
}
762
763
// {{{ _PEAR_call_destructors()
764
765
// Added by Chamilo team, 16-MAR-2010
766
if (!function_exists('_PEAR_call_destructors')) {
767
//
768
function _PEAR_call_destructors()
769
{
770
    global $_PEAR_destructor_object_list;
771
    if (is_array($_PEAR_destructor_object_list) &&
772
        sizeof($_PEAR_destructor_object_list))
773
    {
774
        reset($_PEAR_destructor_object_list);
775
        if (PEAR_ZE2) {
776
            $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo');
777
        } else {
778
            $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
779
        }
780
781
        if ($destructLifoExists) {
782
            $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list);
783
        }
784
785
        while (list($k, $objref) = each($_PEAR_destructor_object_list)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $k is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
786
            $classname = get_class($objref);
787
            while ($classname) {
788
                $destructor = "_$classname";
789
                if (method_exists($objref, $destructor)) {
790
                    $objref->$destructor();
791
                    break;
792
                } else {
793
                    $classname = get_parent_class($classname);
794
                }
795
            }
796
        }
797
        // Empty the object list to ensure that destructors are
798
        // not called more than once.
799
        $_PEAR_destructor_object_list = array();
800
    }
801
802
    // Now call the shutdown functions
803
    if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
804
        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
805
            call_user_func_array($value[0], $value[1]);
806
        }
807
    }
808
}
809
//
810
}
811
//
812
813
// }}}
814
/**
815
 * Standard PEAR error class for PHP 4
816
 *
817
 * This class is supserseded by {@link PEAR_Exception} in PHP 5
818
 *
819
 * @category   pear
820
 * @package    PEAR
821
 * @author     Stig Bakken <[email protected]>
822
 * @author     Tomas V.V. Cox <[email protected]>
823
 * @author     Gregory Beaver <[email protected]>
824
 * @copyright  1997-2006 The PHP Group
825
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
826
 * @version    Release: 1.9.0
827
 * @link       http://pear.php.net/manual/en/core.pear.pear-error.php
828
 * @see        PEAR::raiseError(), PEAR::throwError()
829
 * @since      Class available since PHP 4.0.2
830
 */
831
class PEAR_Error
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
832
{
833
    // {{{ properties
834
835
    var $error_message_prefix = '';
836
    var $mode                 = PEAR_ERROR_RETURN;
837
    var $level                = E_USER_NOTICE;
838
    var $code                 = -1;
839
    var $message              = '';
840
    var $userinfo             = '';
841
    var $backtrace            = null;
842
843
    // }}}
844
    // {{{ constructor
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
    public function __constructor(
867
        $message = 'unknown error',
868
        $code = null,
869
        $mode = null,
870
        $options = null,
871
        $userinfo = null
872
    ) {
873
        if ($mode === null) {
874
            $mode = PEAR_ERROR_RETURN;
875
        }
876
        $this->message   = $message;
877
        $this->code      = $code;
878
        $this->mode      = $mode;
879
        $this->userinfo  = $userinfo;
880
881
        if (PEAR_ZE2) {
882
            $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace');
883
        } else {
884
            $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
885
        }
886
887
        if (!$skiptrace) {
888
            $this->backtrace = debug_backtrace();
889
            if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
890
                unset($this->backtrace[0]['object']);
891
            }
892
        }
893
894
        if ($mode & PEAR_ERROR_CALLBACK) {
895
            $this->level = E_USER_NOTICE;
896
            $this->callback = $options;
897
        } else {
898
            if ($options === null) {
899
                $options = E_USER_NOTICE;
900
            }
901
902
            $this->level = $options;
903
            $this->callback = null;
904
        }
905
906
        if ($this->mode & PEAR_ERROR_PRINT) {
907
            if (is_null($options) || is_int($options)) {
908
                $format = "%s";
909
            } else {
910
                $format = $options;
911
            }
912
913
            printf($format, $this->getMessage());
914
        }
915
916
        if ($this->mode & PEAR_ERROR_TRIGGER) {
917
            trigger_error($this->getMessage(), $this->level);
918
        }
919
920
        if ($this->mode & PEAR_ERROR_DIE) {
921
            $msg = $this->getMessage();
922
            if (is_null($options) || is_int($options)) {
923
                $format = "%s";
924
                if (substr($msg, -1) != "\n") {
925
                    $msg .= "\n";
926
                }
927
            } else {
928
                $format = $options;
929
            }
930
            die(sprintf($format, $msg));
931
        }
932
933
        if ($this->mode & PEAR_ERROR_CALLBACK) {
934
            if (is_callable($this->callback)) {
935
                call_user_func($this->callback, $this);
936
            }
937
        }
938
939
        if ($this->mode & PEAR_ERROR_EXCEPTION) {
0 ignored issues
show
Deprecated Code introduced by
The constant PEAR_ERROR_EXCEPTION has been deprecated.

This constant has been deprecated.

Loading history...
940
            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
941
            eval('$e = new Exception($this->message, $this->code);throw($e);');
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
942
        }
943
    }
944
945
    // }}}
946
    // {{{ getMode()
947
948
    /**
949
     * Get the error mode from an error object.
950
     *
951
     * @return int error mode
952
     * @access public
953
     */
954
    function getMode() {
955
        return $this->mode;
956
    }
957
958
    // }}}
959
    // {{{ getCallback()
960
961
    /**
962
     * Get the callback function/method from an error object.
963
     *
964
     * @return mixed callback function or object/method array
965
     * @access public
966
     */
967
    function getCallback() {
968
        return $this->callback;
969
    }
970
971
    // }}}
972
    // {{{ getMessage()
973
974
975
    /**
976
     * Get the error message from an error object.
977
     *
978
     * @return  string  full error message
979
     * @access public
980
     */
981
    function getMessage()
982
    {
983
        return ($this->error_message_prefix . $this->message);
984
    }
985
986
987
    // }}}
988
    // {{{ getCode()
989
990
    /**
991
     * Get error code from an error object
992
     *
993
     * @return int error code
994
     * @access public
995
     */
996
     function getCode()
997
     {
998
        return $this->code;
999
     }
1000
1001
    // }}}
1002
    // {{{ getType()
1003
1004
    /**
1005
     * Get the name of this error/exception.
1006
     *
1007
     * @return string error/exception name (type)
1008
     * @access public
1009
     */
1010
    function getType()
1011
    {
1012
        return get_class($this);
1013
    }
1014
1015
    // }}}
1016
    // {{{ getUserInfo()
1017
1018
    /**
1019
     * Get additional user-supplied information.
1020
     *
1021
     * @return string user-supplied information
1022
     * @access public
1023
     */
1024
    function getUserInfo()
1025
    {
1026
        return $this->userinfo;
1027
    }
1028
1029
    // }}}
1030
    // {{{ getDebugInfo()
1031
1032
    /**
1033
     * Get additional debug information supplied by the application.
1034
     *
1035
     * @return string debug information
1036
     * @access public
1037
     */
1038
    function getDebugInfo()
1039
    {
1040
        return $this->getUserInfo();
1041
    }
1042
1043
    // }}}
1044
    // {{{ getBacktrace()
1045
1046
    /**
1047
     * Get the call backtrace from where the error was generated.
1048
     * Supported with PHP 4.3.0 or newer.
1049
     *
1050
     * @param int $frame (optional) what frame to fetch
1051
     * @return array Backtrace, or NULL if not available.
1052
     * @access public
1053
     */
1054
    function getBacktrace($frame = null)
1055
    {
1056
        if (defined('PEAR_IGNORE_BACKTRACE')) {
1057
            return null;
1058
        }
1059
        if ($frame === null) {
1060
            return $this->backtrace;
1061
        }
1062
        return $this->backtrace[$frame];
1063
    }
1064
1065
    // }}}
1066
    // {{{ addUserInfo()
1067
1068
    function addUserInfo($info)
1069
    {
1070
        if (empty($this->userinfo)) {
1071
            $this->userinfo = $info;
1072
        } else {
1073
            $this->userinfo .= " ** $info";
1074
        }
1075
    }
1076
1077
    // }}}
1078
    // {{{ toString()
1079
    function __toString()
1080
    {
1081
        return $this->getMessage();
1082
    }
1083
    // }}}
1084
    // {{{ toString()
1085
1086
    /**
1087
     * Make a string representation of this object.
1088
     *
1089
     * @return string a string with an object summary
1090
     * @access public
1091
     */
1092
    function toString() {
1093
        $modes = array();
1094
        $levels = array(E_USER_NOTICE  => 'notice',
1095
                        E_USER_WARNING => 'warning',
1096
                        E_USER_ERROR   => 'error');
1097
        if ($this->mode & PEAR_ERROR_CALLBACK) {
1098
            if (is_array($this->callback)) {
1099
                $callback = (is_object($this->callback[0]) ?
1100
                    strtolower(get_class($this->callback[0])) :
1101
                    $this->callback[0]) . '::' .
1102
                    $this->callback[1];
1103
            } else {
1104
                $callback = $this->callback;
1105
            }
1106
            return sprintf('[%s: message="%s" code=%d mode=callback '.
1107
                           'callback=%s prefix="%s" info="%s"]',
1108
                           strtolower(get_class($this)), $this->message, $this->code,
1109
                           $callback, $this->error_message_prefix,
1110
                           $this->userinfo);
1111
        }
1112
        if ($this->mode & PEAR_ERROR_PRINT) {
1113
            $modes[] = 'print';
1114
        }
1115
        if ($this->mode & PEAR_ERROR_TRIGGER) {
1116
            $modes[] = 'trigger';
1117
        }
1118
        if ($this->mode & PEAR_ERROR_DIE) {
1119
            $modes[] = 'die';
1120
        }
1121
        if ($this->mode & PEAR_ERROR_RETURN) {
1122
            $modes[] = 'return';
1123
        }
1124
        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
1125
                       'prefix="%s" info="%s"]',
1126
                       strtolower(get_class($this)), $this->message, $this->code,
1127
                       implode("|", $modes), $levels[$this->level],
1128
                       $this->error_message_prefix,
1129
                       $this->userinfo);
1130
    }
1131
1132
    // }}}
1133
}
1134
1135
/*
1136
 * Local Variables:
1137
 * mode: php
1138
 * tab-width: 4
1139
 * c-basic-offset: 4
1140
 * End:
1141
 */
1142