Completed
Push — master ( f42a52...0a9499 )
by Thierry
02:50 queued 01:16
created

Argument::__argumentDecodeUTF8_iconv()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

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

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
327
            }
328
329
            $mFunction = [&$this, '__argumentDecodeUTF8_' . $sFunction];
330
            array_walk($this->aArgs, $mFunction);
331
            $this->setOption('core.decode_utf8', false);
332
        }
333
334
        return $this->aArgs;
335
    }
336
}
337