Passed
Push — master ( 02345f...0e807a )
by Fran
05:53 queued 14s
created

Request   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 282
Duplicated Lines 0 %

Coupling/Cohesion

Components 5
Dependencies 2

Test Coverage

Coverage 40%

Importance

Changes 0
Metric Value
dl 0
loc 282
ccs 32
cts 80
cp 0.4
rs 6.8539
c 0
b 0
f 0
wmc 54
lcom 5
cbo 2

26 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 13 9
A parseHeaders() 0 4 1
A hasHeader() 0 4 1
A hasCookies() 0 4 2
A hasUpload() 0 4 2
A ts() 0 4 1
A getTs() 0 4 2
A getMethod() 0 4 2
A header() 0 4 1
A getHeader() 0 8 2
A requestUri() 0 4 1
A getRequestUri() 0 4 2
A getLanguage() 0 4 2
A isFile() 0 5 1
A getQuery() 0 4 2
A getQueryParams() 0 4 1
A get() 0 4 2
A getData() 0 4 1
A redirect() 0 9 2
A getServer() 0 4 2
A getServerName() 0 4 1
A getProtocol() 0 4 3
B getRootUrl() 0 11 5
A getCookie() 0 4 2
A getFile() 0 4 2
A isAjax() 0 5 2

How to fix   Complexity   

Complex Class

Complex classes like Request often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Request, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\types\SingletonTrait;
6
7
if (!function_exists("getallheaders")) {
8
    function getallheaders()
9
    {
10 1
        $headers = array();
11 1
        foreach ($_SERVER as $h => $v)
12 1
            if (preg_match('/HTTP_(.+)/', $h, $hp))
13 1
                $headers[$hp[1]] = $v;
14 1
        return $headers;
15
    }
16
}
17
18
/**
19
 * Class Request
20
 * @package PSFS
21
 */
