Passed
Push — master ( de4070...2f1ea7 )
by Fran
03:15
created

Request::getHeader()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5.9256

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 9
c 1
b 0
f 0
nc 8
nop 2
dl 0
loc 12
ccs 6
cts 9
cp 0.6667
crap 5.9256
rs 8.8571
1
<?php
2
namespace PSFS\base;
3
4
use PSFS\base\types\traits\SingletonTrait;
5
6
/**
7
 * Class Request
8
 * @package PSFS
9
 */
10
class Request
11
{
12
    use SingletonTrait;
13
    protected $server;
14
    protected $cookies;
15
    protected $upload;
16
    protected $header;
17
    protected $data;
18
    protected $raw = [];
19
    protected $query;
20
    private $isLoaded = false;
21
22 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...
23
    {
24 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...
25 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...
26 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...
27 2
        $this->header = $this->parseHeaders();
28 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...
29 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...
30 2
        $this->raw = json_decode(file_get_contents("php://input"), true) ?: [];
31 2
        $this->isLoaded = true;
32 2
    }
33
34
    /**
35
     * @return bool
36
     */
37 1
    public function isLoaded() {
38 1
        return $this->isLoaded;
39
    }
40
41
    /**
42
     * Método que devuelve las cabeceras de la petición
43
     * @return array
44
     */
45 2
    private function parseHeaders()
46
    {
47 2
        return getallheaders();
48
    }
49
50
    /**
51
     * Método que verifica si existe una cabecera concreta
52
     * @param $header
53
     *
54
     * @return boolean
55
     */
56 3
    public function hasHeader($header)
57
    {
58 3
        return array_key_exists($header, $this->header);
59
    }
60
61
62
    /**
63
     * Método que indica si una petición tiene cookies
64
     * @return boolean
65
     */
66 1
    public function hasCookies()
67
    {
68 1
        return (null !== $this->cookies && 0 !== count($this->cookies));
69
    }
70
71
    /**
72
     * Método que indica si una petición tiene cookies
73
     * @return boolean
74
     */
75 1
    public function hasUpload()
76
    {
77 1
        return (null !== $this->upload && 0 !== count($this->upload));
78
    }
79
80
    /**
81
     * Método que devuelve el TimeStamp de la petición
82
     *
83
     * @param boolean $formatted
84
     *
85
     * @return string
86
     */
87
    public static function ts($formatted = false)
88
    {
89
        return self::getInstance()->getTs($formatted);
90
    }
91
92 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...
93
    {
94 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...
95
    }
96
97
    /**
98
     * Método que devuelve el Método HTTP utilizado
99
     * @return string
100
     */
101 4
    public function getMethod()
102
    {
103 4
        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...
104
    }
105
106
    /**
107
     * Método que devuelve una cabecera de la petición si existe
108
     * @param string $name
109
     * @param string $default
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...
110
     *
111
     * @return string|null
112
     */
113 2
    public static function header($name, $default = null)
114
    {
115 2
        return self::getInstance()->getHeader($name,  $default);
116
    }
117
118
    /**
119
     * @param string $name
120
     * @param string $default
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...
121
     * @return string|null
122
     */
123 2
    public function getHeader($name, $default = null)
124
    {
125 2
        $header = null;
126 2
        if ($this->hasHeader($name)) {
127
            $header = $this->header[$name];
128 2
        } else if(array_key_exists('h_' . strtolower($name), $this->query)) {
129
            $header = $this->query['h_' . strtolower($name)];
130 2
        } else if(array_key_exists('HTTP_' . strtoupper(str_replace('-', '_', $name)), $this->server)) {
131
            $header = $this->server['HTTP_' . strtoupper(str_replace('-', '_', $name))];
132
        }
133 2
        return $header ?: $default;
134
    }
135
136
    /**
137
     * Método que devuelve la url solicitada
138
     * @return string|null
139
     */
140 1
    public static function requestUri()
141
    {
142 1
        return self::getInstance()->getRequestUri();
143
    }
144
145
    /**
146
     * @return string
147
     */
148 7
    public function getRequestUri()
149
    {
150 7
        return array_key_exists('REQUEST_URI', $this->server) ? $this->server['REQUEST_URI'] : '';
151
    }
152
153
    /**
154
     * Método que devuelve el idioma de la petición
155
     * @return string
156
     */
157
    public function getLanguage()
158
    {
159
        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...
160
    }
161
162
    /**
163
     * Método que determina si se ha solicitado un fichero
164
     * @return boolean
165
     */
166 4
    public function isFile()
167
    {
168 4
        $file = (preg_match('/\.[a-z0-9]{2,4}$/', $this->getRequestUri()) !== 0);
169 4
        return $file;
170
    }
171
172
    /**
173
     * Get query params
174
     *
175
     * @param string $queryParams
176
     *
177
     * @return mixed
178
     */
179
    public function getQuery($queryParams)
180
    {
181
        return (array_key_exists($queryParams, $this->query)) ? $this->query[$queryParams] : null;
182
    }
183
184
    /**
185
     * Get all query params
186
     *
187
     * @return mixed
188
     */
189 1
    public function getQueryParams()
190
    {
191 1
        return $this->query;
192
    }
193
194
    /**
195
     * Método que devuelve un parámetro de la solicitud
196
     * @param string $param
197
     *
198
     * @return string|null
199
     */
200
    public function get($param)
201
    {
202
        return (array_key_exists($param, $this->data)) ? $this->data[$param] : null;
203
    }
204
205
    /**
206
     * Método que devuelve todos los datos del Request
207
     * @return array
208
     */
209 1
    public function getData()
210
    {
211 1
        return array_merge($this->data, $this->raw);
212
    }
213
214
    /**
215
     * @return array
216
     */
217
    public function getRawData() {
218
        return $this->raw;
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 5
    public function getServer($param)
242
    {
243 5
        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 2
    public function getServerName()
251
    {
252 2
        return $this->getServer("SERVER_NAME");
253
    }
254
255
    /**
256
     * Devuelve el protocolo de la conexión
257
     * @return string
258
     */
259 2
    public function getProtocol()
260
    {
261 2
        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 2
    public function getRootUrl($protocol = true)
270
    {
271 2
        $url = $this->getServerName();
272 2
        $protocol = $protocol ? $this->getProtocol() : '';
273 2
        if (!empty($protocol)) $url = $protocol . $url;
274 2
        if (!in_array($this->getServer('SERVER_PORT'), [80, 443])) {
275 2
            $url .= ':' . $this->getServer('SERVER_PORT');
276
        }
277 2
        return $url;
278
    }
279
280
    /**
281
     * Método que devuelve el valor de una cookie en caso de que exista
282
     * @param string $name
283
     *
284
     * @return string
285
     */
286 1
    public function getCookie($name)
287
    {
288 1
        return array_key_exists($name, $this->cookies) ? $this->cookies[$name] : null;
289
    }
290
291
    /**
292
     * Método que devuelve los files subidos por POST
293
     * @param $name
294
     *
295
     * @return array
296
     */
297
    public function getFile($name)
298
    {
299
        return array_key_exists($name, $this->upload) ? $this->upload[$name] : array();
300
    }
301
302
    /**
303
     * Método que devuelve si la petición es ajax o no
304
     * @return boolean
305
     */
306 1
    public function isAjax()
307
    {
308 1
        $requested = $this->getServer("HTTP_X_REQUESTED_WITH");
309 1
        return (null !== $requested && strtolower($requested) == 'xmlhttprequest');
310
    }
311
312
}
313