Completed
Push — master ( 603564...3d1dbb )
by Michael
03:27
created

PEAR::_setErrorHandling()   D

Complexity

Conditions 10
Paths 18

Size

Total Lines 37
Code Lines 28

Duplication

Lines 32
Ratio 86.49 %

Importance

Changes 0
Metric Value
cc 10
eloc 28
nc 18
nop 3
dl 32
loc 37
rs 4.8196
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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 46.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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-2010 The Authors
16
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
17
 * @link       http://pear.php.net/package/PEAR
18
 * @since      File available since Release 0.1
19
 */
20
21
/**#@+
22
 * ERROR constants
23
 */
24
define('PEAR_ERROR_RETURN',     1);
25
define('PEAR_ERROR_PRINT',      2);
26
define('PEAR_ERROR_TRIGGER',    4);
27
define('PEAR_ERROR_DIE',        8);
28
define('PEAR_ERROR_CALLBACK',  16);
29
/**
30
 * WARNING: obsolete
31
 * @deprecated
32
 */
33
define('PEAR_ERROR_EXCEPTION', 32);
34
/**#@-*/
35
36
if (substr(PHP_OS, 0, 3) == 'WIN') {
37
    define('OS_WINDOWS', true);
38
    define('OS_UNIX',    false);
39
    define('PEAR_OS',    'Windows');
40
} else {
41
    define('OS_WINDOWS', false);
42
    define('OS_UNIX',    true);
43
    define('PEAR_OS',    'Unix'); // blatant assumption
44
}
45
46
$GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
47
$GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
48
$GLOBALS['_PEAR_destructor_object_list'] = array();
49
$GLOBALS['_PEAR_shutdown_funcs']         = array();
50
$GLOBALS['_PEAR_error_handler_stack']    = array();
51
52
@ini_set('track_errors', true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
53
54
/**
55
 * Base class for other PEAR classes.  Provides rudimentary
56
 * emulation of destructors.
57
 *
58
 * If you want a destructor in your class, inherit PEAR and make a
59
 * destructor method called _yourclassname (same name as the
60
 * constructor, but with a "_" prefix).  Also, in your constructor you
61
 * have to call the PEAR constructor: $this->PEAR();.
62
 * The destructor method will be called without parameters.  Note that
63
 * at in some SAPI implementations (such as Apache), any output during
64
 * the request shutdown (in which destructors are called) seems to be
65
 * discarded.  If you need to get any debug information from your
66
 * destructor, use error_log(), syslog() or something similar.
67
 *
68
 * IMPORTANT! To use the emulated destructors you need to create the
69
 * objects by reference: $obj =& new PEAR_child;
70
 *
71
 * @category   pear
72
 * @package    PEAR
73
 * @author     Stig Bakken <[email protected]>
74
 * @author     Tomas V.V. Cox <[email protected]>
75
 * @author     Greg Beaver <[email protected]>
76
 * @copyright  1997-2006 The PHP Group
77
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
78
 * @version    Release: 1.10.3
79
 * @link       http://pear.php.net/package/PEAR
80
 * @see        PEAR_Error
81
 * @since      Class available since PHP 4.0.2
82
 * @link        http://pear.php.net/manual/en/core.pear.php#core.pear.pear
83
 */
84
class PEAR
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
85
{
86
    /**
87
     * Whether to enable internal debug messages.
88
     *
89
     * @var     bool
90
     * @access  private
91
     */
92
    var $_debug = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_debug.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
93
94
    /**
95
     * Default error mode for this object.
96
     *
97
     * @var     int
98
     * @access  private
99
     */
100
    var $_default_error_mode = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_default_error_mode.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
101
102
    /**
103
     * Default error options used for this object when error mode
104
     * is PEAR_ERROR_TRIGGER.
105
     *
106
     * @var     int
107
     * @access  private
108
     */
109
    var $_default_error_options = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_default_error_options.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
110
111
    /**
112
     * Default error handler (callback) for this object, if error mode is
113
     * PEAR_ERROR_CALLBACK.
114
     *
115
     * @var     string
116
     * @access  private
117
     */
118
    var $_default_error_handler = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_default_error_handler.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
119
120
    /**
121
     * Which class to use for error objects.
122
     *
123
     * @var     string
124
     * @access  private
125
     */
126
    var $_error_class = 'PEAR_Error';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_error_class.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
127
128
    /**
129
     * An array of expected errors.
130
     *
131
     * @var     array
132
     * @access  private
133
     */
134
    var $_expected_errors = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $_expected_errors.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
135
136
    /**
137
     * List of methods that can be called both statically and non-statically.
138
     * @var array
139
     */
140
    protected static $bivalentMethods = array(
141
        'setErrorHandling' => true,
142
        'raiseError' => true,
143
        'throwError' => true,
144
        'pushErrorHandling' => true,
145
        'popErrorHandling' => true,
146
    );
147
148
    /**
149
     * Constructor.  Registers this object in
150
     * $_PEAR_destructor_object_list for destructor emulation if a
151
     * destructor object exists.
152
     *
153
     * @param string $error_class  (optional) which class to use for
0 ignored issues
show
Documentation introduced by
Should the type for parameter $error_class not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
154
     *        error objects, defaults to PEAR_Error.
155
     * @access public
156
     * @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...
157
     */
158
    function __construct($error_class = null)
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
159
    {
160
        $classname = strtolower(get_class($this));
161
        if ($this->_debug) {
162
            print "PEAR constructor called, class=$classname\n";
163
        }
164
165
        if ($error_class !== null) {
166
            $this->_error_class = $error_class;
167
        }
168
169
        while ($classname && strcasecmp($classname, "pear")) {
170
            $destructor = "_$classname";
171
            if (method_exists($this, $destructor)) {
172
                global $_PEAR_destructor_object_list;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
173
                $_PEAR_destructor_object_list[] = &$this;
174
                if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
175
                    register_shutdown_function("_PEAR_call_destructors");
176
                    $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
177
                }
178
                break;
179
            } else {
180
                $classname = get_parent_class($classname);
181
            }
182
        }
183
    }
184
185
    /**
186
     * Only here for backwards compatibility.
187
     * E.g. Archive_Tar calls $this->PEAR() in its constructor.
188
     *
189
     * @param string $error_class Which class to use for error objects,
0 ignored issues
show
Documentation introduced by
Should the type for parameter $error_class not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
190
     *                            defaults to PEAR_Error.
191
     */
192
    public function PEAR($error_class = null)
193
    {
194
        self::__construct($error_class);
195
    }
196
197
    /**
198
     * Destructor (the emulated type of...).  Does nothing right now,
199
     * but is included for forward compatibility, so subclass
200
     * destructors should always call it.
201
     *
202
     * See the note in the class desciption about output from
203
     * destructors.
204
     *
205
     * @access public
206
     * @return void
207
     */
208
    function _PEAR() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
209
        if ($this->_debug) {
210
            printf("PEAR destructor called, class=%s\n", strtolower(get_class($this)));
211
        }
212
    }
