Completed
Push — master ( 71f3ca...10d1fd )
by Thierry
01:44
created

Handler::getRequestMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
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 Handler
28
{
29
    use \Jaxon\Utils\Traits\Config;
30
    use \Jaxon\Utils\Traits\Translator;
31
32
    /**
33
     * The plugin manager.
34
     *
35
     * @var Jaxon\Plugin\Manager
36
     */
37
    private $xPluginManager;
38
39
    /**
40
     * An array of arguments received via the GET or POST parameter jxnargs.
41
     *
42
     * @var array
43
     */
44
    private $aArgs;
45
46
    /**
47
     * Stores the method that was used to send the arguments from the client.
48
     * Will be one of: Jaxon::METHOD_UNKNOWN, Jaxon::METHOD_GET, Jaxon::METHOD_POST.
49
     *
50
     * @var integer
51
     */
52
    private $nMethod;
53
54
    /**
55
     * The constructor
56
     *
57
     * Get and decode the arguments of the HTTP request
58
     */
59
    public function __construct(\Jaxon\Plugin\Manager $xPluginManager)
60
    {
61
        $this->xPluginManager = $xPluginManager;
0 ignored issues
show
Documentation Bug introduced by
It seems like $xPluginManager of type object<Jaxon\Plugin\Manager> is incompatible with the declared type object<Jaxon\Jaxon\Plugin\Manager> of property $xPluginManager.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
62
63
        $this->aArgs = [];
64
        $this->nMethod = Jaxon::METHOD_UNKNOWN;
65
66
        if(isset($_POST['jxnargs']))
67
        {
68
            $this->nMethod = Jaxon::METHOD_POST;
69
            $this->aArgs = $_POST['jxnargs'];
70
        }
71
        elseif(isset($_GET['jxnargs']))
72
        {
73
            $this->nMethod = Jaxon::METHOD_GET;
74
            $this->aArgs = $_GET['jxnargs'];
75
        }
76
        if(get_magic_quotes_gpc() == 1)
77
        {
78
            array_walk($this->aArgs, array(&$this, '__argumentStripSlashes'));
79
        }
80
        array_walk($this->aArgs, array(&$this, '__argumentDecode'));
81
    }
82
83
    /**
84
     * Converts a string to a boolean var
85
     *
86
     * @param string        $sValue                The string to be converted
87
     *
88
     * @return boolean
89
     */
90
    private function __convertStringToBool($sValue)
91
    {
92
        if(strcasecmp($sValue, 'true') == 0)
93
        {
94
            return true;
95
        }
96
        if(strcasecmp($sValue, 'false') == 0)
97
        {
98
            return false;
99
        }
100
        if(is_numeric($sValue))
101
        {
102
            if($sValue == 0)
103
            {
104
                return false;
105
            }
106
            return true;
107
        }
108
        return false;
109
    }
110
111
    /**
112
     * Strip the slashes from a string
113
     *
114
     * @param string        $sArg                The string to be stripped
115
     *
116
     * @return string
117
     */
118
    private function __argumentStripSlashes(&$sArg)
119
    {
120
        if(!is_string($sArg))
121
        {
122
            return '';
123
        }
124
        $sArg = stripslashes($sArg);
125
    }
126
127
    /**
128
     * Convert an Jaxon request argument to its value
129
     *
130
     * Depending of its first char, the Jaxon request argument is converted to a given type.
131
     *
132
     * @param string        $sValue                The keys of the options in the file
133
     *
134
     * @return mixed
135
     */
136
    private function __convertValue($sValue)
137
    {
138
        $cType = substr($sValue, 0, 1);
139
        $sValue = substr($sValue, 1);
140
        switch ($cType)
141
        {
142
            case 'S':
143
                $value = ($sValue === false ? '' : $sValue);
144
                break;
145
            case 'B':
146
                $value = $this->__convertStringToBool($sValue);
147
                break;
148
            case 'N':
149
                $value = ($sValue == floor($sValue) ? (int)$sValue : (float)$sValue);
150
                break;
151
            case '*':
152
            default:
153
                $value = null;
154
                break;
155
        }
156
        return $value;
157
    }
158
159
    /**
160
     * Decode and convert an Jaxon request argument from JSON
161
     *
162
     * @param string        $sArg                The Jaxon request argument
163
     *
164
     * @return mixed
165
     */
166
    private function __argumentDecode(&$sArg)
167
    {
168
        if($sArg == '')
169
        {
170
            return '';
171
        }
172
173
        // Arguments are url encoded when uploading files
174
        $sType = 'multipart/form-data';
175
        $iLen = strlen($sType);
176
        $sContentType = '';
177
        if(key_exists('CONTENT_TYPE', $_SERVER))
178
        {
179
            $sContentType = substr($_SERVER['CONTENT_TYPE'], 0, $iLen);
180
        }
181
        elseif(key_exists('HTTP_CONTENT_TYPE', $_SERVER))
182
        {
183
            $sContentType = substr($_SERVER['HTTP_CONTENT_TYPE'], 0, $iLen);
184
        }
185
        if($sContentType == $sType)
186
        {
187
            $sArg = urldecode($sArg);
188
        }
189
190
        $data = json_decode($sArg, true);
191
192
        if($data !== null && $sArg != $data)
193
        {
194
            $sArg = $data;
195
        }
196
        else
197
        {
198
            $sArg = $this->__convertValue($sArg);
199
        }
200
    }
201
202
    /**
203
     * Decode an Jaxon request argument and convert to UTF8 with iconv
204
     *
205
     * @param string|array        $mArg                The Jaxon request argument
206
     *
207
     * @return void
208
     */
209
    private function __argumentDecodeUTF8_iconv(&$mArg)
210
    {
211
        if(is_array($mArg))
212
        {
213
            foreach($mArg as $sKey => &$xArg)
214
            {
215
                $sNewKey = $sKey;
216
                $this->__argumentDecodeUTF8_iconv($sNewKey);
217
                if($sNewKey != $sKey)
218
                {
219
                    $mArg[$sNewKey] = $xArg;
220
                    unset($mArg[$sKey]);
221
                    $sKey = $sNewKey;
222
                }
223
                $this->__argumentDecodeUTF8_iconv($xArg);
224
            }
225
        }
226
        elseif(is_string($mArg))
227
        {
228
            $mArg = iconv("UTF-8", $this->getOption('core.encoding') . '//TRANSLIT', $mArg);
229
        }
230
    }
231
232
    /**
233
     * Decode an Jaxon request argument and convert to UTF8 with mb_convert_encoding
234
     *
235
     * @param string|array        $mArg                The Jaxon request argument
236
     *
237
     * @return void
238
     */
239 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...
240
    {
241
        if(is_array($mArg))
242
        {
243
            foreach($mArg as $sKey => &$xArg)
244
            {
245
                $sNewKey = $sKey;
246
                $this->__argumentDecodeUTF8_mb_convert_encoding($sNewKey);
247
                if($sNewKey != $sKey)
248
                {
249
                    $mArg[$sNewKey] = $xArg;
250
                    unset($mArg[$sKey]);
251
                    $sKey = $sNewKey;
252
                }
253
                $this->__argumentDecodeUTF8_mb_convert_encoding($xArg);
254
            }
255
        }
256
        elseif(is_string($mArg))
257
        {
258
            $mArg = mb_convert_encoding($mArg, $this->getOption('core.encoding'), "UTF-8");
259
        }
260
    }
261
262
    /**
263
     * Decode an Jaxon request argument from UTF8
264
     *
265
     * @param string|array        $mArg                The Jaxon request argument
266
     *
267
     * @return void
268
     */
269 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...
270
    {
271
        if(is_array($mArg))
272
        {
273
            foreach($mArg as $sKey => &$xArg)
274
            {
275
                $sNewKey = $sKey;
276
                $this->__argumentDecodeUTF8_utf8_decode($sNewKey);
277
278
                if($sNewKey != $sKey)
279
                {
280
                    $mArg[$sNewKey] = $xArg;
281
                    unset($mArg[$sKey]);
282
                    $sKey = $sNewKey;
283
                }
284
285
                $this->__argumentDecodeUTF8_utf8_decode($xArg);
286
            }
287
        }
288
        elseif(is_string($mArg))
289
        {
290
            $mArg = utf8_decode($mArg);
291
        }
292
    }
293
294
    /**
295
     * Return the method that was used to send the arguments from the client
296
     *
297
     * The method is one of: Jaxon::METHOD_UNKNOWN, Jaxon::METHOD_GET, Jaxon::METHOD_POST.
298
     *
299
     * @return integer
300
     */
301
    public function getRequestMethod()
302
    {
303
        return $this->nMethod;
304
    }
305
306
    /**
307
     * Return the array of arguments that were extracted and parsed from the GET or POST data
308
     *
309
     * @return array
310
     */
311
    public function processArguments()
312
    {
313
        if(($this->getOption('core.decode_utf8')))
314
        {
315
            $sFunction = '';
316
317
            if(function_exists('iconv'))
318
            {
319
                $sFunction = "iconv";
320
            }
321
            elseif(function_exists('mb_convert_encoding'))
322
            {
323
                $sFunction = "mb_convert_encoding";
324
            }
325
            elseif($this->getOption('core.encoding') == "ISO-8859-1")
326
            {
327
                $sFunction = "utf8_decode";
328
            }
329
            else
330
            {
331
                throw new \Jaxon\Exception\Error($this->trans('errors.request.conversion'));
332
            }
333
334
            $mFunction = array(&$this, '__argumentDecodeUTF8_' . $sFunction);
335
            array_walk($this->aArgs, $mFunction);
336
            $this->setOption('core.decode_utf8', false);
337
        }
338
339
        return $this->aArgs;
340
    }
341
342
    /**
343
     * Check if the current request can be processed
344
     *
345
     * Calls each of the request plugins and determines if the current request can be processed by one of them.
346
     * If no processor identifies the current request, then the request must be for the initial page load.
347
     *
348
     * @return boolean
349
     */
350
    public function canProcessRequest()
351
    {
352
        foreach($this->xPluginManager->getRequestPlugins() as $xPlugin)
353
        {
354
            if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest())
355
            {
356
                return true;
357
            }
358
        }
359
        return false;
360
    }
361
362
    /**
363
     * Process the current request
364
     *
365
     * Calls each of the request plugins to request that they process the current request.
366
     * If any plugin processes the request, it will return true.
367
     *
368
     * @return boolean
369
     */
370
    public function processRequest()
371
    {
372
        foreach($this->xPluginManager->getRequestPlugins() as $xPlugin)
373
        {
374
            if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest())
375
            {
376
                $xUploadPlugin = $this->xPluginManager->getRequestPlugin(Jaxon::FILE_UPLOAD);
377
                // Process uploaded files
378
                if($xUploadPlugin != null)
379
                {
380
                    $xUploadPlugin->processRequest();
381
                }
382
                // Process the request
383
                return $xPlugin->processRequest();
384
            }
385
        }
386
        // Todo: throw an exception
387
        return false;
388
    }
389
}
390