Passed
Push — master ( a3c74f...35b0eb )
by Stefan
05:55
created

Request::uriWithQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Nono;
4
5
/**
6
 * Simple request class, which is passed as the first argument to
7
 * any callable / controller method associated with a route.
8
 *
9
 * @method string|mixed get(string $name = null, mixed $default = null)
10
 * @method string|mixed post(string $name = null, mixed $default = null)
11
 * @method string|mixed query(string $name = null, mixed $default = null)
12
 * @method string|mixed request(string $name = null, mixed $default = null)
13
 * @method string|mixed server(string $name = null, mixed $default = null)
14
 * @method string|mixed session(string $name = null, mixed $default = null)
15
 * @method string|mixed cookie(string $name = null, mixed $default = null)
16
 * @method array|mixed  files(string $name = null, mixed $default = null)
17
 */
18
class Request
19
{
20
    /**
21
     * Just triggering the super global and fill the query global.
22
     */
23 19
    public function __construct()
0 ignored issues
show
Coding Style introduced by
__construct 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
__construct 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...
24
    {
25 19
        $_SERVER;
26 19
        if (!in_array($this->method(), ['GET', 'POST'])) {
27 1
            parse_str(file_get_contents('php://input'), $GLOBALS['_QUERY']);
28 1
        }
29 19
    }
30
31
    /**
32
     * Return URI with query string.
33
     *
34
     * @return string
35
     */
36 6
    public function uriWithQuery()
37
    {
38 6
        return urldecode($this->server('REQUEST_URI'));
39
    }
40
41
    /**
42
     * Return URI without query string.
43
     *
44
     * @return string
45
     */
46 5
    public function uri()
47
    {
48 5
        return explode('?', $this->uriWithQuery())[0];
49
    }
50
51
    /**
52
     * Return the http verb.
53
     *
54
     * @return string
55
     */
56 19
    public function method()
57
    {
58 19
        return $this->server('REQUEST_METHOD');
59
    }
60
61
    /**
62
     * Return whether the request URL is HTTPS URL or not.
63
     * Questionable reliability -> depends upon server config.
64
     *
65
     * @return string
66
     */
67 1
    public function isHttps()
68
    {
69 1
        return $this->server('SERVER_PORT') == 443
70 1
            || strtoupper($this->server('HTTPS')) == 'ON';
71
    }
72
73
    /**
74
     * Return the hostname.
75
     *
76
     * @return string
77
     */
78 1
    public function host()
79
    {
80 1
        return $this->server('HTTP_HOST');
81
    }
82
83
    /**
84
     * Return the time the request was initiated.
85
     *
86
     * @return float
87
     */
88 1
    public function requestTimeFloat()
89
    {
90 1
        return $this->server('REQUEST_TIME_FLOAT');
91
    }
92
93
    /**
94
     * Return the elapsed time since the request was initiated.
95
     *
96
     * @return float
97
     */
98 1
    public function elapsedRequestTimeFloat()
99
    {
100 1
        return microtime(1) - $this->server('REQUEST_TIME_FLOAT');
101
    }
102
103
    /**
104
     * Allow redirects when headers have already been sent
105
     * due to sessions or other output.
106
     *
107
     * @param string $url
108
     */
109 1
    public function redirect($url)
110
    {
111 1
        echo "<script>location.replace('$url');</script>";
112 1
    }
113
114
    /**
115
     * Magic method to access super globals with optional default argument.
116
     * Calling without arguments e.g. $request->server() will simply
117
     * return the entire _SERVER global.
118
     *
119
     * @param string $name
120
     * @param array  $args
121
     * @return mixed
122
     */
123 19
    public function __call($name, $args)
0 ignored issues
show
Coding Style introduced by
__call 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...
124
    {
125 19
        $global = $GLOBALS['_' . strtoupper($name)];
126 19
        $default = isset($args[1]) ? $args[1] : null;
127
128 19
        if (!count($args)) {
129 1
            return $global;
130 19
        } elseif (isset($global[$args[0]])) {
131 18
            return $global[$args[0]];
132
        } else {
133 3
            return $default;
134
        }
135
    }
136
}
137
138