Completed
Branch master (740422)
by Mathieu
02:04
created

Request::getHeaders()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Suricate;
3
4
class Request
5
{
6
    const HTTP_METHOD_GET       = 'GET';
7
    const HTTP_METHOD_POST      = 'POST';
8
    const HTTP_METHOD_PUT       = 'PUT';
9
    const HTTP_METHOD_DELETE    = 'DELETE';
10
    const HTTP_METHOD_HEAD      = 'HEAD';
11
    const HTTP_METHOD_OPTIONS   = 'OPTIONS';
12
13
    private $method = self::HTTP_METHOD_GET;
14
    private $methods = array(
15
            self::HTTP_METHOD_GET       => 'GET',
16
            self::HTTP_METHOD_POST      => 'POST',
17
            self::HTTP_METHOD_PUT       => 'PUT',
18
            self::HTTP_METHOD_DELETE    => 'DELETE',
19
            self::HTTP_METHOD_HEAD      => 'HEAD',
20
            self::HTTP_METHOD_OPTIONS   => 'OPTIONS'
21
        );
22
23
    private $httpCodeString = array(
24
                    100 => 'Continue',
25
                    101 => 'Switching Protocols',
26
                    102 => 'Processing',
27
                    200 => 'OK',
28
                    201 => 'Created',
29
                    202 => 'Accepted',
30
                    203 => 'Non-Authoritative Information',
31
                    204 => 'No Content',
32
                    205 => 'Reset Content',
33
                    206 => 'Partial Content',
34
                    207 => 'Multi-Status',
35
                    208 => 'Already Reported',
36
                    226 => 'IM Used',
37
                    250 => 'Low on Storage Space',
38
                    300 => 'Multiple Choices',
39
                    301 => 'Moved Permanently',
40
                    302 => 'Found',
41
                    303 => 'See Other',
42
                    304 => 'Not Modified',
43
                    305 => 'Use Proxy',
44
                    306 => '306 Switch Proxy',
45
                    307 => 'Temporary Redirect',
46
                    308 => 'Permanent Redirect',
47
                    400 => 'Bad Request',
48
                    401 => 'Unauthorized',
49
                    402 => 'Payment Required',
50
                    403 => 'Forbidden',
51
                    404 => 'Not Found',
52
                    405 => 'Method Not Allowed',
53
                    406 => 'Not Acceptable',
54
                    407 => 'Proxy Authentication Required',
55
                    408 => 'Request Timeout',
56
                    409 => 'Conflict',
57
                    410 => 'Gone',
58
                    411 => 'Length Required',
59
                    412 => 'Precondition Failed',
60
                    413 => 'Request Entity Too Large',
61
                    414 => 'Request-URI Too Long',
62
                    415 => 'Unsupported Media Type',
63
                    416 => 'Requested Range Not Satisfiable',
64
                    417 => 'Expectation Failed',
65
                    422 => 'Unprocessable Entity',
66
                    423 => 'Locked',
67
                    424 => 'Failed Dependency',
68
                    425 => 'Unordered Collection',
69
                    426 => 'Upgrade Required',
70
                    428 => 'Precondition Required',
71
                    429 => 'Too Many Requests',
72
                    431 => 'Request Header Fields Too Large',
73
                    444 => 'No Response',
74
                    449 => 'Retry With',
75
                    450 => 'Blocked by Windows Parental Controls',
76
                    494 => 'Request Header Too Large',
77
                    495 => 'Cert Error',
78
                    496 => 'No Cert',
79
                    497 => 'HTTP to HTTPS',
80
                    499 => 'Client Closed Request',
81
                    500 => 'Internal Server Error',
82
                    501 => 'Not Implemented',
83
                    502 => 'Bad Gateway',
84
                    503 => 'Service Unavailable',
85
                    504 => 'Gateway Timeout',
86
                    505 => 'HTTP Version Not Supported',
87
                    506 => 'Variant Also Negotiates',
88
                    507 => 'Insufficient Storage',
89
                    508 => 'Loop Detected',
90
                    509 => 'Bandwidth Limit Exceeded',
91
                    510 => 'Not Extended',
92
                    511 => 'Network Authentication Required'
93
        );
94
95
    private $httpCode;
96
    private $headers;
97
    private $requestUri;
98
    private $url;
99
    private $body;
100
    private $flashData = array();
0 ignored issues
show
Unused Code introduced by
The property $flashData is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
101
    private $path;
102
    private $query;
103
104 8
    public function __construct()
105
    {
106 8
        $this->headers  = array();
107 8
        $this->httpCode = 200;
108 8
    }
109
110
    public function parse()
0 ignored issues
show
Coding Style introduced by
parse 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
parse 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...
111
    {
112
        if (isset($_SERVER['REQUEST_URI'])) {
113
            $this->setRequestUri($_SERVER['REQUEST_URI']);
114
            $parseResult = parse_url($_SERVER['REQUEST_URI']);
115
            $this->path     = dataGet($parseResult, 'path');
116
            $this->query    = dataGet($parseResult, 'query');
117
        }
118
119
        if (isset($_SERVER['REQUEST_METHOD'])) {
120
            $this->setMethod($_SERVER['REQUEST_METHOD']);
121
        }
122
        if (isset($_POST['_method'])) {
123
            $this->setMethod($_POST['_method']);
124
        }
125
126
    }
127
128 1
    public function setMethod($method)
129
    {
130
        if (!isset($this->methods[$method])) {
131
            throw new \InvalidArgumentException('Invalid HTTP Method ' . $method);
132
        }
133
134 1
        $this->method = $method;
135
136 1
        return $this;
137
    }
138
139 1
    public function getMethod()
140
    {
141 1
        return $this->method;
142
    }
143
144
    public function setUrl($url)
145
    {
146
        $this->url = $url;
147
148
        return $this;
149
    }
150
    public function getUrl()
151
    {
152
        return $this->url;
153
    }
154
155 1
    public function setRequestUri($uri)
156
    {
157 1
        $this->requestUri = $uri;
158
159 1
        return $this;
160
    }
161
162 3
    public function getRequestUri()
163
    {
164 3
        return $this->requestUri;
165
    }
166
167 1
    public function getPath()
168
    {
169 1
        return $this->path;
170
    }
171
172 1
    public function getQuery()
173
    {
174 1
        return $this->query;
175
    }
176
177 1
    public static function getPostParam($variable, $defaultValue = null)
0 ignored issues
show
Coding Style introduced by
getPostParam 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...
178
    {
179
        if (isset($_POST[$variable])) {
180
            return $_POST[$variable];
181
        }
182 1
        return $defaultValue;
183
    }
184
185 1
    public static function getParam($variable, $defaultValue = null)
0 ignored issues
show
Coding Style introduced by
getParam 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
getParam 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...
186
    {
187
        if (isset($_GET[$variable])) {
188 1
            return $_GET[$variable];
189
        } elseif (isset($_POST[$variable])) {
190
            return $_POST[$variable];
191
        } else {
192 1
            return $defaultValue;
193
        }
194
    }
195
196
    public static function hasParam($variable)
0 ignored issues
show
Coding Style introduced by
hasParam 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
hasParam 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...
197
    {
198
        return isset($_GET[$variable]) || isset($_POST[$variable]);
199
    }
200
201
       
202
    public function setHeaders($headers)
203
    {
204
        $this->headers = $headers;
205
206
        return $this;
207
    }
208
209
    public function addHeader($header, $value)
210
    {
211
        $this->headers[$header] = $value;
212
213
        return $this;
214
    }
215
216
    public function getHeaders()
217
    {
218
        return $this->headers;
219
    }
220
221
222 1
    public function setContentType($content_type, $encoding = null)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $content_type is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
223
    {
224
        if ($encoding !== null) {
225 1
            $content_type .= '; charset=' . $encoding;
226
        }
227
        $this->addHeader('Content-type', $content_type);
228
229
        return $this;
230 1
    }
231
232 1
    public function setBody($body)
233
    {
234 1
        $this->body = $body;
235
236 1
        return $this;
237
    }
238
239 1
    public function getBody()
240
    {
241 1
        return $this->body;
242
    }
243
244
245
    public function write()
246
    {
247
        if (!headers_sent()) {
248
            if (substr(php_sapi_name(), 0, 3) == 'cgi') {
249
                $headerString = 'Status: ' . self::getStringForHttpCode();
250
            } else {
251
                $headerString = 'HTTP/1.1 ' . self::getStringForHttpCode();
252
            }
253
254
            header($headerString);
255
256
            // Send headers
257
            foreach ($this->headers as $headerName => $headerValue) {
258
                header($headerName . ':' . $headerValue);
259
            }
260
        }
261
262
        /**
263
         TODO HANDLE HTTP RESPONSE CODE
264
         */
265
        if ($this->httpCode !== null) {
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...
266
267
        }
268
269
        // Send body
270
        echo $this->body;
271
    }
272
273
    //
274
    // HTTP Code
275
    //
276
277
    public function setHttpCode($code)
278
    {
279
        $this->httpCode = $code;
280
281
        return $this;
282
    }
283
284 1
    public function getHttpCode()
285
    {
286 1
        return $this->httpCode;
287
    }
288
289
    public function flash($type, $data)
290
    {
291
        Flash::write($type, $data);
292
        
293
        return $this;
294
    }
295
296
    public function flashData($name, $value)
297
    {
298
        Flash::write('data', array($name => $value));
299
300
        return $this;
301
    }
302
303
    public function redirect($url, $httpCode = 302)
304
    {
305
        $this->setHttpCode($httpCode);
306
        $this->addHeader('Location', $url);
307
308
        $this->write();
309
        die();
0 ignored issues
show
Coding Style Compatibility introduced by
The method redirect() 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...
310
    }
311
312
    public function redirectWithSuccess($url, $message)
313
    {
314
        $this
315
            ->flash('success', $message)
316
            ->redirect($url);
317
    }
318
319
    public function redirectWithInfo($url, $message)
320
    {
321
        $this
322
            ->flash('info', $message)
323
            ->redirect($url);
324
    }
325
326
    public function redirectWithError($url, $message)
327
    {
328
        $this
329
            ->flash('error', $message)
330
            ->redirect($url);
331
    }
332
333
    public function redirectWithData($url, $key, $value)
334
    {
335
        $this
336
            ->flashData($key, $value)
337
            ->redirect($url);
338
    }
339
340
    public function isOK()
341
    {
342
        return ( $this->httpCode == 200 );
343
    }
344
345
    public function isRedirect()
346
    {
347
        return ( $this->httpCode >= 300 && $this->httpCode < 400 );
348
    }
349
350
    public function isClientError()
351
    {
352
        return ( $this->httpCode >= 400 && $this->httpCode < 500 );
353
    }
354
355
    public function isServerError()
356
    {
357
        return ( $this->httpCode >= 500 && $this->httpCode < 600 );
358
    }
359
360 1
    private function getStringForHttpCode()
361
    {
362
        if (isset($this->httpCodeString[$this->httpCode])) {
363 1
            return $this->httpCode . ' ' . $this->httpCodeString[$this->httpCode];
364
        }
365 1
    }
366
}
367