213
214 View Code Duplication
    public function __call($method, $arguments)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
215
    {
216
        if (!isset(self::$bivalentMethods[$method])) {
217
            trigger_error(
218
                'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
219
            );
220
        }
221
        return call_user_func_array(
222
            array(get_class(), '_' . $method),
223
            array_merge(array($this), $arguments)
224
        );
225
    }
226
227 View Code Duplication
    public static function __callStatic($method, $arguments)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
    {
229
        if (!isset(self::$bivalentMethods[$method])) {
230
            trigger_error(
231
                'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR
232
            );
233
        }
234
        return call_user_func_array(
235
            array(get_class(), '_' . $method),
236
            array_merge(array(null), $arguments)
237
        );
238
    }
239
240
    /**
241
    * If you have a class that's mostly/entirely static, and you need static
242
    * properties, you can use this method to simulate them. Eg. in your method(s)
243
    * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar');
244
    * You MUST use a reference, or they will not persist!
245
    *
246
    * @param  string $class  The calling classname, to prevent clashes
247
    * @param  string $var    The variable to retrieve.
248
    * @return mixed   A reference to the variable. If not set it will be
249
    *                 auto initialised to NULL.
250
    */
251
    public static function &getStaticProperty($class, $var)
252
    {
253
        static $properties;
254
        if (!isset($properties[$class])) {
255
            $properties[$class] = array();
256
        }
257
258
        if (!array_key_exists($var, $properties[$class])) {
259
            $properties[$class][$var] = null;
260
        }
261
262
        return $properties[$class][$var];
263
    }
264
265
    /**
266
    * Use this function to register a shutdown method for static
267
    * classes.
268
    *
269
    * @param  mixed $func  The function name (or array of class/method) to call
270
    * @param  mixed $args  The arguments to pass to the function
271
    *
272
    * @return void
273
    */
274
    public static function registerShutdownFunc($func, $args = array())
