Completed
Pull Request — master (#6)
by Michael
01:49
created

UserlogRequest::getOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
 */
11
/**
12
 *  Userlog class
13
 *
14
 * @copyright       Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
15
 * @license         GNU/GPL, see LICENSE.php
16
 *                  Joomla! is free software. This version may have been modified pursuant
17
 *                  to the GNU General Public License, and as distributed it includes or
18
 *                  is derivative of works licensed under the GNU General Public License or
19
 *                  other free or open source software licenses.
20
 *                  See COPYRIGHT.php for copyright notices and details.
21
 * @package         Userlog
22
 * @since           1.0
23
 * @author          trabis <[email protected]>
24
 */
25
26
/**
27
 * Set the available masks for cleaning variables
28
 */
29
define('Userlog_REQUEST_NOTRIM', 1);
30
define('Userlog_REQUEST_ALLOWRAW', 2);
31
define('Userlog_REQUEST_ALLOWHTML', 4);
32
33
/**
34
 * UserlogRequest Class
35
 * This class serves to provide a common interface to access
36
 * request variables.  This includes $_POST, $_GET, and naturally $_REQUEST.  Variables
37
 * can be passed through an input filter to avoid injection or returned raw.
38
 */
39
class UserlogRequest
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...
40
{
41
    /**
42
     * Gets the request method
43
     *
44
     * @return string
45
     */
46
    public static function getOptions()
0 ignored issues
show
Coding Style introduced by
getOptions uses the super-global variable $_SERVER 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...
47
    {
48
        $method = strtoupper($_SERVER['REQUEST_METHOD']);
49
50
        return $method;
51
    }
52
53
    /**
54
     * Fetches and returns a given variable.
55
     * The default behaviour is fetching variables depending on the
56
     * current request method: GET and HEAD will result in returning
57
     * an entry from $_GET, POST and PUT will result in returning an
58
     * entry from $_POST.
59
     * You can force the source by setting the $hash parameter:
60
     *   post       $_POST
61
     *   get        $_GET
62
     *   files      $_FILES
63
     *   cookie     $_COOKIE
64
     *   env        $_ENV
65
     *   server     $_SERVER
66
     *   method     via current $_SERVER['REQUEST_METHOD']
67
     *   default    $_REQUEST
68
     *
69
     * @static
70
     *
71
     * @param string $name    Variable name
72
     * @param string $default Default value if the variable does not exist
0 ignored issues
show
Documentation introduced by
Should the type for parameter $default 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...
73
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
74
     * @param string $type    Return type for the variable, for valid values see {@link JFilterInput::clean()}
75
     * @param int    $mask    Filter mask for the variable
76
     *
77
     * @return mixed Requested variable
78
     */
79
    public static function getVar($name, $default = null, $hash = 'default', $type = 'none', $mask = 0)
0 ignored issues
show
Coding Style introduced by
getVar uses the super-global variable $_SERVER 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...
Coding Style introduced by
getVar uses the super-global variable $_GET 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...
Coding Style introduced by
getVar uses the super-global variable $_POST 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...
Coding Style introduced by
getVar uses the super-global variable $_FILES 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...
Coding Style introduced by
getVar uses the super-global variable $_COOKIE 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...
Coding Style introduced by
getVar uses the super-global variable $_ENV 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...
Coding Style introduced by
getVar uses the super-global variable $_REQUEST 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...
80
    {
81
        // Ensure hash and type are uppercase
82
        $hash = strtoupper($hash);
83
        if ($hash === 'METHOD') {
84
            $hash = strtoupper($_SERVER['REQUEST_METHOD']);
85
        }
86
        $type = strtoupper($type);
87
        // Get the input hash
88
        switch ($hash) {
89
            case 'GET':
90
                $input =& $_GET;
91
                break;
92
            case 'POST':
93
                $input =& $_POST;
94
                break;
95
            case 'FILES':
96
                $input =& $_FILES;
97
                break;
98
            case 'COOKIE':
99
                $input =& $_COOKIE;
100
                break;
101
            case 'ENV':
102
                $input =& $_ENV;
103
                break;
104
            case 'SERVER':
105
                $input =& $_SERVER;
106
                break;
107
            default:
108
                $input =& $_REQUEST;
109
                $hash  = 'REQUEST';
110
                break;
111
        }
112
        if (isset($input[$name]) && $input[$name] !== null) {
113
            // Get the variable from the input hash and clean it
114
            $var = UserlogRequest::_cleanVar($input[$name], $mask, $type);
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...
115
            // Handle magic quotes compatability
116
            if (get_magic_quotes_gpc() && ($var != $default) && ($hash !== 'FILES')) {
117
                $var = UserlogRequest::_stripSlashesRecursive($var);
0 ignored issues
show
Documentation introduced by
$var is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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...
118
            }
119
        } elseif ($default !== null) {
120
            // Clean the default value
121
            $var = UserlogRequest::_cleanVar($default, $mask, $type);
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...
122
        } else {
123
            $var = $default;
124
        }
125
126
        return $var;
127
    }
128
129
    /**
130
     * Fetches and returns a given filtered variable. The integer
131
     * filter will allow only digits to be returned. This is currently
132
     * only a proxy function for getVar().
133
     * See getVar() for more in-depth documentation on the parameters.
134
     *
135
     * @static
136
     *
137
     * @param string $name    Variable name
138
     * @param int    $default Default value if the variable does not exist
139
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
140
     *
141
     * @return integer Requested variable
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
142
     */
143
    public static function getInt($name, $default = 0, $hash = 'default')
144
    {
145
        return UserlogRequest::getVar($name, $default, $hash, 'int');
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...
146
    }
147
148
    /**
149
     * Fetches and returns a given filtered variable.  The float
150
     * filter only allows digits and periods.  This is currently
151
     * only a proxy function for getVar().
152
     * See getVar() for more in-depth documentation on the parameters.
153
     *
154
     * @static
155
     *
156
     * @param string $name    Variable name
157
     * @param float  $default Default value if the variable does not exist
158
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
159
     *
160
     * @return float Requested variable
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
161
     */
162
    public static function getFloat($name, $default = 0.0, $hash = 'default')
163
    {
164
        return UserlogRequest::getVar($name, $default, $hash, 'float');
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...
165
    }
166
167
    /**
168
     * Fetches and returns a given filtered variable. The bool
169
     * filter will only return true/false bool values. This is
170
     * currently only a proxy function for getVar().
171
     * See getVar() for more in-depth documentation on the parameters.
172
     *
173
     * @static
174
     *
175
     * @param string $name    Variable name
176
     * @param bool   $default Default value if the variable does not exist
177
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
178
     *
179
     * @return bool Requested variable
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
180
     */
181
    public static function getBool($name, $default = false, $hash = 'default')
182
    {
183
        return UserlogRequest::getVar($name, $default, $hash, 'bool');
0 ignored issues
show
Documentation introduced by
$default is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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...
184
    }
185
186
    /**
187
     * Fetches and returns a given filtered variable. The word
188
     * filter only allows the characters [A-Za-z_]. This is currently
189
     * only a proxy function for getVar().
190
     * See getVar() for more in-depth documentation on the parameters.
191
     *
192
     * @static
193
     *
194
     * @param string $name    Variable name
195
     * @param string $default Default value if the variable does not exist
196
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
197
     *
198
     * @return string Requested variable
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
199
     */
200
    public static function getWord($name, $default = '', $hash = 'default')
201
    {
202
        return UserlogRequest::getVar($name, $default, $hash, 'word');
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...
203
    }
204
205
    /**
206
     * Fetches and returns a given filtered variable. The cmd
207
     * filter only allows the characters [A-Za-z0-9.-_]. This is
208
     * currently only a proxy function for getVar().
209
     * See getVar() for more in-depth documentation on the parameters.
210
     *
211
     * @static
212
     *
213
     * @param string $name    Variable name
214
     * @param string $default Default value if the variable does not exist
215
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
216
     *
217
     * @return string Requested variable
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
218
     */
219
    public static function getCmd($name, $default = '', $hash = 'default')
220
    {
221
        return UserlogRequest::getVar($name, $default, $hash, 'cmd');
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...
222
    }
223
224
    /**
225
     * Fetches and returns a given filtered variable. The string
226
     * filter deletes 'bad' HTML code, if not overridden by the mask.
227
     * This is currently only a proxy function for getVar().
228
     * See getVar() for more in-depth documentation on the parameters.
229
     *
230
     * @static
231
     *
232
     * @param string $name    Variable name
233
     * @param string $default Default value if the variable does not exist
234
     * @param string $hash    Where the var should come from (POST, GET, FILES, COOKIE, METHOD)
235
     * @param int    $mask    Filter mask for the variable
236
     *
237
     * @return string Requested variable
238
     */
239
    public static function getString($name, $default = '', $hash = 'default', $mask = 0)
240
    {
241
        // Cast to string, in case JREQUEST_ALLOWRAW was specified for mask
242
        return (string)UserlogRequest::getVar($name, $default, $hash, 'string', $mask);
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...
243
    }
244
245
    /**
246
     * @param        $name
247
     * @param array  $default
248
     * @param string $hash
249
     *
250
     * @return mixed
251
     */
252
    public static function getArray($name, $default = array(), $hash = 'default')
253
    {
254
        return UserlogRequest::getVar($name, $default, $hash, 'array');
0 ignored issues
show
Documentation introduced by
$default is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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...
255
    }
256
257
    /**
258
     * @param        $name
259
     * @param string $default
260
     * @param string $hash
261
     *
262
     * @return string
263
     */
264
    public static function getText($name, $default = '', $hash = 'default')
265
    {
266
        return (string)UserlogRequest::getVar($name, $default, $hash, 'string', Userlog_REQUEST_ALLOWRAW);
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...
267
    }
268
269
    /**
270
     * Set a variabe in on of the request variables
271
     *
272
     * @access    public
273
     *
274
     * @param string  $name      Name
275
     * @param string  $value     Value
0 ignored issues
show
Documentation introduced by
Should the type for parameter $value 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...
276
     * @param string  $hash      Hash
277
     * @param boolean $overwrite Boolean
278
     *
279
     * @return string Previous value
280
     */
281
    public static function setVar($name, $value = null, $hash = 'method', $overwrite = true)
0 ignored issues
show
Coding Style introduced by
setVar uses the super-global variable $_REQUEST 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...
Coding Style introduced by
setVar uses the super-global variable $_SERVER 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...
Coding Style introduced by
setVar uses the super-global variable $_GET 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...
Coding Style introduced by
setVar uses the super-global variable $_POST 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...
Coding Style introduced by
setVar uses the super-global variable $_COOKIE 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...
Coding Style introduced by
setVar uses the super-global variable $_FILES 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...
Coding Style introduced by
setVar uses the super-global variable $_ENV 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...
282
    {
283
        //If overwrite is true, makes sure the variable hasn't been set yet
284
        if (!$overwrite && array_key_exists($name, $_REQUEST)) {
285
            return $_REQUEST[$name];
286
        }
287
        // Get the request hash value
288
        $hash = strtoupper($hash);
289
        if ($hash === 'METHOD') {
290
            $hash = strtoupper($_SERVER['REQUEST_METHOD']);
291
        }
292
        $previous = array_key_exists($name, $_REQUEST) ? $_REQUEST[$name] : null;
293
        switch ($hash) {
294
            case 'GET':
295
                $_GET[$name]     = $value;
296
                $_REQUEST[$name] = $value;
297
                break;
298
            case 'POST':
299
                $_POST[$name]    = $value;
300
                $_REQUEST[$name] = $value;
301
                break;
302
            case 'COOKIE':
303
                $_COOKIE[$name]  = $value;
304
                $_REQUEST[$name] = $value;
305
                break;
306
            case 'FILES':
307
                $_FILES[$name] = $value;
308
                break;
309
            case 'ENV':
310
                $_ENV['name'] = $value;
311
                break;
312
            case 'SERVER':
313
                $_SERVER['name'] = $value;
314
                break;
315
        }
316
317
        return $previous;
318
    }
319
320
    /**
321
     * Fetches and returns a request array.
322
     * The default behaviour is fetching variables depending on the
323
     * current request method: GET and HEAD will result in returning
324
     * $_GET, POST and PUT will result in returning $_POST.
325
     * You can force the source by setting the $hash parameter:
326
     *   post        $_POST
327
     *   get        $_GET
328
     *   files        $_FILES
329
     *   cookie        $_COOKIE
330
     *   env        $_ENV
331
     *   server        $_SERVER
332
     *   method        via current $_SERVER['REQUEST_METHOD']
333
     *   default    $_REQUEST
334
     *
335
     * @static
336
     *
337
     * @param string $hash to get (POST, GET, FILES, METHOD)
338
     * @param int    $mask Filter mask for the variable
339
     *
340
     * @return mixed Request hash
341
     */
342
    public static function get($hash = 'default', $mask = 0)
0 ignored issues
show
Coding Style introduced by
get uses the super-global variable $_SERVER 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...
Coding Style introduced by
get uses the super-global variable $_GET 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...
Coding Style introduced by
get uses the super-global variable $_POST 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...
Coding Style introduced by
get uses the super-global variable $_FILES 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...
Coding Style introduced by
get uses the super-global variable $_COOKIE 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...
Coding Style introduced by
get uses the super-global variable $_ENV 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...
Coding Style introduced by
get uses the super-global variable $_REQUEST 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...
343
    {
344
        $hash = strtoupper($hash);
345
        if ($hash === 'METHOD') {
346
            $hash = strtoupper($_SERVER['REQUEST_METHOD']);
347
        }
348
        switch ($hash) {
349
            case 'GET':
350
                $input = $_GET;
351
                break;
352
            case 'POST':
353
                $input = $_POST;
354
                break;
355
            case 'FILES':
356
                $input = $_FILES;
357
                break;
358
            case 'COOKIE':
359
                $input = $_COOKIE;
360
                break;
361
            case 'ENV':
362
                $input =& $_ENV;
363
                break;
364
            case 'SERVER':
365
                $input =& $_SERVER;
366
                break;
367
            default:
368
                $input = $_REQUEST;
369
                break;
370
        }
371
        $result = UserlogRequest::_cleanVar($input, $mask);
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...
372
        // Handle magic quotes compatability
373
        if (get_magic_quotes_gpc() && ($hash !== 'FILES')) {
374
            $result = UserlogRequest::_stripSlashesRecursive($result);
0 ignored issues
show
Documentation introduced by
$result is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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...
375
        }
376
377
        return $result;
378
    }
379
380
    /**
381
     * Sets a request variable
382
     *
383
     * @param array   $array     An associative array of key-value pairs
384
     * @param string  $hash      The request variable to set (POST, GET, FILES, METHOD)
385
     * @param boolean $overwrite If true and an existing key is found, the value is overwritten, otherwise it is ingored
386
     */
387
    public static function set($array, $hash = 'default', $overwrite = true)
388
    {
389
        foreach ($array as $key => $value) {
390
            UserlogRequest::setVar($key, $value, $hash, $overwrite);
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...
391
        }
392
    }
393
394
    /**
395
     * Cleans the request from script injection.
396
     *
397
     * @static
398
     * @return void
399
     */
400
    public static function clean()
0 ignored issues
show
Coding Style introduced by
clean uses the super-global variable $_FILES 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...
Coding Style introduced by
clean uses the super-global variable $_ENV 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...
Coding Style introduced by
clean uses the super-global variable $_GET 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...
Coding Style introduced by
clean uses the super-global variable $_POST 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...
Coding Style introduced by
clean uses the super-global variable $_COOKIE 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...
Coding Style introduced by
clean uses the super-global variable $_SERVER 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...
Coding Style introduced by
clean uses the super-global variable $_SESSION 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...
Coding Style introduced by
clean uses the super-global variable $_REQUEST 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...
Coding Style introduced by
clean 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...
401
    {
402
        UserlogRequest::_cleanArray($_FILES);
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...
403
        UserlogRequest::_cleanArray($_ENV);
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...
404
        UserlogRequest::_cleanArray($_GET);
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...
405
        UserlogRequest::_cleanArray($_POST);
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...
406
        UserlogRequest::_cleanArray($_COOKIE);
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...
407
        UserlogRequest::_cleanArray($_SERVER);
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...
408
        if (isset($_SESSION)) {
409
            UserlogRequest::_cleanArray($_SESSION);
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...
410
        }
411
        $REQUEST = $_REQUEST;
412
        $GET     = $_GET;
413
        $POST    = $_POST;
414
        $COOKIE  = $_COOKIE;
415
        $FILES   = $_FILES;
416
        $ENV     = $_ENV;
417
        $SERVER  = $_SERVER;
418
        if (isset($_SESSION)) {
419
            $SESSION = $_SESSION;
420
        }
421
        foreach ($GLOBALS as $key => $value) {
422
            if ($key !== 'GLOBALS') {
423
                unset($GLOBALS[$key]);
424
            }
425
        }
426
        $_REQUEST = $REQUEST;
427
        $_GET     = $GET;
428
        $_POST    = $POST;
429
        $_COOKIE  = $COOKIE;
430
        $_FILES   = $FILES;
431
        $_ENV     = $ENV;
432
        $_SERVER  = $SERVER;
433
        if (isset($SESSION)) {
434
            $_SESSION = $SESSION;
435
        }
436
    }
437
438
    /**
439
     * Adds an array to the GLOBALS array and checks that the GLOBALS variable is not being attacked
440
     *
441
     * @access    protected
442
     *
443
     * @param array   $array     Array to clean
444
     * @param boolean $globalise True if the array is to be added to the GLOBALS
445
     */
446
    public static function _cleanArray(&$array, $globalise = false)
0 ignored issues
show
Coding Style introduced by
_cleanArray 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...
447
    {
448
        static $banned = array('_files', '_env', '_get', '_post', '_cookie', '_server', '_session', 'globals');
449
        foreach ($array as $key => $value) {
450
            // PHP GLOBALS injection bug
451
            $failed = in_array(strtolower($key), $banned);
452
            // PHP Zend_Hash_Del_Key_Or_Index bug
453
            $failed |= is_numeric($key);
454
            if ($failed) {
455
                exit('Illegal variable <strong>' . implode('</strong> or <strong>', $banned) . '</strong> passed to script.');
0 ignored issues
show
Coding Style Compatibility introduced by
The method _cleanArray() 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...
456
            }
457
            if ($globalise) {
458
                $GLOBALS[$key] = $value;
459
            }
460
        }
461
    }
462
463
    /**
464
     * Clean up an input variable.
465
     *
466
     * @param mixed  $var  The input variable.
467
     * @param int    $mask Filter bit mask. 1=no trim: If this flag is cleared and the
468
     *                     input is a string, the string will have leading and trailing whitespace
469
     *                     trimmed. 2=allow_raw: If set, no more filtering is performed, higher bits
470
     *                     are ignored. 4=allow_html: HTML is allowed, but passed through a safe
471
     *                     HTML filter first. If set, no more filtering is performed. If no bits
472
     *                     other than the 1 bit is set, a strict filter is applied.
473
     * @param string $type The variable type {@see JFilterInput::clean()}.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type 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...
474
     *
475
     * @return string
476
     */
477
    public static function _cleanVar($var, $mask = 0, $type = null)
478
    {
479
        // Static input filters for specific settings
480
        static $noHtmlFilter = null;
481
        static $safeHtmlFilter = null;
482
        // If the no trim flag is not set, trim the variable
483
        if (!($mask & 1) && is_string($var)) {
484
            $var = trim($var);
485
        }
486
        // Now we handle input filtering
487
        if ($mask & 2) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
488
            // If the allow raw flag is set, do not modify the variable
489
        } elseif ($mask & 4) {
490
            // If the allow html flag is set, apply a safe html filter to the variable
491
            if (null === $safeHtmlFilter) {
492
                $safeHtmlFilter = UserlogFilterInput::getInstance(null, null, 1, 1);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
493
            }
494
            $var = $safeHtmlFilter->clean($var, $type);
495
        } else {
496
            // Since no allow flags were set, we will apply the most strict filter to the variable
497
            if (null === $noHtmlFilter) {
498
                $noHtmlFilter = UserlogFilterInput::getInstance(/* $tags, $attr, $tag_method, $attr_method, $xss_auto */);
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
499
            }
500
            $var = $noHtmlFilter->clean($var, $type);
501
        }
502
503
        return $var;
504
    }
505
506
    /**
507
     * Strips slashes recursively on an array
508
     *
509
     * @access    protected
510
     *
511
     * @param array $value Array of (nested arrays of) strings
512
     *
513
     * @return array|string The input array with stripshlashes applied to it
514
     */
515
    protected function _stripSlashesRecursive($value)
516
    {
517
        $value = is_array($value) ? array_map(array('UserlogRequest', '_stripSlashesRecursive'), $value) : stripslashes($value);
518
519
        return $value;
520
    }
521
}
522
523
/**
524
 * UserlogInput is a class for filtering input from any data source
525
 * Forked from the php input filter library by: Daniel Morris <[email protected]>
526
 * Original Contributors: Gianpaolo Racca, Ghislain Picard, Marco Wandschneider, Chris Tobin and Andrew Eddie.
527
 *
528
 * @author      Louis Landry <[email protected]>
529
 */
