1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Manager.php - Jaxon Request Manager |
5
|
|
|
* |
6
|
|
|
* This class processes the input arguments from the GET or POST data of the request. |
7
|
|
|
* If this is a request for the initial page load, no arguments will be processed. |
8
|
|
|
* During a jaxon request, any arguments found in the GET or POST will be converted to a PHP array. |
9
|
|
|
* |
10
|
|
|
* @package jaxon-core |
11
|
|
|
* @author Jared White |
12
|
|
|
* @author J. Max Wilson |
13
|
|
|
* @author Joseph Woolley |
14
|
|
|
* @author Steffen Konerow |
15
|
|
|
* @author Thierry Feuzeu <[email protected]> |
16
|
|
|
* @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson |
17
|
|
|
* @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White & J. Max Wilson |
18
|
|
|
* @copyright 2016 Thierry Feuzeu <[email protected]> |
19
|
|
|
* @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License |
20
|
|
|
* @link https://github.com/jaxon-php/jaxon-core |
21
|
|
|
*/ |
22
|
|
|
|
23
|
|
|
namespace Jaxon\Request; |
24
|
|
|
|
25
|
|
|
use Jaxon\Jaxon; |
26
|
|
|
|
27
|
|
|
class Manager |
28
|
|
|
{ |
29
|
|
|
use \Jaxon\Utils\Traits\Config; |
30
|
|
|
use \Jaxon\Utils\Traits\Translator; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* An array of arguments received via the GET or POST parameter jxnargs. |
34
|
|
|
* |
35
|
|
|
* @var array |
36
|
|
|
*/ |
37
|
|
|
private $aArgs; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Stores the method that was used to send the arguments from the client. |
41
|
|
|
* Will be one of: Jaxon::METHOD_UNKNOWN, Jaxon::METHOD_GET, Jaxon::METHOD_POST. |
42
|
|
|
* |
43
|
|
|
* @var integer |
44
|
|
|
*/ |
45
|
|
|
private $nMethod; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* The constructor |
49
|
|
|
* |
50
|
|
|
* Get and decode the arguments of the HTTP request |
51
|
|
|
*/ |
52
|
|
|
public function __construct() |
53
|
|
|
{ |
54
|
|
|
|
55
|
|
|
$this->aArgs = array(); |
56
|
|
|
$this->nMethod = Jaxon::METHOD_UNKNOWN; |
57
|
|
|
|
58
|
|
|
if(isset($_POST['jxnargs'])) |
59
|
|
|
{ |
60
|
|
|
$this->nMethod = Jaxon::METHOD_POST; |
61
|
|
|
$this->aArgs = $_POST['jxnargs']; |
62
|
|
|
} |
63
|
|
|
elseif(isset($_GET['jxnargs'])) |
64
|
|
|
{ |
65
|
|
|
$this->nMethod = Jaxon::METHOD_GET; |
66
|
|
|
$this->aArgs = $_GET['jxnargs']; |
67
|
|
|
} |
68
|
|
|
if(get_magic_quotes_gpc() == 1) |
69
|
|
|
{ |
70
|
|
|
array_walk($this->aArgs, array(&$this, '__argumentStripSlashes')); |
71
|
|
|
} |
72
|
|
|
array_walk($this->aArgs, array(&$this, '__argumentDecode')); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Converts a string to a boolean var |
77
|
|
|
* |
78
|
|
|
* @param string $sValue The string to be converted |
79
|
|
|
* |
80
|
|
|
* @return boolean |
81
|
|
|
*/ |
82
|
|
|
private function __convertStringToBool($sValue) |
83
|
|
|
{ |
84
|
|
|
if(strcasecmp($sValue, 'true') == 0) |
85
|
|
|
{ |
86
|
|
|
return true; |
87
|
|
|
} |
88
|
|
|
if(strcasecmp($sValue, 'false') == 0) |
89
|
|
|
{ |
90
|
|
|
return false; |
91
|
|
|
} |
92
|
|
|
if(is_numeric($sValue)) |
93
|
|
|
{ |
94
|
|
|
if($sValue == 0) |
95
|
|
|
{ |
96
|
|
|
return false; |
97
|
|
|
} |
98
|
|
|
return true; |
99
|
|
|
} |
100
|
|
|
return false; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Strip the slashes from a string |
105
|
|
|
* |
106
|
|
|
* @param string $sArg The string to be stripped |
107
|
|
|
* |
108
|
|
|
* @return string |
109
|
|
|
*/ |
110
|
|
|
private function __argumentStripSlashes(&$sArg) |
111
|
|
|
{ |
112
|
|
|
if(!is_string($sArg)) |
113
|
|
|
{ |
114
|
|
|
return ''; |
115
|
|
|
} |
116
|
|
|
$sArg = stripslashes($sArg); |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Convert an Jaxon request argument to its value |
121
|
|
|
* |
122
|
|
|
* Depending of its first char, the Jaxon request argument is converted to a given type. |
123
|
|
|
* |
124
|
|
|
* @param string $sValue The keys of the options in the file |
125
|
|
|
* |
126
|
|
|
* @return mixed |
127
|
|
|
*/ |
128
|
|
|
private function __convertValue($sValue) |
129
|
|
|
{ |
130
|
|
|
$cType = substr($sValue, 0, 1); |
131
|
|
|
$sValue = substr($sValue, 1); |
132
|
|
|
switch ($cType) |
133
|
|
|
{ |
134
|
|
|
case 'S': |
135
|
|
|
$value = ($sValue === false ? '' : $sValue); |
136
|
|
|
break; |
137
|
|
|
case 'B': |
138
|
|
|
$value = $this->__convertStringToBool($sValue); |
139
|
|
|
break; |
140
|
|
|
case 'N': |
141
|
|
|
$value = ($sValue == floor($sValue) ? (int)$sValue : (float)$sValue); |
142
|
|
|
break; |
143
|
|
|
case '*': |
144
|
|
|
default: |
145
|
|
|
$value = null; |
146
|
|
|
break; |
147
|
|
|
} |
148
|
|
|
return $value; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Decode and convert an Jaxon request argument from JSON |
153
|
|
|
* |
154
|
|
|
* @param string $sArg The Jaxon request argument |
155
|
|
|
* |
156
|
|
|
* @return mixed |
157
|
|
|
*/ |
158
|
|
|
private function __argumentDecode(&$sArg) |
159
|
|
|
{ |
160
|
|
|
if($sArg == '') |
161
|
|
|
{ |
162
|
|
|
return ''; |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
// Arguments are url encoded when uploading files |
166
|
|
|
$sType = 'multipart/form-data'; |
167
|
|
|
$iLen = strlen($sType); |
168
|
|
|
$sContentType = ''; |
169
|
|
|
if(key_exists('CONTENT_TYPE', $_SERVER)) |
170
|
|
|
{ |
171
|
|
|
$sContentType = substr($_SERVER['CONTENT_TYPE'], 0, $iLen); |
172
|
|
|
} |
173
|
|
|
else if(key_exists('HTTP_CONTENT_TYPE', $_SERVER)) |
174
|
|
|
{ |
175
|
|
|
$sContentType = substr($_SERVER['HTTP_CONTENT_TYPE'], 0, $iLen); |
176
|
|
|
} |
177
|
|
|
if($sContentType == $sType) |
178
|
|
|
{ |
179
|
|
|
$sArg = urldecode($sArg); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
$data = json_decode($sArg, true); |
183
|
|
|
|
184
|
|
|
if($data !== null && $sArg != $data) |
185
|
|
|
{ |
186
|
|
|
$sArg = $data; |
187
|
|
|
} |
188
|
|
|
else |
189
|
|
|
{ |
190
|
|
|
$sArg = $this->__convertValue($sArg); |
191
|
|
|
} |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Decode an Jaxon request argument and convert to UTF8 with iconv |
196
|
|
|
* |
197
|
|
|
* @param string|array $mArg The Jaxon request argument |
198
|
|
|
* |
199
|
|
|
* @return void |
200
|
|
|
*/ |
201
|
|
|
private function __argumentDecodeUTF8_iconv(&$mArg) |
202
|
|
|
{ |
203
|
|
|
if(is_array($mArg)) |
204
|
|
|
{ |
205
|
|
|
foreach($mArg as $sKey => &$xArg) |
206
|
|
|
{ |
207
|
|
|
$sNewKey = $sKey; |
208
|
|
|
$this->__argumentDecodeUTF8_iconv($sNewKey); |
209
|
|
|
if($sNewKey != $sKey) |
210
|
|
|
{ |
211
|
|
|
$mArg[$sNewKey] = $xArg; |
212
|
|
|
unset($mArg[$sKey]); |
213
|
|
|
$sKey = $sNewKey; |
214
|
|
|
} |
215
|
|
|
$this->__argumentDecodeUTF8_iconv($xArg); |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
elseif(is_string($mArg)) |
219
|
|
|
{ |
220
|
|
|
$mArg = iconv("UTF-8", $this->getOption('core.encoding') . '//TRANSLIT', $mArg); |
221
|
|
|
} |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* Decode an Jaxon request argument and convert to UTF8 with mb_convert_encoding |
226
|
|
|
* |
227
|
|
|
* @param string|array $mArg The Jaxon request argument |
228
|
|
|
* |
229
|
|
|
* @return void |
230
|
|
|
*/ |
231
|
|
View Code Duplication |
private function __argumentDecodeUTF8_mb_convert_encoding(&$mArg) |
|
|
|
|
232
|
|
|
{ |
233
|
|
|
if(is_array($mArg)) |
234
|
|
|
{ |
235
|
|
|
foreach($mArg as $sKey => &$xArg) |
236
|
|
|
{ |
237
|
|
|
$sNewKey = $sKey; |
238
|
|
|
$this->__argumentDecodeUTF8_mb_convert_encoding($sNewKey); |
239
|
|
|
if($sNewKey != $sKey) |
240
|
|
|
{ |
241
|
|
|
$mArg[$sNewKey] = $xArg; |
242
|
|
|
unset($mArg[$sKey]); |
243
|
|
|
$sKey = $sNewKey; |
244
|
|
|
} |
245
|
|
|
$this->__argumentDecodeUTF8_mb_convert_encoding($xArg); |
246
|
|
|
} |
247
|
|
|
} |
248
|
|
|
elseif(is_string($mArg)) |
249
|
|
|
{ |
250
|
|
|
$mArg = mb_convert_encoding($mArg, $this->getOption('core.encoding'), "UTF-8"); |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Decode an Jaxon request argument from UTF8 |
256
|
|
|
* |
257
|
|
|
* @param string|array $mArg The Jaxon request argument |
258
|
|
|
* |
259
|
|
|
* @return void |
260
|
|
|
*/ |
261
|
|
View Code Duplication |
private function __argumentDecodeUTF8_utf8_decode(&$mArg) |
|
|
|
|
262
|
|
|
{ |
263
|
|
|
if(is_array($mArg)) |
264
|
|
|
{ |
265
|
|
|
foreach($mArg as $sKey => &$xArg) |
266
|
|
|
{ |
267
|
|
|
$sNewKey = $sKey; |
268
|
|
|
$this->__argumentDecodeUTF8_utf8_decode($sNewKey); |
269
|
|
|
|
270
|
|
|
if($sNewKey != $sKey) |
271
|
|
|
{ |
272
|
|
|
$mArg[$sNewKey] = $xArg; |
273
|
|
|
unset($mArg[$sKey]); |
274
|
|
|
$sKey = $sNewKey; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
$this->__argumentDecodeUTF8_utf8_decode($xArg); |
278
|
|
|
} |
279
|
|
|
} |
280
|
|
|
elseif(is_string($mArg)) |
281
|
|
|
{ |
282
|
|
|
$mArg = utf8_decode($mArg); |
283
|
|
|
} |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
/** |
287
|
|
|
* Return the method that was used to send the arguments from the client |
288
|
|
|
* |
289
|
|
|
* The method is one of: Jaxon::METHOD_UNKNOWN, Jaxon::METHOD_GET, Jaxon::METHOD_POST. |
290
|
|
|
* |
291
|
|
|
* @return integer |
292
|
|
|
*/ |
293
|
|
|
public function getRequestMethod() |
294
|
|
|
{ |
295
|
|
|
return $this->nMethod; |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Return the array of arguments that were extracted and parsed from the GET or POST data |
300
|
|
|
* |
301
|
|
|
* @return array |
302
|
|
|
*/ |
303
|
|
|
public function process() |
304
|
|
|
{ |
305
|
|
|
if(($this->getOption('core.decode_utf8'))) |
306
|
|
|
{ |
307
|
|
|
$sFunction = ''; |
308
|
|
|
|
309
|
|
|
if(function_exists('iconv')) |
310
|
|
|
{ |
311
|
|
|
$sFunction = "iconv"; |
312
|
|
|
} |
313
|
|
|
elseif(function_exists('mb_convert_encoding')) |
314
|
|
|
{ |
315
|
|
|
$sFunction = "mb_convert_encoding"; |
316
|
|
|
} |
317
|
|
|
elseif($this->getOption('core.encoding') == "ISO-8859-1") |
318
|
|
|
{ |
319
|
|
|
$sFunction = "utf8_decode"; |
320
|
|
|
} |
321
|
|
|
else |
322
|
|
|
{ |
323
|
|
|
throw new \Jaxon\Exception\Error($this->trans('errors.request.conversion')); |
324
|
|
|
} |
325
|
|
|
|
326
|
|
|
$mFunction = array(&$this, '__argumentDecodeUTF8_' . $sFunction); |
327
|
|
|
array_walk($this->aArgs, $mFunction); |
328
|
|
|
$this->setOption('core.decode_utf8', false); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
return $this->aArgs; |
332
|
|
|
} |
333
|
|
|
} |
334
|
|
|
|
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.