0 ignored issues
show
Coding Style introduced by
registerShutdownFunc uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
275
    {
276
        // if we are called statically, there is a potential
277
        // that no shutdown func is registered.  Bug #6445
278
        if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) {
279
            register_shutdown_function("_PEAR_call_destructors");
280
            $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true;
281
        }
282
        $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args);
283
    }
284
285
    /**
286
     * Tell whether a value is a PEAR error.
287
     *
288
     * @param   mixed $data   the value to test
289
     * @param   int   $code   if $data is an error object, return true
0 ignored issues
show
Documentation introduced by
Should the type for parameter $code not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
290
     *                        only if $code is a string and
291
     *                        $obj->getMessage() == $code or
292
     *                        $code is an integer and $obj->getCode() == $code
293
     *
294
     * @return  bool    true if parameter is an error
295
     */
296
    public static function isError($data, $code = null)
297
    {
298
        if (!is_a($data, 'PEAR_Error')) {
299
            return false;
300
        }
301
302
        if (is_null($code)) {
303
            return true;
304
        } elseif (is_string($code)) {
305
            return $data->getMessage() == $code;
306
        }
307
308
        return $data->getCode() == $code;
309
    }
310
311
    /**
312
     * Sets how errors generated by this object should be handled.
313
     * Can be invoked both in objects and statically.  If called
314
     * statically, setErrorHandling sets the default behaviour for all
315
     * PEAR objects.  If called in an object, setErrorHandling sets
316
     * the default behaviour for that object.
317
     *
318
     * @param object $object
319
     *        Object the method was called on (non-static mode)
320
     *
321
     * @param int $mode
0 ignored issues
show
Documentation introduced by
Should the type for parameter $mode not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
322
     *        One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
323
     *        PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
324
     *        PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION.
325
     *
326
     * @param mixed $options
327
     *        When $mode is PEAR_ERROR_TRIGGER, this is the error level (one
328
     *        of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
329
     *
330
     *        When $mode is PEAR_ERROR_CALLBACK, this parameter is expected
331
     *        to be the callback function or method.  A callback
332
     *        function is a string with the name of the function, a
333
     *        callback method is an array of two elements: the element
334
     *        at index 0 is the object, and the element at index 1 is
335
     *        the name of the method to call in the object.
336
     *
337
     *        When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is
338
     *        a printf format string used when printing the error
339
     *        message.
340
     *
341
     * @access public
342
     * @return void
343
     * @see PEAR_ERROR_RETURN
344
     * @see PEAR_ERROR_PRINT
345
     * @see PEAR_ERROR_TRIGGER
346
     * @see PEAR_ERROR_DIE
347
     * @see PEAR_ERROR_CALLBACK
348
     * @see PEAR_ERROR_EXCEPTION
349
     *
350
     * @since PHP 4.0.5
351
     */
352
    protected static function _setErrorHandling(
0 ignored issues
show
Coding Style introduced by
_setErrorHandling uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
353
        $object, $mode = null, $options = null
354
    ) {
355 View Code Duplication
        if ($object !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356
            $setmode     = &$object->_default_error_mode;
357
            $setoptions  = &$object->_default_error_options;
358
        } else {
359
            $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
360
            $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
361
        }
362
363 View Code Duplication
        switch ($mode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
364
            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...
365
            case PEAR_ERROR_RETURN:
366
            case PEAR_ERROR_PRINT:
367
            case PEAR_ERROR_TRIGGER:
368
            case PEAR_ERROR_DIE:
369
            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...
370
                $setmode = $mode;
371
                $setoptions = $options;
372
                break;
373
374
            case PEAR_ERROR_CALLBACK:
375
                $setmode = $mode;
376
                // class/object method callback
377
                if (is_callable($options)) {
378
                    $setoptions = $options;
379
                } else {
380
                    trigger_error("invalid error callback", E_USER_WARNING);
381
                }
382
                break;
383
384
            default:
385
                trigger_error("invalid error mode", E_USER_WARNING);
386
                break;
387
        }
388
    }
389
390
    /**
391
     * This method is used to tell which errors you expect to get.
392
     * Expected errors are always returned with error mode
393
     * PEAR_ERROR_RETURN.  Expected error codes are stored in a stack,
394
     * and this method pushes a new element onto it.  The list of
395
     * expected errors are in effect until they are popped off the
396
     * stack with the popExpect() method.
397
     *
398
     * Note that this method can not be called statically
399
     *
400
     * @param mixed $code a single error code or an array of error codes to expect
401
     *
402
     * @return int     the new depth of the "expected errors" stack
403
     * @access public
404
     */
