Passed
Push — master ( b17869...4a30ca )
by Fran
05:09
created

Request::init()   C

Complexity

Conditions 10
Paths 288

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 10.1953

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 13
c 1
b 0
f 0
nc 288
nop 0
dl 0
loc 17
ccs 14
cts 16
cp 0.875
crap 10.1953
rs 6

How to fix   Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace PSFS\base;
4
5
use PSFS\base\types\SingletonTrait;
6
7
if (!function_exists("getallheaders")) {
8
    function getallheaders()
9
    {
10 2
        $headers = array();
11 2
        foreach ($_SERVER as $h => $v)
12 2
            if (preg_match('/HTTP_(.+)/', $h, $hp))
13 2
                $headers[$hp[1]] = $v;
14 2
        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
    private $isLoaded = false;
32
33 2
    public function init()
0 ignored issues
show
Coding Style introduced by
init 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
init 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
init 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
init 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
init 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...
34
    {
35 2
        $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...
36 2
        $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...
37 2
        $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...
38 2
        $this->header = $this->parseHeaders();
39 2
        $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...
40 2
        $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...
41 2
        $contentType = $this->getHeader('Content-Type');
42 2
        if(null === $contentType) {
43 2
            $contentType = $this->getServer('CONTENT_TYPE') ?: 'text/html';
44 2
        }
45 2
        if (preg_match('/application\/json/i', $contentType)) {
46
            $this->data += json_decode(file_get_contents("php://input"), true) ?: array();
47
        }
48 2
        $this->isLoaded = true;
49 2
    }
50
51
    /**
52
     * @return bool
53
     */
54 1
    public function isLoaded() {
55 1
        return $this->isLoaded;
56
    }
57
58
    /**
59
     * Método que devuelve las cabeceras de la petición
60
     * @return array
61
     */
62 2
    private function parseHeaders()
63
    {
64 2
        return getallheaders();
65
    }
66
67
    /**
68
     * Método que verifica si existe una cabecera concreta
69
     * @param $header
70
     *
71
     * @return boolean
72
     */
73 3
    public function hasHeader($header)
74
    {
75 3
        return array_key_exists($header, $this->header);
76
    }
77
78
79
    /**
80
     * Método que indica si una petición tiene cookies
81
     * @return boolean
82
     */
83 1
    public function hasCookies()
84
    {
85 1
        return (null !== $this->cookies && 0 !== count($this->cookies));
86
    }
87
88
    /**
89
     * Método que indica si una petición tiene cookies
90
     * @return boolean
91
     */
92 1
    public function hasUpload()
93
    {
94 1
        return (null !== $this->upload && 0 !== count($this->upload));
95
    }
96
97
    /**
98
     * Método que devuelve el TimeStamp de la petición
99
     *
100
     * @param boolean $formatted
101
     *
102
     * @return string
103
     */
104
    public static function ts($formatted = false)
105
    {
106
        return self::getInstance()->getTs($formatted);
107
    }
108
109 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...
110
    {
111 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...
112
    }
113
114
    /**
115
     * Método que devuelve el Método HTTP utilizado
116
     * @return string
117
     */
118 3
    public function getMethod()
119
    {
120 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...
121
    }
122
123
    /**
124
     * Método que devuelve una cabecera de la petición si existe
125
     * @param $name
126
     *
127
     * @return string|null
128
     */
129
    public static function header($name)
130
    {
131
        return self::getInstance()->getHeader($name);
132
    }
133
134 2
    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...
135
    {
136 2
        $header = null;
137 2
        if ($this->hasHeader($name)) {
138
            $header = $this->header[$name];
139
        }
140 2
        return $header;
141
    }
142
143
    /**
144
     * Método que devuelve la url solicitada
145
     * @return string|null
146
     */
147
    public static function requestUri()
148
    {
149
        return self::getInstance()->getRequestUri();
150
    }
151
152
    /**
153
     * @return string
154
     */
155 6
    public function getRequestUri()
156
    {
157 6
        return array_key_exists('REQUEST_URI', $this->server) ? $this->server['REQUEST_URI'] : '';
158
    }
159
160
    /**
161
     * Método que devuelve el idioma de la petición
162
     * @return string
163
     */
164
    public function getLanguage()
165
    {
166
        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...
167
    }
168
169
    /**
170
     * Método que determina si se ha solicitado un fichero
171
     * @return boolean
172
     */
173 4
    public function isFile()
174
    {
175 4
        $file = (preg_match('/\.[a-z0-9]{2,4}$/', $this->getRequestUri()) !== 0);
176 4
        return $file;
177
    }
178
179
    /**
180
     * Get query params
181
     *
182
     * @param string $queryParams
183
     *
184
     * @return mixed
185
     */
186
    public function getQuery($queryParams)
187
    {
188
        return (array_key_exists($queryParams, $this->query)) ? $this->query[$queryParams] : null;
189
    }
190
191
    /**
192
     * Get all query params
193
     *
194
     * @return mixed
195
     */
196
    public function getQueryParams()
197
    {
198
        return $this->query;
199
    }
200
201
    /**
202
     * Método que devuelve un parámetro de la solicitud
203
     * @param string $param
204
     *
205
     * @return string|null
206
     */
207
    public function get($param)
208
    {
209
        return (array_key_exists($param, $this->data)) ? $this->data[$param] : null;
210
    }
211
212
    /**
213
     * Método que devuelve todos los datos del Request
214
     * @return array
215
     */
216
    public function getData()
217
    {
218
        return $this->data;
219
    }
220
221
    /**
222
     * Método que realiza una redirección a la url dada
223
     * @param string $url
224
     */
225
    public function redirect($url = null)
226
    {
227
        if (null === $url) $url = $this->getServer('HTTP_ORIGIN');
228
        ob_start();
229
        header('Location: ' . $url);
230
        ob_end_clean();
231
        Security::getInstance()->updateSession();
232
        exit(_("Redireccionando..."));
233
    }
234
235
    /**
236
     * Devuelve un parámetro de $_SERVER
237
     * @param string $param
238
     *
239
     * @return string|null
240
     */
241 3
    public function getServer($param)
242
    {
243 3
        return array_key_exists($param, $this->server) ? $this->server[$param] : null;
244
    }
245
246
    /**
247
     * Devuelve el nombre del servidor
248
     * @return string|null
249
     */
250
    public function getServerName()
251
    {
252
        return $this->getServer("SERVER_NAME");
253
    }
254
255
    /**
256
     * Devuelve el protocolo de la conexión
257
     * @return string
258
     */
259
    public function getProtocol()
260
    {
261
        return ($this->getServer("HTTPS") || $this->getServer("https")) ? 'https://' : 'http://';
262
    }
263
264
    /**
265
     * Devuelve la url completa de base
266
     * @param boolean $protocol
267
     * @return string
268
     */
269
    public function getRootUrl($protocol = true)
270
    {
271
        $host = $this->getServerName();
272
        $protocol = $protocol ? $this->getProtocol() : '';
273
        $url = '';
274
        if (!empty($host) && !empty($protocol)) $url = $protocol . $host;
275
        if (!in_array($this->getServer('SERVER_PORT'), [80, 443])) {
276
            $url .= ':' . $this->getServer('SERVER_PORT');
277
        }
278
        return $url;
279
    }
280
281
    /**
282
     * Método que devuelve el valor de una cookie en caso de que exista
283
     * @param string $name
284
     *
285
     * @return string
286
     */
287 1
    public function getCookie($name)
288
    {
289 1
        return array_key_exists($name, $this->cookies) ? $this->cookies[$name] : null;
290
    }
291
292
    /**
293
     * Método que devuelve los files subidos por POST
294
     * @param $name
295
     *
296
     * @return array
297
     */
298
    public function getFile($name)
299
    {
300
        return array_key_exists($name, $this->upload) ? $this->upload[$name] : array();
301
    }
302
303
    /**
304
     * Método que devuelve si la petición es ajax o no
305
     * @return boolean
306
     */
307 1
    public function isAjax()
308
    {
309 1
        $requested = $this->getServer("HTTP_X_REQUESTED_WITH");
310 1
        return (null !== $requested && strtolower($requested) == 'xmlhttprequest');
311
    }
312
313
}
314