22
class Request
23
{
24
    use SingletonTrait;
25
    protected $server;
26
    protected $cookies;
27
    protected $upload;
28
    protected $header;
29
    protected $data;
30
    protected $query;
31
32
    /**
33
     */
34 1
    public function __construct()
35
    {
36 1
        $this->server = $_SERVER or [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
37 1
        $this->cookies = $_COOKIE or [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
38 1
        $this->upload = $_FILES or [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
39 1
        $this->header = $this->parseHeaders();
40 1
        $this->data = $_REQUEST or [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
41 1
        $this->query = $_GET or [];
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
42 1
        $contentType = (array_key_exists('Content-Type', $this->header)) ? $this->header['Content-Type'] : "text/html";
43 1
        if (preg_match('/application\/json/i', $contentType)) {
44
            $this->data += json_decode(file_get_contents("php://input"), true) ?: array();
45
        }
46 1
    }
47
48
    /**
49
     * Método que devuelve las cabeceras de la petición
50
     * @return array
51
     */
52 1
    private function parseHeaders()
53
    {
54 1
        return getallheaders();
55
    }
56
57
    /**
58
     * Método que verifica si existe una cabecera concreta
59
     * @param $header
60
     *
61
     * @return boolean
62
     */
63 1
    public function hasHeader($header)
64
    {
65 1
        return array_key_exists($header, $this->header);
66
    }
67
68
69
    /**
70
     * Método que indica si una petición tiene cookies
71
     * @return boolean
72
     */
73 1
    public function hasCookies()
74
    {
75 1
        return (null !== $this->cookies && 0 !== count($this->cookies));
76
    }
77
78
    /**
79
     * Método que indica si una petición tiene cookies
80
     * @return boolean
81
     */
82 1
    public function hasUpload()
83
    {
84 1
        return (null !== $this->upload && 0 !== count($this->upload));
85
    }
86
87
    /**
88
     * Método que devuelve el TimeStamp de la petición
89
     *
90
     * @param boolean $formatted
91
     *
92
     * @return string
93
     */
94
    public static function ts($formatted = false)
95
    {
96
        return self::getInstance()->getTs($formatted);
97
    }
98
99 1
    public function getTs($formatted = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
100
    {
101 1
        return ($formatted) ? date('Y-m-d H:i:s', $this->server['REQUEST_TIME_FLOAT']) : $this->server['REQUEST_TIME_FLOAT'];
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 125 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
102
    }
103
104
    /**
105
     * Método que devuelve el Método HTTP utilizado
106
     * @return string
107
     */
108 3
    public function getMethod()
109
    {
110 3
        return (array_key_exists('REQUEST_METHOD', $this->server)) ? strtoupper($this->server['REQUEST_METHOD']) : 'GET';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
111
    }
112
113
    /**
114
     * Método que devuelve una cabecera de la petición si existe
115
     * @param $name
116
     *
117
     * @return string|null
118
     */
119
    public static function header($name)
120
    {
121
        return self::getInstance()->getHeader($name);
122
    }
123
124
    public function getHeader($name)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
125
    {
126
        $header = null;
127
        if ($this->hasHeader($name)) {
128
            $header = $this->header[$name];
129
        }
130
        return $header;
131
    }
132
133
    /**
134
     * Método que devuelve la url solicitada
135
     * @return string|null
136
     */
137
    public static function requestUri()
138
    {
139
        return self::getInstance()->getRequestUri();
140
    }
141
142
    /**
143
     * @return string
144
     */
145 6
    public function getRequestUri()
146
    {
147 6
        return array_key_exists('REQUEST_URI', $this->server) ? $this->server['REQUEST_URI'] : '';
148
    }
149
150
    /**
151
     * Método que devuelve el idioma de la petición
152
     * @return string
153
     */
154
    public function getLanguage()
155
    {
156
        return array_key_exists('HTTP_ACCEPT_LANGUAGE', $this->server) ? $this->server['HTTP_ACCEPT_LANGUAGE'] : 'es_ES';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
157
    }
158
159
    /**
160
     * Método que determina si se ha solicitado un fichero
161
     * @return boolean
162
     */
163 4
    public function isFile()
164
    {
165 4
        $file = (preg_match('/\.[a-z0-9]{2,4}$/', $this->getRequestUri()) !== 0);
166 4
        return $file;
167
    }
168
169
    /**
170
     * Get query params
171
     *
172
     * @param string $queryParams
173
     *
174
     * @return mixed
175
     */
176
    public function getQuery($queryParams)
177
    {
178
        return (array_key_exists($queryParams, $this->query)) ? $this->query[$queryParams] : null;
179
    }
180
181
    /**
182
     * Get all query params
183
     *
184
     * @return mixed
185
     */
186
    public function getQueryParams()
187
    {
188
        return $this->query;
189
    }
190
191
    /**
192
     * Método que devuelve un parámetro de la solicitud
193
     * @param string $param
194
     *
195
     * @return string|null
196
     */
197
    public function get($param)
198
    {
199
        return (array_key_exists($param, $this->data)) ? $this->data[$param] : null;
200
    }
201
202
    /**
203
     * Método que devuelve todos los datos del Request
204
     * @return array
205
     */
206
    public function getData()
207
    {
208
        return $this->data;
209
    }
210
211
    /**
212
     * Método que realiza una redirección a la url dada
213
     * @param string $url
214
     */
215
    public function redirect($url = null)
216
    {
217
        if (null === $url) $url = $this->getServer('HTTP_ORIGIN');
218
        ob_start();
219
        header('Location: ' . $url);
220
        ob_end_clean();
221
        Security::getInstance()->updateSession();
222
        exit(_("Redireccionando..."));
223
    }
224
225
    /**
226
     * Devuelve un parámetro de $_SERVER
227
     * @param string $param
228
     *
229
     * @return string|null
230
     */
231 2
    public function getServer($param)
232
    {
233 2
        return array_key_exists($param, $this->server) ? $this->server[$param] : null;
234
    }
235
236
    /**
237
     * Devuelve el nombre del servidor
238
     * @return string|null
239
     */
240
    public function getServerName()
241
    {
242
        return $this->getServer("SERVER_NAME");
243
    }
244
245
    /**
246
     * Devuelve el protocolo de la conexión
247
     * @return string
248
     */
249
    public function getProtocol()
250
    {
251
        return ($this->getServer("HTTPS") || $this->getServer("https")) ? 'https://' : 'http://';
252
    }
253
254
    /**
255
     * Devuelve la url completa de base
256
     * @param boolean $protocol
257
     * @return string
258
     */
259
    public function getRootUrl($protocol = true)
260
    {
261
        $host = $this->getServerName();
262
        $protocol = $protocol ? $this->getProtocol() : '';
263
        $url = '';
264
        if (!empty($host) && !empty($protocol)) $url = $protocol . $host;
265
        if (!in_array($this->getServer('SERVER_PORT'), [80, 443])) {
266
            $url .= ':' . $this->getServer('SERVER_PORT');
267
        }
268
        return $url;
269
    }
270
271
    /**
272
     * Método que devuelve el valor de una cookie en caso de que exista
273
     * @param string $name
274
     *
275
     * @return string
276
     */
277
    public function getCookie($name)
278
    {
279
        return array_key_exists($name, $this->cookies) ? $this->cookies[$name] : null;
280
    }
281
282
    /**
283
     * Método que devuelve los files subidos por POST
284
     * @param $name
285
     *
286
     * @return array
287
     */
288
    public function getFile($name)
289
    {
290
        return array_key_exists($name, $this->upload) ? $this->upload[$name] : array();
291
    }
292
293
    /**
294
     * Método que devuelve si la petición es ajax o no
295
     * @return boolean
296
     */
297 1
    public function isAjax()
298
    {
299 1
        $requested = $this->getServer("HTTP_X_REQUESTED_WITH");
300 1
        return (null !== $requested && strtolower($requested) == 'xmlhttprequest');
301
    }
302
303
}
304