405
    function expectError($code = '*')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
406
    {
407
        if (is_array($code)) {
408
            array_push($this->_expected_errors, $code);
409
        } else {
410
            array_push($this->_expected_errors, array($code));
411
        }
412
        return count($this->_expected_errors);
413
    }
414
415
    /**
416
     * This method pops one element off the expected error codes
417
     * stack.
418
     *
419
     * @return array   the list of error codes that were popped
420
     */
421
    function popExpect()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
422
    {
423
        return array_pop($this->_expected_errors);
424
    }
425
426
    /**
427
     * This method checks unsets an error code if available
428
     *
429
     * @param mixed error code
430
     * @return bool true if the error code was unset, false otherwise
431
     * @access private
432
     * @since PHP 4.3.0
433
     */
434
    function _checkDelExpect($error_code)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
435
    {
436
        $deleted = false;
437
        foreach ($this->_expected_errors as $key => $error_array) {
438
            if (in_array($error_code, $error_array)) {
439
                unset($this->_expected_errors[$key][array_search($error_code, $error_array)]);
440
                $deleted = true;
441
            }
442
443
            // clean up empty arrays
444
            if (0 == count($this->_expected_errors[$key])) {
445
                unset($this->_expected_errors[$key]);
446
            }
447
        }
448
449
        return $deleted;
450
    }
451
452
    /**
453
     * This method deletes all occurrences of the specified element from
454
     * the expected error codes stack.
455
     *
456
     * @param  mixed $error_code error code that should be deleted
457
     * @return mixed list of error codes that were deleted or error
458
     * @access public
459
     * @since PHP 4.3.0
460
     */
461
    function delExpect($error_code)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
462
    {
463
        $deleted = false;
464
        if ((is_array($error_code) && (0 != count($error_code)))) {
465
            // $error_code is a non-empty array here; we walk through it trying
466
            // to unset all values
467
            foreach ($error_code as $key => $error) {
468
                $deleted =  $this->_checkDelExpect($error) ? true : false;
469
            }
470
471
            return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
472
        } elseif (!empty($error_code)) {
473
            // $error_code comes alone, trying to unset it
474
            if ($this->_checkDelExpect($error_code)) {
475
                return true;
476
            }
477
478
            return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
479
        }
480
481
        // $error_code is empty
482
        return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
483
    }
484
485
    /**
486
     * This method is a wrapper that returns an instance of the
487
     * configured error class with this object's default error
488
     * handling applied.  If the $mode and $options parameters are not
489
     * specified, the object's defaults are used.
490
     *
491
     * @param mixed $message a text error message or a PEAR error object
492
     *
493
     * @param int $code      a numeric error code (it is up to your class
0 ignored issues
show
Documentation introduced by
Should the type for parameter $code not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
494
     *                  to define these if you want to use codes)
495
     *
496
     * @param int $mode      One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT,
0 ignored issues
show
Documentation introduced by
Should the type for parameter $mode not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
497
     *                  PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE,
498
     *                  PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION.
499
     *
500
     * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter
501
     *                  specifies the PHP-internal error level (one of
502
     *                  E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR).
503
     *                  If $mode is PEAR_ERROR_CALLBACK, this
504
     *                  parameter specifies the callback function or
505
     *                  method.  In other error modes this parameter
506
     *                  is ignored.
507
     *
508
     * @param string $userinfo If you need to pass along for example debug
0 ignored issues
show
Documentation introduced by
Should the type for parameter $userinfo not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
509
     *                  information, this parameter is meant for that.
510
     *
511
     * @param string $error_class The returned error object will be
0 ignored issues
show
Documentation introduced by
Should the type for parameter $error_class not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
512
     *                  instantiated from this class, if specified.
513
     *
514
     * @param bool $skipmsg If true, raiseError will only pass error codes,
515
     *                  the error message parameter will be dropped.
516
     *
517
     * @return object   a PEAR error object
518
     * @see PEAR::setErrorHandling
519
     * @since PHP 4.0.5
520
     */
521
    protected static function _raiseError($object,
0 ignored issues
show
Coding Style introduced by
_raiseError uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
522
                         $message = null,
523
                         $code = null,
524
                         $mode = null,
525
                         $options = null,
526
                         $userinfo = null,
527
                         $error_class = null,
528
                         $skipmsg = false)
