Passed
Push — master ( 5ae195...c1faee )
by Nícollas
02:35 queued 56s
created

Request::resolveRouteData()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 27
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 14
nc 9
nop 2
dl 0
loc 27
rs 8.8333
c 2
b 0
f 0
1
<?php
2
3
namespace MinasRouter\Http;
4
5
class Request
6
{
7
    private $fullUrl;
8
9
    private $httpMethod;
10
11
    private $data = [];
12
13
    private $queryStrings;
14
15
    private $params;
16
17
    private $headers;
18
19
    public function __construct(
20
        String $fullUrl,
21
        String $route,
22
        array $routeParams
23
    ) {
24
        $this->fullUrl = $fullUrl . ($_SERVER['REQUEST_URI'] ?? '/');
25
26
        $this->httpMethod = $_SERVER['REQUEST_METHOD'] ?? '';
27
        $this->queryStrings = $_GET;
28
        
29
        if(isset($this->queryStrings["route"])) {
30
            unset($this->queryStrings["route"]);
31
        }
32
33
        $this->headers = $this->resolveHeaders();
34
35
        $this->resolveRouteData($route, $routeParams);
36
37
        if ($this->httpMethod != 'GET') {
38
            $this->setData();
39
        }
40
    }
41
42
    /**
43
     * Method responsible for bringing
44
     * all request headers.
45
     * 
46
     * @return array
47
     */
48
    protected function resolveHeaders()
49
    {
50
        $headers = [];
51
52
        foreach ($_SERVER as $name => $value) {
53
            if (substr($name, 0, 5) == 'HTTP_') {
54
                $index = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
55
                $headers[$index] = $value;
56
            }
57
        }
58
59
        return $headers;
60
    }
61
62
    /**
63
     * Method responsible for returning the
64
     * route's dynamic parameters.
65
     * 
66
     * @return array
67
     */
68
    public function getParams()
69
    {
70
        return $this->params ?? $this->data;
71
    }
72
73
    /**
74
     * Method responsible for returning one or all
75
     * data coming from the params query ($_GET).
76
     * 
77
     * @return null|string $name = null
78
     * 
79
     * @return array|string
80
     */
81
    public function getQueryString(?String $name = null)
82
    {
83
        if ($name && isset($this->queryStrings[$name])) {
84
            return $this->queryStrings[$name];
85
        }
86
87
        return $this->queryStrings;
88
    }
89
90
    /**
91
     * Returns a property that does not exist in the class,
92
     * usually they are indexes of the route array. Returns null
93
     * if this index/property does not exist.
94
     * 
95
     * @param string $data
96
     * 
97
     * @return string|null|array
98
     */
99
    public function __get(String $data)
100
    {
101
        if(isset($this->data[$data])) {
102
            return $this->data[$data];
103
        }
104
105
        if(isset($this->queryStrings[$data])) {
106
            return $this->queryStrings[$data];
107
        }
108
109
        if(isset($this->params[$data])) {
110
            return $this->params[$data];
111
        }
112
113
        return null;
114
    }
115
116
    /**
117
     * Method responsible for defining route data
118
     * 
119
     * @param string $route
120
     * @param array $routeParams
121
     * 
122
     * @return void
123
     */
124
    protected function resolveRouteData(String $route, array $routeParams): void
125
    {
126
        $params = parse_url($this->fullUrl);
127
128
        $diff = array_diff(explode('/', $params['path']), explode('/', $route));
129
130
        $diff = array_values($diff);
131
132
        if (!empty($diff)) {
133
            foreach ($routeParams as $index => $param) {
134
                if (!isset($diff[$index])) return;
135
136
                if ($this->httpMethod != 'GET') {
137
                    $this->params[$param] = rawurldecode($diff[$index]);
138
                    continue;
139
                }
140
141
                $this->data[$param] = rawurldecode($diff[$index]);
142
            }
143
        }
144
145
        if(empty($this->data)) {
146
            $this->data = [];
147
        }
148
149
        if(empty($this->params)) {
150
            $this->params = [];
151
        }
152
    }
153
154
    /**
155
     * Method responsible for assigning and handling
156
     * the data coming from the web form.
157
     * 
158
     * @return void
159
     */
160
    protected function setData()
161
    {
162
        $enableFormSpoofing = ["PUT", "PATCH", "DELETE"];
163
164
        $post = filter_input_array(INPUT_POST, FILTER_DEFAULT);
165
166
        if (!empty($post['_method']) && in_array($post['_method'], $enableFormSpoofing)) {
167
            $this->httpMethod = $post['_method'];
168
            $this->data = $post;
169
170
            unset($this->data["_method"]);
171
            return;
172
        }
173
        if ($this->httpMethod == "POST") {
174
            $this->data = filter_input_array(INPUT_POST, FILTER_DEFAULT);
175
176
            unset($this->data["_method"]);
177
            return;
178
        }
179
180
        if (in_array($this->httpMethod, $enableFormSpoofing) && !empty($_SERVER['CONTENT_LENGTH'])) {
181
            parse_str(file_get_contents('php://input', false, null, 0, $_SERVER['CONTENT_LENGTH']), $putPatch);
182
            $this->data = $putPatch;
183
184
            unset($this->data["_method"]);
185
            return;
186
        }
187
188
        $this->data = [];
189
        return;
190
    }
191
192
    /**
193
     * Return the httpMethod.
194
     * 
195
     * @return string
196
     */
197
    public function getMethod()
198
    {
199
        return $this->httpMethod;
200
    }
201
202
    /**
203
     * Method responsible for returning all request data.
204
     * 
205
     * @param null|string $except = null
206
     * 
207
     * @return array|null
208
     */
209
    public function all(?String $except = null)
210
    {
211
        if (!$except) {
212
            return $this->data;
213
        }
214
215
        $allWithExcession = $this->data;
216
        $except = explode(',', $except);
217
218
        $except = array_map(function ($excession) {
219
            return trim(rtrim($excession));
220
        }, $except);
221
222
        foreach ($except as $excession) {
223
            if (!isset($this->data[$excession])) return;
224
225
            unset($allWithExcession[$excession]);
226
        }
227
228
        return $allWithExcession;
229
    }
230
231
    /**
232
     * Method responsible for returning only
233
     * the data passed in parameter.
234
     * 
235
     * @param string $only
236
     * 
237
     * @return array|string
238
     */
239
    public function only(String $only)
0 ignored issues
show
Unused Code introduced by
The parameter $only is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

239
    public function only(/** @scrutinizer ignore-unused */ String $only)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
240
    {
241
        $result = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
242
    }
243
244
    /**
245
     * Method responsible for returning one or all header data.
246
     * 
247
     * @param string $header = null
248
     * 
249
     * @return array|string
250
     */
251
    public function getHeaders(?String $header = null)
252
    {
253
        if ($header && isset($this->headers[$header])) {
254
            return $this->headers[$header];
255
        }
256
257
        return $this->headers;
258
    }
259
}
260