1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace BFW; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Class to get informations about http request. |
7
|
|
|
* Singleton pattern. |
8
|
|
|
*/ |
9
|
|
|
class Request |
10
|
|
|
{ |
11
|
|
|
/** |
12
|
|
|
* @var \BFW\Request $instance Instance for this class (singleton pattern) |
13
|
|
|
*/ |
14
|
|
|
protected static $instance = null; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* @var string $ip The client IP |
18
|
|
|
*/ |
19
|
|
|
protected $ip; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @var string $lang The client primary language |
23
|
|
|
*/ |
24
|
|
|
protected $lang; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var string $referer The referer url |
28
|
|
|
*/ |
29
|
|
|
protected $referer; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @var string $method The HTTP method (GET/POST/PUT/DELETE/...) |
33
|
|
|
*/ |
34
|
|
|
protected $method; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @var boolean $ssl If the request is with ssl (https) or not |
38
|
|
|
*/ |
39
|
|
|
protected $ssl; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var \stdClass The current request |
43
|
|
|
*/ |
44
|
|
|
protected $request; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Constructor |
48
|
|
|
* Call runDetect to detect all informations |
49
|
|
|
*/ |
50
|
|
|
protected function __construct() |
51
|
|
|
{ |
52
|
|
|
$this->runDetect(); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Create singleton instance for this class |
57
|
|
|
* |
58
|
|
|
* @return \BFW\Request |
59
|
|
|
*/ |
60
|
|
View Code Duplication |
public static function getInstance() |
|
|
|
|
61
|
|
|
{ |
62
|
|
|
if (self::$instance === null) { |
63
|
|
|
$calledClass = get_called_class(); //Autorize extends this class |
64
|
|
|
self::$instance = new $calledClass; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
return self::$instance; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Get the client IP |
72
|
|
|
* |
73
|
|
|
* @return string |
74
|
|
|
*/ |
75
|
|
|
public function getIp() |
76
|
|
|
{ |
77
|
|
|
return $this->ip; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Get the client primary language |
82
|
|
|
* |
83
|
|
|
* @return string |
84
|
|
|
*/ |
85
|
|
|
public function getLang() |
86
|
|
|
{ |
87
|
|
|
return $this->lang; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Get the referer url |
92
|
|
|
* |
93
|
|
|
* @return string |
94
|
|
|
*/ |
95
|
|
|
public function getReferer() |
96
|
|
|
{ |
97
|
|
|
return $this->referer; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Get the http method |
102
|
|
|
* |
103
|
|
|
* @return string |
104
|
|
|
*/ |
105
|
|
|
public function getMethod() |
106
|
|
|
{ |
107
|
|
|
return $this->method; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Get information about if the request is ssl |
112
|
|
|
* |
113
|
|
|
* @return boolean |
114
|
|
|
*/ |
115
|
|
|
public function getSsl() |
116
|
|
|
{ |
117
|
|
|
return $this->ssl; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Get the current request |
122
|
|
|
* |
123
|
|
|
* @return \stdClass |
124
|
|
|
*/ |
125
|
|
|
public function getRequest() |
126
|
|
|
{ |
127
|
|
|
return $this->request; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Get the information from the $_SERVER array if the key exist. |
132
|
|
|
* If not exist, return a empty string. |
133
|
|
|
* |
134
|
|
|
* @param string $keyName The key's value in $_SERVER array |
135
|
|
|
* |
136
|
|
|
* @return string |
137
|
|
|
* |
138
|
|
|
* @throws \Exception If the key not exist into $_SERVER |
139
|
|
|
*/ |
140
|
|
|
public static function getServerValue($keyName) |
141
|
|
|
{ |
142
|
|
|
if (!isset($_SERVER[$keyName])) { |
143
|
|
|
throw new \Exception( |
144
|
|
|
'The key '.$keyName.' not exist into $_SERVER array' |
145
|
|
|
); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return $_SERVER[$keyName]; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
protected function serverValue($keyName) |
152
|
|
|
{ |
153
|
|
|
$calledClass = get_called_class(); //Autorize extends this class |
154
|
|
|
|
155
|
|
|
try { |
156
|
|
|
return $calledClass::getServerValue($keyName); |
157
|
|
|
} catch (\Exception $e) { |
158
|
|
|
return ''; |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Run all detect method |
164
|
|
|
* |
165
|
|
|
* @return void |
166
|
|
|
*/ |
167
|
|
|
public function runDetect() |
168
|
|
|
{ |
169
|
|
|
$this->detectIp(); |
170
|
|
|
$this->detectLang(); |
171
|
|
|
$this->detectReferer(); |
172
|
|
|
$this->detectMethod(); |
173
|
|
|
$this->detectSsl(); |
174
|
|
|
$this->detectRequest(); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Detect the client IP |
179
|
|
|
* |
180
|
|
|
* @return void |
181
|
|
|
*/ |
182
|
|
|
protected function detectIp() |
183
|
|
|
{ |
184
|
|
|
$this->ip = $this->serverValue('REMOTE_ADDR'); |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Detect the primary client's language |
189
|
|
|
* |
190
|
|
|
* @return void |
191
|
|
|
*/ |
192
|
|
|
protected function detectLang() |
193
|
|
|
{ |
194
|
|
|
/* |
195
|
|
|
* HTTP_ACCEPT_LANGUAGE -> fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4 |
196
|
|
|
* First "fr-FR" (preference 1/1) |
197
|
|
|
* After in the order, "fr" (preference 0.8 / 1) |
198
|
|
|
* Next "en-US" (preference 0.6/1) |
199
|
|
|
* End "en" (preference 0.4/1) |
200
|
|
|
**/ |
201
|
|
|
|
202
|
|
|
$acceptLanguage = $this->serverValue('HTTP_ACCEPT_LANGUAGE'); |
203
|
|
|
if (empty($acceptLanguage)) { |
204
|
|
|
$this->lang = ''; |
205
|
|
|
return; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
$acceptedLangs = explode(',', $acceptLanguage); |
209
|
|
|
$firstLang = explode(';', $acceptedLangs[0]); |
210
|
|
|
$lang = strtolower($firstLang[0]); |
211
|
|
|
|
212
|
|
|
if (strpos($lang, '-') !== false) { |
213
|
|
|
$minLang = explode('-', $lang); |
214
|
|
|
$lang = $minLang[0]; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
$this->lang = $lang; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Detect the referer page |
222
|
|
|
* |
223
|
|
|
* @return void |
224
|
|
|
*/ |
225
|
|
|
protected function detectReferer() |
226
|
|
|
{ |
227
|
|
|
$this->referer = $this->serverValue('HTTP_REFERER'); |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Detect the http method |
232
|
|
|
* |
233
|
|
|
* @return void |
234
|
|
|
*/ |
235
|
|
|
protected function detectMethod() |
236
|
|
|
{ |
237
|
|
|
$this->method = $this->serverValue('REQUEST_METHOD'); |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
/** |
241
|
|
|
* Detect if the request is with ssl (https) |
242
|
|
|
* |
243
|
|
|
* @return void |
244
|
|
|
*/ |
245
|
|
|
protected function detectSsl() |
246
|
|
|
{ |
247
|
|
|
$serverHttps = $this->serverValue('HTTPS'); |
248
|
|
|
$fwdProto = $this->serverValue('HTTP_X_FORWARDED_PROTO'); |
249
|
|
|
$fwdSsl = $this->serverValue('HTTP_X_FORWARDED_SSL'); |
250
|
|
|
|
251
|
|
|
$this->ssl = false; |
252
|
|
|
|
253
|
|
|
if (!empty($serverHttps) && $serverHttps !== 'off') { |
254
|
|
|
$this->ssl = true; |
255
|
|
|
} elseif (!empty($fwdProto) && $fwdProto === 'https') { |
256
|
|
|
$this->ssl = true; |
257
|
|
|
} elseif (!empty($fwdSsl) && $fwdSsl === 'on') { |
258
|
|
|
$this->ssl = true; |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* Detect the current request informations |
264
|
|
|
* |
265
|
|
|
* @return void |
266
|
|
|
*/ |
267
|
|
|
protected function detectRequest() |
268
|
|
|
{ |
269
|
|
|
$parseUrl = parse_url($this->serverValue('REQUEST_URI')); |
270
|
|
|
|
271
|
|
|
$request = [ |
272
|
|
|
'scheme' => '', |
273
|
|
|
'host' => $this->serverValue('HTTP_HOST'), |
274
|
|
|
'port' => '', |
275
|
|
|
'user' => '', |
276
|
|
|
'pass' => '', |
277
|
|
|
'path' => '', |
278
|
|
|
'query' => '', |
279
|
|
|
'fragment' => '', |
280
|
|
|
]; |
281
|
|
|
|
282
|
|
|
$this->request = (object) array_merge($request, $parseUrl); |
283
|
|
|
} |
284
|
|
|
} |
285
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.