529
    {
530
        // The error is yet a PEAR error object
531
        if (is_object($message)) {
532
            $code        = $message->getCode();
533
            $userinfo    = $message->getUserInfo();
534
            $error_class = $message->getType();
535
            $message->error_message_prefix = '';
536
            $message     = $message->getMessage();
537
        }
538
539
        if (
540
            $object !== null &&
541
            isset($object->_expected_errors) &&
542
            count($object->_expected_errors) > 0 &&
543
            count($exp = end($object->_expected_errors))
544
        ) {
545
            if ($exp[0] == "*" ||
546
                (is_int(reset($exp)) && in_array($code, $exp)) ||
547
                (is_string(reset($exp)) && in_array($message, $exp))
548
            ) {
549
                $mode = PEAR_ERROR_RETURN;
550
            }
551
        }
552
553
        // No mode given, try global ones
554
        if ($mode === null) {
555
            // Class error handler
556
            if ($object !== null && isset($object->_default_error_mode)) {
557
                $mode    = $object->_default_error_mode;
558
                $options = $object->_default_error_options;
559
            // Global error handler
560
            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
561
                $mode    = $GLOBALS['_PEAR_default_error_mode'];
562
                $options = $GLOBALS['_PEAR_default_error_options'];
563
            }
564
        }
565
566
        if ($error_class !== null) {
567
            $ec = $error_class;
568
        } elseif ($object !== null && isset($object->_error_class)) {
569
            $ec = $object->_error_class;
570
        } else {
571
            $ec = 'PEAR_Error';
572
        }
573
574
        if ($skipmsg) {
575
            $a = new $ec($code, $mode, $options, $userinfo);
576
        } else {
577
            $a = new $ec($message, $code, $mode, $options, $userinfo);
578
        }
579
580
        return $a;
581
    }
582
583
    /**
584
     * Simpler form of raiseError with fewer options.  In most cases
585
     * message, code and userinfo are enough.
586
     *
587
     * @param mixed $message a text error message or a PEAR error object
588
     *
589
     * @param int $code      a numeric error code (it is up to your class
0 ignored issues
show
Documentation introduced by
Should the type for parameter $code not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
590
     *                  to define these if you want to use codes)
591
     *
592
     * @param string $userinfo If you need to pass along for example debug
0 ignored issues
show
Documentation introduced by
Should the type for parameter $userinfo not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
593
     *                  information, this parameter is meant for that.
594
     *
595
     * @return object   a PEAR error object
596
     * @see PEAR::raiseError
597
     */
598
    protected static function _throwError($object, $message = null, $code = null, $userinfo = null)
599
    {
600
        if ($object !== null) {
601
            $a = &$object->raiseError($message, $code, null, null, $userinfo);
602
            return $a;
603
        }
604
605
        $a = &PEAR::raiseError($message, $code, null, null, $userinfo);
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
606
        return $a;
607
    }
608
609
    public static function staticPushErrorHandling($mode, $options = null)