530
class UserlogFilterInput
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...
531
{
532
    public $tagsArray; // default = empty array
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
533
    public $attrArray; // default = empty array
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
534
    public $tagsMethod; // default = 0
535
    public $attrMethod; // default = 0
536
    public $xssAuto; // default = 1
537
    public $tagBlacklist  = array(
538
        'applet',
539
        'body',
540
        'bgsound',
541
        'base',
542
        'basefont',
543
        'embed',
544
        'frame',
545
        'frameset',
546
        'head',
547
        'html',
548
        'id',
549
        'iframe',
550
        'ilayer',
551
        'layer',
552
        'link',
553
        'meta',
554
        'name',
555
        'object',
556
        'script',
557
        'style',
558
        'title',
559
        'xml'
560
    );
561
    public $attrBlacklist = array(
562
        'action',
563
        'background',
564
        'codebase',
565
        'dynsrc',
566
        'lowsrc'
567
    ); // also will strip ALL event handlers
568
569
    /**
570
     * Constructor for inputFilter class. Only first parameter is required.
571
     *
572
     * @access  protected
573
     *
574
     * @param array $tagsArray  list of user-defined tags
575
     * @param array $attrArray  list of user-defined attributes
576
     * @param int   $tagsMethod WhiteList method = 0, BlackList method = 1
577
     * @param int   $attrMethod WhiteList method = 0, BlackList method = 1
578
     * @param int   $xssAuto    Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1
579
     */
580
    public function __construct(
581
        $tagsArray = array(),
582
        $attrArray = array(),
583
        $tagsMethod = 0,
584
        $attrMethod = 0,
585
        $xssAuto = 1
586
    ) {
587
        // Make sure user defined arrays are in lowercase
588
        $tagsArray = array_map('strtolower', (array)$tagsArray);
589
        $attrArray = array_map('strtolower', (array)$attrArray);
590
        // Assign member variables
591
        $this->tagsArray  = $tagsArray;
592
        $this->attrArray  = $attrArray;
593
        $this->tagsMethod = $tagsMethod;
594
        $this->attrMethod = $attrMethod;
595
        $this->xssAuto    = $xssAuto;
596
    }
597
598
    /**
599
     * Returns a reference to an input filter object, only creating it if it doesn't already exist.
600
     * This method must be invoked as:
601
     *      <pre>  $filter = & UserlogFilterInput::getInstance();</pre>
602
     *
603
     * @static
604
     *
605
     * @param array $tagsArray  list of user-defined tags
606
     * @param array $attrArray  list of user-defined attributes
607
     * @param int   $tagsMethod WhiteList method = 0, BlackList method = 1
608
     * @param int   $attrMethod WhiteList method = 0, BlackList method = 1
609
     * @param int   $xssAuto    Only auto clean essentials = 0, Allow clean blacklisted tags/attr = 1
610
     *
611
     * @return object The UserlogFilterInput object.
612
     * @since   1.5
613
     */
614
    public static function getInstance(
615
        $tagsArray = array(),
616
        $attrArray = array(),
617
        $tagsMethod = 0,
618
        $attrMethod = 0,
619
        $xssAuto = 1
620
    ) {
621
        static $instances;
622
        $sig = md5(serialize(array($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto)));
623
        if (!isset($instances)) {
624
            $instances = array();
625
        }
626
        if (empty($instances[$sig])) {
627
            $instances[$sig] = new UserlogFilterInput($tagsArray, $attrArray, $tagsMethod, $attrMethod, $xssAuto);
628
        }
629
630
        return $instances[$sig];
631
    }
632
633
    /**
634
     * Method to be called by another php script. Processes for XSS and
635
     * specified bad code.
636
     *
637
     * @access  public
638
     *
639
     * @param mixed  $source Input string/array-of-string to be 'cleaned'
640
     * @param string $type   Return type for the variable (INT, FLOAT, BOOLEAN, WORD, ALNUM, CMD, BASE64, STRING, ARRAY, PATH, NONE)
641
     *
642
     * @return mixed 'Cleaned' version of input parameter
643
     * @static
644
     */
645
    public function clean($source, $type = 'string')
646
    {
647
        // Handle the type constraint
648
        switch (strtoupper($type)) {
649
            case 'INT':
650 View Code Duplication
            case 'INTEGER':
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...
651
                // Only use the first integer value
652
                preg_match('/-?[0-9]+/', (string)$source, $matches);
653
                $result = @ (int)$matches[0];
654
                break;
655
            case 'FLOAT':
656 View Code Duplication
            case 'DOUBLE':
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...
657
                // Only use the first floating point value
658
                preg_match('/-?[0-9]+(\.[0-9]+)?/', (string)$source, $matches);
659
                $result = @ (float)$matches[0];
660
                break;
661
            case 'BOOL':
662
            case 'BOOLEAN':
663
                $result = (bool)$source;
664
                break;
665
            case 'WORD':
666
                $result = (string)preg_replace('/[^A-Z_]/i', '', $source);
667
                break;
668
            case 'ALNUM':
669
                $result = (string)preg_replace('/[^A-Z0-9]/i', '', $source);
670
                break;
671
            case 'CMD':
672
                $result = (string)preg_replace('/[^A-Z0-9_\.-]/i', '', $source);
673
                $result = ltrim($result, '.');
674
                break;
675
            case 'BASE64':
676
                $result = (string)preg_replace('/[^A-Z0-9\/+=]/i', '', $source);
677
                break;
678
            case 'STRING':
679
                // Check for static usage and assign $filter the proper variable
680
                if (isset($this) && is_a($this, 'UserlogFilterInput')) {
681
                    $filter =& $this;
682
                } else {
683
                    $filter = UserlogFilterInput::getInstance();
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...
684
                }
685
                $result = (string)$filter->_remove($filter->_decode((string)$source));
686
                break;
687
            case 'ARRAY':
688
                $result = (array)$source;
689
                break;
690 View Code Duplication
            case 'PATH':
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...
691
                $pattern = '/^[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*([\\\\\/][A-Za-z0-9_-]+[A-Za-z0-9_\.-]*)*$/';
692
                preg_match($pattern, (string)$source, $matches);
693
                $result = @ (string)$matches[0];
694
                break;
695
            case 'USERNAME':
696
                $result = (string)preg_replace('/[\x00-\x1F\x7F<>"\'%&]/', '', $source);
697
                break;
698
            default:
699
                // Check for static usage and assign $filter the proper variable
700
                if (is_object($this) && get_class($this) === 'UserlogFilterInput') {
701
                    $filter =& $this;
702
                } else {
703
                    $filter = UserlogFilterInput::getInstance();
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...
704
                }
705
                // Are we dealing with an array?
706
                if (is_array($source)) {
707
                    foreach ($source as $key => $value) {
708
                        // filter element for XSS and other 'bad' code etc.
709
                        if (is_string($value)) {
710
                            $source[$key] = $filter->_remove($filter->_decode($value));
711
                        }
712
                    }
713
                    $result = $source;
714
                } else {
715
                    // Or a string?
716
                    if (is_string($source) && !empty($source)) {
717
                        // filter source for XSS and other 'bad' code etc.
718
                        $result = $filter->_remove($filter->_decode($source));
719
                    } else {
720
                        // Not an array or string.. return the passed parameter
721
                        $result = $source;
722
                    }
723
                }
724
                break;
725
        }
726
727
        return $result;
728
    }
729
730
    /**
731
     * Function to determine if contents of an attribute is safe
732
     *
733
     * @static
734
     *
735
     * @param array $attrSubSet A 2 element array for attributes name,value
736
     *
737
     * @return boolean True if bad code is detected
738
     */
739
    public function checkAttribute($attrSubSet)
740
    {
741
        $attrSubSet[0] = strtolower($attrSubSet[0]);
742
        $attrSubSet[1] = strtolower($attrSubSet[1]);
743
744
        return (((strpos($attrSubSet[1], 'expression') !== false) && $attrSubSet[0] === 'style')
745
                || (strpos($attrSubSet[1], 'javascript:') !== false)
746
                || (strpos($attrSubSet[1], 'behaviour:') !== false)
747
                || (strpos($attrSubSet[1], 'vbscript:') !== false)
748
                || (strpos($attrSubSet[1], 'mocha:') !== false)
749
                || (strpos($attrSubSet[1], 'livescript:') !== false));
750
    }
751
752
    /**
753
     * Internal method to iteratively remove all unwanted tags and attributes
754
     *
755
     * @access  protected
756
     *
757
     * @param string $source Input string to be 'cleaned'
758
     *
759
     * @return string 'Cleaned' version of input parameter
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
760
     */
761
    protected function _remove($source)
762
    {
763
        $loopCounter = 0;
764
        // Iteration provides nested tag protection
765
        while ($source != $this->_cleanTags($source)) {
766
            $source = $this->_cleanTags($source);
767
            ++$loopCounter;
768
        }
769
770
        return $source;
771
    }
772
773
    /**
774
     * Internal method to strip a string of certain tags
775
     *
776
     * @access  protected
777
     *
778
     * @param string $source Input string to be 'cleaned'
779
     *
780
     * @return string 'Cleaned' version of input parameter
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
781
     */
782
    protected function _cleanTags($source)
783
    {
784
        /*
785
         * In the beginning we don't really have a tag, so everything is
786
         * postTag
787
         */
788
        $preTag  = null;
789
        $postTag = $source;
790
        // Is there a tag? If so it will certainly start with a '<'
791
        $tagOpen_start = strpos($source, '<');
792
        while ($tagOpen_start !== false) {
793
            // Get some information about the tag we are processing
794
            $preTag      .= substr($postTag, 0, $tagOpen_start);
795
            $postTag     = substr($postTag, $tagOpen_start);
796
            $fromTagOpen = substr($postTag, 1);
797
            $tagOpen_end = strpos($fromTagOpen, '>');
798
            // Let's catch any non-terminated tags and skip over them
799
            if ($tagOpen_end === false) {
800
                $postTag       = substr($postTag, $tagOpen_start + 1);
801
                $tagOpen_start = strpos($postTag, '<');
802
                continue;
803
            }
804
            // Do we have a nested tag?
805
            $tagOpen_nested = strpos($fromTagOpen, '<');
806
            if (($tagOpen_nested !== false) && ($tagOpen_nested < $tagOpen_end)) {
807
                $preTag        .= substr($postTag, 0, $tagOpen_nested + 1);
808
                $postTag       = substr($postTag, $tagOpen_nested + 1);
809
                $tagOpen_start = strpos($postTag, '<');
810
                continue;
811
            }
812
            // Lets get some information about our tag and setup attribute pairs
813
            $currentTag   = substr($fromTagOpen, 0, $tagOpen_end);
814
            $tagLength    = strlen($currentTag);
815
            $tagLeft      = $currentTag;
816
            $attrSet      = array();
817
            $currentSpace = strpos($tagLeft, ' ');
818
            // Are we an open tag or a close tag?
819
            if (substr($currentTag, 0, 1) === '/') {
820
                // Close Tag
821
                $isCloseTag = true;
822
                list($tagName) = explode(' ', $currentTag);
823
                $tagName = substr($tagName, 1);
824
            } else {
825
                // Open Tag
826
                $isCloseTag = false;
827
                list($tagName) = explode(' ', $currentTag);
828
            }
829
            /*
830
             * Exclude all "non-regular" tagnames
831
             * OR no tagname
832
             * OR remove if xssauto is on and tag is blacklisted
833
             */
834
            if ((!preg_match("/^[a-z][a-z0-9]*$/i", $tagName)) || (!$tagName)
835
                || (in_array(strtolower($tagName), $this->tagBlacklist) && $this->xssAuto)) {
836
                $postTag       = substr($postTag, $tagLength + 2);
837
                $tagOpen_start = strpos($postTag, '<');
838
                // Strip tag
839
                continue;
840
            }
841
            /*
842
             * Time to grab any attributes from the tag... need this section in
843
             * case attributes have spaces in the values.
844
             */
845
            while ($currentSpace !== false) {
846
                $attr        = '';
847
                $fromSpace   = substr($tagLeft, $currentSpace + 1);
848
                $nextSpace   = strpos($fromSpace, ' ');
849
                $openQuotes  = strpos($fromSpace, '"');
850
                $closeQuotes = strpos(substr($fromSpace, $openQuotes + 1), '"') + $openQuotes + 1;
851
                // Do we have an attribute to process? [check for equal sign]
852
                if (strpos($fromSpace, '=') !== false) {
853
                    /*
854
                     * If the attribute value is wrapped in quotes we need to
855
                     * grab the substring from the closing quote, otherwise grab
856
                     * till the next space
857
                     */
858
                    if (($openQuotes !== false) && (strpos(substr($fromSpace, $openQuotes + 1), '"') !== false)) {
859
                        $attr = substr($fromSpace, 0, $closeQuotes + 1);
860
                    } else {
861
                        $attr = substr($fromSpace, 0, $nextSpace);
862
                    }
863
                } else {
864
                    /*
865
                     * No more equal signs so add any extra text in the tag into
866
                     * the attribute array [eg. checked]
867
                     */
868
                    if ($fromSpace !== '/') {
869
                        $attr = substr($fromSpace, 0, $nextSpace);
870
                    }
871
                }
872
                // Last Attribute Pair
873
                if (!$attr && $fromSpace !== '/') {
874
                    $attr = $fromSpace;
875
                }
876
                // Add attribute pair to the attribute array
877
                $attrSet[] = $attr;
878
                // Move search point and continue iteration
879
                $tagLeft      = substr($fromSpace, strlen($attr));
880
                $currentSpace = strpos($tagLeft, ' ');
881
            }
882
            // Is our tag in the user input array?
883
            $tagFound = in_array(strtolower($tagName), $this->tagsArray);
884
            // If the tag is allowed lets append it to the output string
885
            if ((!$tagFound && $this->tagsMethod) || ($tagFound && !$this->tagsMethod)) {
886
                // Reconstruct tag with allowed attributes
887
                if (!$isCloseTag) {
888
                    // Open or Single tag
889
                    $attrSet = $this->_cleanAttributes($attrSet);
890
                    $preTag  .= '<' . $tagName;
891
                    for ($i = 0, $iMax = count($attrSet); $i < $iMax; ++$i) {
892
                        $preTag .= ' ' . $attrSet[$i];
893
                    }
894
                    // Reformat single tags to XHTML
895
                    if (strpos($fromTagOpen, '</' . $tagName)) {
896
                        $preTag .= '>';
897
                    } else {
898
                        $preTag .= '>';
899
                    }
900
                } else {
901
                    // Closing Tag
902
                    $preTag .= '</' . $tagName . '>';
903
                }
904
            }
905
            // Find next tag's start and continue iteration
906
            $postTag       = substr($postTag, $tagLength + 2);
907
            $tagOpen_start = strpos($postTag, '<');
908
        }
909
        // Append any code after the end of tags and return
910
        if ($postTag !== '<') {
911
            $preTag .= $postTag;
912
        }
913
914
        return $preTag;
915
    }
916
917
    /**
918
     * Internal method to strip a tag of certain attributes
919
     *
920
     * @access  protected
921
     *
922
     * @param array $attrSet Array of attribute pairs to filter
923
     *
924
     * @return array Filtered array of attribute pairs
925
     */
926
    protected function _cleanAttributes($attrSet)
927
    {
928
        // Initialize variables
929
        $newSet = array();
930
        // Iterate through attribute pairs
931
        for ($i = 0, $iMax = count($attrSet); $i < $iMax; ++$i) {
932
            // Skip blank spaces
933
            if (!$attrSet[$i]) {
934
                continue;
935
            }
936
            // Split into name/value pairs
937
            $attrSubSet = explode('=', trim($attrSet[$i]), 2);
938
            list($attrSubSet[0]) = explode(' ', $attrSubSet[0]);
939
            /*
940
             * Remove all "non-regular" attribute names
941
             * AND blacklisted attributes
942
             */
943
            if ((!preg_match('/[a-z]*$/i', $attrSubSet[0]))
944
                || ($this->xssAuto
945
                    && (in_array(strtolower($attrSubSet[0]), $this->attrBlacklist)
946
                        || (substr($attrSubSet[0], 0, 2) === 'on')))) {
947
                continue;
948
            }
949
            // XSS attribute value filtering
950
            if ($attrSubSet[1]) {
951
                // strips unicode, hex, etc
952
                $attrSubSet[1] = str_replace('&#', '', $attrSubSet[1]);
953
                // strip normal newline within attr value
954
                $attrSubSet[1] = preg_replace('/[\n\r]/', '', $attrSubSet[1]);
955
                // strip double quotes
956
                $attrSubSet[1] = str_replace('"', '', $attrSubSet[1]);
957
                // convert single quotes from either side to doubles (Single quotes shouldn't be used to pad attr value)
958
                if ((substr($attrSubSet[1], 0, 1) === "'")
959
                    && (substr($attrSubSet[1], strlen($attrSubSet[1]) - 1, 1) === "'")) {
960
                    $attrSubSet[1] = substr($attrSubSet[1], 1, -2);
961
                }
962
                // strip slashes
963
                $attrSubSet[1] = stripslashes($attrSubSet[1]);
964
            }
965
            // Autostrip script tags
966
            if (UserlogFilterInput::checkAttribute($attrSubSet)) {
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...
967
                continue;
968
            }
969
            // Is our attribute in the user input array?
970
            $attrFound = in_array(strtolower($attrSubSet[0]), $this->attrArray);
971
            // If the tag is allowed lets keep it
972
            if ((!$attrFound && $this->attrMethod) || ($attrFound && !$this->attrMethod)) {
973
                // Does the attribute have a value?
974
                if ($attrSubSet[1]) {
975
                    $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[1] . '"';
976
                } elseif ($attrSubSet[1] == '0') {
977
                    /*
978
                     * Special Case
979
                     * Is the value 0?
980
                     */
981
                    $newSet[] = $attrSubSet[0] . '="0"';
982
                } else {
983
                    $newSet[] = $attrSubSet[0] . '="' . $attrSubSet[0] . '"';
984
                }
985
            }
986
        }
987
988
        return $newSet;
989
    }
990
991
    /**
992
     * Try to convert to plaintext
993
     *
994
     * @access  protected
995
     *
996
     * @param string $source
997
     *
998
     * @return string Plaintext string
999
     */
1000
    protected function _decode($source)
1001
    {
1002
        // entity decode
1003
        $trans_tbl = get_html_translation_table(HTML_ENTITIES);
1004
        foreach ($trans_tbl as $k => $v) {
1005
            $ttr[$v] = utf8_encode($k);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ttr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ttr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1006
        }
1007
        $source = strtr($source, $ttr);
0 ignored issues
show
Bug introduced by
The variable $ttr does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1008
        // convert decimal
1009
        //$source = preg_replace('/&#(\d+);/me', "chr(\\1)", $source); // decimal notation
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1010
        //TODO swich to this once we have PHP 5.3 as minimum
1011
        //        $source = preg_replace_callback('/&#(\d+);/m', function($m) {return chr($m[1]);}, $source); // decimal notation
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1012
        $source = preg_replace_callback('/&#(\d+);/m', create_function('$matches', "return  chr(\$matches[1]);"), $source); // decimal notation
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1013
        // convert hex
1014
        //$source = preg_replace('/&#x([a-f0-9]+);/mei', "chr(0x\\1)", $source); // hex notation
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1015
        //TODO swich to this once we have PHP 5.3 as minimum
1016
        //        $source = preg_replace_callback('/&#x([a-f0-9]+);/mi', function($m) {return chr(hexdec($m[1]));}, $source); // hex notation
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1017
        $source = preg_replace_callback('/&#x([a-f0-9]+);/mi', create_function('$matches', "return  chr('0x'.\$matches[1]);"), $source);   // hex notation
0 ignored issues
show
Security Best Practice introduced by
The use of create_function is highly discouraged, better use a closure.

create_function can pose a great security vulnerability as it is similar to eval, and could be used for arbitrary code execution. We highly recommend to use a closure instead.

// Instead of
$function = create_function('$a, $b', 'return $a + $b');

// Better use
$function = function($a, $b) { return $a + $b; }
Loading history...
1018
1019
        return $source;
1020
    }
1021
}
1022