Completed
Push — master ( 26a0ce...f09443 )
by Thierry
01:51
created

Manager::__argumentDecode()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 13
nop 1
dl 0
loc 35
rs 8.4266
c 0
b 0
f 0
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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