0 ignored issues
show
Coding Style introduced by
staticPushErrorHandling uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
610
    {
611
        $stack       = &$GLOBALS['_PEAR_error_handler_stack'];
612
        $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
613
        $def_options = &$GLOBALS['_PEAR_default_error_options'];
614
        $stack[] = array($def_mode, $def_options);
615 View Code Duplication
        switch ($mode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
616
            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...
617
            case PEAR_ERROR_RETURN:
618
            case PEAR_ERROR_PRINT:
619
            case PEAR_ERROR_TRIGGER:
620
            case PEAR_ERROR_DIE:
621
            case null:
622
                $def_mode = $mode;
623
                $def_options = $options;
624
                break;
625
626
            case PEAR_ERROR_CALLBACK:
627
                $def_mode = $mode;
628
                // class/object method callback
629
                if (is_callable($options)) {
630
                    $def_options = $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
        $stack[] = array($mode, $options);
641
        return true;
642
    }
643
644
    public static function staticPopErrorHandling()
0 ignored issues
show
Coding Style introduced by
staticPopErrorHandling uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
645
    {
646
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
647
        $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
648
        $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
649
        array_pop($stack);
650
        list($mode, $options) = $stack[sizeof($stack) - 1];
651
        array_pop($stack);
652 View Code Duplication
        switch ($mode) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
653
            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...
654
            case PEAR_ERROR_RETURN:
655
            case PEAR_ERROR_PRINT:
656
            case PEAR_ERROR_TRIGGER:
657
            case PEAR_ERROR_DIE:
658
            case null:
659
                $setmode = $mode;
660
                $setoptions = $options;
661
                break;
662
663
            case PEAR_ERROR_CALLBACK:
664
                $setmode = $mode;
665
                // class/object method callback
666
                if (is_callable($options)) {
667
                    $setoptions = $options;
668
                } else {
669
                    trigger_error("invalid error callback", E_USER_WARNING);
670
                }
671
                break;
672
673
            default:
674
                trigger_error("invalid error mode", E_USER_WARNING);
675
                break;
676
        }
677
        return true;
678
    }
679
680
    /**
681
     * Push a new error handler on top of the error handler options stack. With this
682
     * you can easily override the actual error handler for some code and restore
683
     * it later with popErrorHandling.
684
     *
685
     * @param mixed $mode (same as setErrorHandling)
686
     * @param mixed $options (same as setErrorHandling)
687
     *
688
     * @return bool Always true
689
     *
690
     * @see PEAR::setErrorHandling
691
     */
692
    protected static function _pushErrorHandling($object, $mode, $options = null)
0 ignored issues
show
Coding Style introduced by
_pushErrorHandling uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
693
    {
694
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
695 View Code Duplication
        if ($object !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
696
            $def_mode    = &$object->_default_error_mode;
697
            $def_options = &$object->_default_error_options;
698
        } else {
699
            $def_mode    = &$GLOBALS['_PEAR_default_error_mode'];
700
            $def_options = &$GLOBALS['_PEAR_default_error_options'];
701
        }
702
        $stack[] = array($def_mode, $def_options);
703
704
        if ($object !== null) {
705
            $object->setErrorHandling($mode, $options);
706
        } else {
707
            PEAR::setErrorHandling($mode, $options);
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method setErrorHandling() does not exist on PEAR. Did you maybe mean _setErrorHandling()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
708
        }
709
        $stack[] = array($mode, $options);
710
        return true;
711
    }
712
713
    /**
714
    * Pop the last error handler used
715
    *
716
    * @return bool Always true
717
    *
718
    * @see PEAR::pushErrorHandling
719
    */
720
    protected static function _popErrorHandling($object)
0 ignored issues
show
Coding Style introduced by
_popErrorHandling uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
721
    {
722
        $stack = &$GLOBALS['_PEAR_error_handler_stack'];
723
        array_pop($stack);
724
        list($mode, $options) = $stack[sizeof($stack) - 1];
725
        array_pop($stack);
726
        if ($object !== null) {
727
            $object->setErrorHandling($mode, $options);
728
        } else {
729
            PEAR::setErrorHandling($mode, $options);
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
Bug introduced by
The method setErrorHandling() does not exist on PEAR. Did you maybe mean _setErrorHandling()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
730
        }
731
        return true;
732
    }
733
734
    /**
735
    * OS independent PHP extension load. Remember to take care
736
    * on the correct extension name for case sensitive OSes.
737
    *
738
    * @param string $ext The extension name
739
    * @return bool Success or not on the dl() call
740
    */
741
    public static function loadExtension($ext)
742
    {
743
        if (extension_loaded($ext)) {
744
            return true;
745
        }
746
747
        // if either returns true dl() will produce a FATAL error, stop that
748
        if (
749
            function_exists('dl') === false ||
750
            ini_get('enable_dl') != 1
751
        ) {
752
            return false;
753
        }
754
755
        if (OS_WINDOWS) {
756
            $suffix = '.dll';
757
        } elseif (PHP_OS == 'HP-UX') {
758
            $suffix = '.sl';
759
        } elseif (PHP_OS == 'AIX') {
760
            $suffix = '.a';
761
        } elseif (PHP_OS == 'OSX') {
762
            $suffix = '.bundle';
763
        } else {
764
            $suffix = '.so';
765
        }
766
767
        return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix);
768
    }
769
}
770
771
function _PEAR_call_destructors()
0 ignored issues
show
Coding Style introduced by
_PEAR_call_destructors uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
772
{
773
    global $_PEAR_destructor_object_list;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
774
    if (is_array($_PEAR_destructor_object_list) &&
775
        sizeof($_PEAR_destructor_object_list))
776
    {
777
        reset($_PEAR_destructor_object_list);
778
779
        $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo');
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 (
804
        isset($GLOBALS['_PEAR_shutdown_funcs']) &&
805
        is_array($GLOBALS['_PEAR_shutdown_funcs']) &&
806
        !empty($GLOBALS['_PEAR_shutdown_funcs'])
807
    ) {
808
        foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) {
809
            call_user_func_array($value[0], $value[1]);
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.10.3
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...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
832
{
833
    var $error_message_prefix = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $error_message_prefix.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
834
    var $mode                 = PEAR_ERROR_RETURN;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $mode.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
835
    var $level                = E_USER_NOTICE;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $level.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
836
    var $code                 = -1;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $code.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
837
    var $message              = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $message.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
838
    var $userinfo             = '';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $userinfo.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
839
    var $backtrace            = null;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $backtrace.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
840
841
    /**
842
     * PEAR_Error constructor
843
     *
844
     * @param string $message  message
845
     *
846
     * @param int $code     (optional) error code
0 ignored issues
show
Documentation introduced by
Should the type for parameter $code not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
847
     *
848
     * @param int $mode     (optional) error mode, one of: PEAR_ERROR_RETURN,
0 ignored issues
show
Documentation introduced by
Should the type for parameter $mode not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
849
     * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER,
850
     * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION
851
     *
852
     * @param mixed $options   (optional) error level, _OR_ in the case of
853
     * PEAR_ERROR_CALLBACK, the callback function or object/method
854
     * tuple.
855
     *
856
     * @param string $userinfo (optional) additional user/debug info
0 ignored issues
show
Documentation introduced by
Should the type for parameter $userinfo not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
857
     *
858
     * @access public
859
     *
860
     */
861
    function __construct($message = 'unknown error', $code = null,
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
862
                        $mode = null, $options = null, $userinfo = null)
863
    {
864
        if ($mode === null) {
865
            $mode = PEAR_ERROR_RETURN;
866
        }
867
        $this->message   = $message;
868
        $this->code      = $code;
869
        $this->mode      = $mode;
870
        $this->userinfo  = $userinfo;
871
872
        $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace');
873
874
        if (!$skiptrace) {
875
            $this->backtrace = debug_backtrace();
876
            if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) {
877
                unset($this->backtrace[0]['object']);
878
            }
879
        }
880
881
        if ($mode & PEAR_ERROR_CALLBACK) {
882
            $this->level = E_USER_NOTICE;
883
            $this->callback = $options;
0 ignored issues
show
Bug introduced by
The property callback does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
884
        } else {
885
            if ($options === null) {
886
                $options = E_USER_NOTICE;
887
            }
888
889
            $this->level = $options;
890
            $this->callback = null;
891
        }
892
893
        if ($this->mode & PEAR_ERROR_PRINT) {
894
            if (is_null($options) || is_int($options)) {
895
                $format = "%s";
896
            } else {
897
                $format = $options;
898
            }
899
900
            printf($format, $this->getMessage());
901
        }
902
903
        if ($this->mode & PEAR_ERROR_TRIGGER) {
904
            trigger_error($this->getMessage(), $this->level);
905
        }
906
907
        if ($this->mode & PEAR_ERROR_DIE) {
908
            $msg = $this->getMessage();
909
            if (is_null($options) || is_int($options)) {
910
                $format = "%s";
911
                if (substr($msg, -1) != "\n") {
912
                    $msg .= "\n";
913
                }
914
            } else {
915
                $format = $options;
916
            }
917
            printf($format, $msg);
918
            exit($code);
0 ignored issues
show
Coding Style Compatibility introduced by
The method __construct() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
919
        }
920
921
        if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) {
922
            call_user_func($this->callback, $this);
923
        }
924
925
        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...
926
            trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING);
927
            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...
928
        }
929
    }
930
931
    /**
932
     * Only here for backwards compatibility.
933
     *
934
     * Class "Cache_Error" still uses it, among others.
935
     *
936
     * @param string $message  Message
937
     * @param int    $code     Error code
0 ignored issues
show
Documentation introduced by
Should the type for parameter $code not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
938
     * @param int    $mode     Error mode
0 ignored issues
show
Documentation introduced by
Should the type for parameter $mode not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
939
     * @param mixed  $options  See __construct()
940
     * @param string $userinfo Additional user/debug info
0 ignored issues
show
Documentation introduced by
Should the type for parameter $userinfo not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
941
     */
942
    public function PEAR_Error(
943
        $message = 'unknown error', $code = null, $mode = null,
944
        $options = null, $userinfo = null
945
    ) {
946
        self::__construct($message, $code, $mode, $options, $userinfo);
947
    }
948
949
    /**
950
     * Get the error mode from an error object.
951
     *
952
     * @return int error mode
953
     * @access public
954
     */
955
    function getMode()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
956
    {
957
        return $this->mode;
958
    }
959
960
    /**
961
     * Get the callback function/method from an error object.
962
     *
963
     * @return mixed callback function or object/method array
964
     * @access public
965
     */
966
    function getCallback()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
967
    {
968
        return $this->callback;
969
    }
970
971
    /**
972
     * Get the error message from an error object.
973
     *
974
     * @return  string  full error message
975
     * @access public
976
     */
977
    function getMessage()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
978
    {
979
        return ($this->error_message_prefix . $this->message);
980
    }
981
982
    /**
983
     * Get error code from an error object
984
     *
985
     * @return int error code
986
     * @access public
987
     */
988
     function getCode()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
989
     {
990
        return $this->code;
991
     }
992
993
    /**
994
     * Get the name of this error/exception.
995
     *
996
     * @return string error/exception name (type)
997
     * @access public
998
     */
999
    function getType()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1000
    {
1001
        return get_class($this);
1002
    }
1003
1004
    /**
1005
     * Get additional user-supplied information.
1006
     *
1007
     * @return string user-supplied information
1008
     * @access public
1009
     */
1010
    function getUserInfo()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1011
    {
1012
        return $this->userinfo;
1013
    }
1014
1015
    /**
1016
     * Get additional debug information supplied by the application.
1017
     *
1018
     * @return string debug information
1019
     * @access public
1020
     */
1021
    function getDebugInfo()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1022
    {
1023
        return $this->getUserInfo();
1024
    }
1025
1026
    /**
1027
     * Get the call backtrace from where the error was generated.
1028
     * Supported with PHP 4.3.0 or newer.
1029
     *
1030
     * @param int $frame (optional) what frame to fetch
0 ignored issues
show
Documentation introduced by
Should the type for parameter $frame not be integer|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1031
     * @return array Backtrace, or NULL if not available.
1032
     * @access public
1033
     */
1034
    function getBacktrace($frame = null)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1035
    {
1036
        if (defined('PEAR_IGNORE_BACKTRACE')) {
1037
            return null;
1038
        }
1039
        if ($frame === null) {
1040
            return $this->backtrace;
1041
        }
1042
        return $this->backtrace[$frame];
1043
    }
1044
1045
    function addUserInfo($info)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1046
    {
1047
        if (empty($this->userinfo)) {
1048
            $this->userinfo = $info;
1049
        } else {
1050
            $this->userinfo .= " ** $info";
1051
        }
1052
    }
1053
1054
    function __toString()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1055
    {
1056
        return $this->getMessage();
1057
    }
1058
1059
    /**
1060
     * Make a string representation of this object.
1061
     *
1062
     * @return string a string with an object summary
1063
     * @access public
1064
     */
1065
    function toString()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1066
    {
1067
        $modes = array();
1068
        $levels = array(E_USER_NOTICE  => 'notice',
1069
                        E_USER_WARNING => 'warning',
1070
                        E_USER_ERROR   => 'error');
1071
        if ($this->mode & PEAR_ERROR_CALLBACK) {
1072
            if (is_array($this->callback)) {
1073
                $callback = (is_object($this->callback[0]) ?
1074
                    strtolower(get_class($this->callback[0])) :
1075
                    $this->callback[0]) . '::' .
1076
                    $this->callback[1];
1077
            } else {
1078
                $callback = $this->callback;
1079
            }
1080
            return sprintf('[%s: message="%s" code=%d mode=callback '.
1081
                           'callback=%s prefix="%s" info="%s"]',
1082
                           strtolower(get_class($this)), $this->message, $this->code,
1083
                           $callback, $this->error_message_prefix,
1084
                           $this->userinfo);
1085
        }
1086
        if ($this->mode & PEAR_ERROR_PRINT) {
1087
            $modes[] = 'print';
1088
        }
1089
        if ($this->mode & PEAR_ERROR_TRIGGER) {
1090
            $modes[] = 'trigger';
1091
        }
1092
        if ($this->mode & PEAR_ERROR_DIE) {
1093
            $modes[] = 'die';
1094
        }
1095
        if ($this->mode & PEAR_ERROR_RETURN) {
1096
            $modes[] = 'return';
1097
        }
1098
        return sprintf('[%s: message="%s" code=%d mode=%s level=%s '.
1099
                       'prefix="%s" info="%s"]',
1100
                       strtolower(get_class($this)), $this->message, $this->code,
1101
                       implode("|", $modes), $levels[$this->level],
1102
                       $this->error_message_prefix,
1103
                       $this->userinfo);
1104
    }
1105
}
1106
1107
/*
1108
 * Local Variables:
1109
 * mode: php
1110
 * tab-width: 4
1111
 * c-basic-offset: 4
1112
 * End:
1113
 */
1114