Completed
Push — master ( 1a208b...8249d2 )
by Thierry
01:32
created

Handler::canProcessRequest()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 0
dl 0
loc 23
rs 9.2408
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Handler.php - Jaxon Request Handler
5
 *
6
 * This class processes an incoming jaxon request.
7
 *
8
 * @package jaxon-core
9
 * @author Jared White
10
 * @author J. Max Wilson
11
 * @author Joseph Woolley
12
 * @author Steffen Konerow
13
 * @author Thierry Feuzeu <[email protected]>
14
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
15
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
16
 * @copyright 2016 Thierry Feuzeu <[email protected]>
17
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
18
 * @link https://github.com/jaxon-php/jaxon-core
19
 */
20
21
namespace Jaxon\Request\Handler;
22
23
use Jaxon\Jaxon;
24
use Jaxon\Plugin\Manager as PluginManager;
25
use Jaxon\Response\Manager as ResponseManager;
26
use Jaxon\Request\Plugin\FileUpload;
27
28
use Exception;
29
30
class Handler
31
{
32
    use \Jaxon\Features\Config;
33
    use \Jaxon\Features\Translator;
34
35
    /**
36
     * The plugin manager.
37
     *
38
     * @var PluginManager
39
     */
40
    private $xPluginManager;
41
42
    /**
43
     * The response manager.
44
     *
45
     * @var ResponseManager
46
     */
47
    private $xResponseManager;
48
49
    /**
50
     * The arguments handler.
51
     *
52
     * @var Argument
53
     */
54
    private $xArgumentManager;
55
56
    /**
57
     * The callbacks to run while processing the request
58
     *
59
     * @var Callback
60
     */
61
    private $xCallbackManager;
62
63
    /**
64
     * The request plugin that is able to process the current request
65
     *
66
     * @var \Jaxon\Plugin\Request
67
     */
68
    private $xTargetRequestPlugin = null;
69
70
    /**
71
     * The file upload request plugin
72
     *
73
     * @var FileUpload
74
     */
75
    private $xUploadRequestPlugin = null;
76
77
    /**
78
     * The constructor
79
     *
80
     * @param PluginManager         $xPluginManager
81
     * @param ResponseManager       $xResponseManager
82
     * @param FileUpload            $xUploadRequestPlugin
83
     */
84
    public function __construct(PluginManager $xPluginManager,
85
        ResponseManager $xResponseManager, FileUpload $xUploadRequestPlugin)
86
    {
87
        $this->xPluginManager = $xPluginManager;
88
        $this->xResponseManager = $xResponseManager;
89
        $this->xUploadRequestPlugin = $xUploadRequestPlugin;
90
91
        $this->xArgumentManager = new Argument();
92
        $this->xCallbackManager = new Callback();
93
    }
94
95
    /**
96
     * Return the method that was used to send the arguments from the client
97
     *
98
     * The method is one of: Argument::METHOD_UNKNOWN, Argument::METHOD_GET, Argument::METHOD_POST.
99
     *
100
     * @return integer
101
     */
102
    public function getRequestMethod()
103
    {
104
        return $this->xArgumentManager->getRequestMethod();
105
    }
106
107
    /**
108
     * Return true if the current request method is GET
109
     *
110
     * @return bool
111
     */
112
    public function requestMethodIsGet()
113
    {
114
        return ($this->xArgumentManager->getRequestMethod() == Argument::METHOD_GET);
115
    }
116
117
    /**
118
     * Return the array of arguments that were extracted and parsed from the GET or POST data
119
     *
120
     * @return array
121
     */
122
    public function processArguments()
123
    {
124
        return $this->xArgumentManager->process();
125
    }
126
127
    /**
128
     * Get the callback handler
129
     *
130
     * @return Callback
131
     */
132
    public function getCallbackManager()
133
    {
134
        return $this->xCallbackManager;
135
    }
136
137
    /**
138
     * This is the pre-request processing callback passed to the Jaxon library.
139
     *
140
     * @param  boolean  &$bEndRequest if set to true, the request processing is interrupted.
141
     *
142
     * @return Jaxon\Response\Response  the Jaxon response
143
     */
144 View Code Duplication
    public function onBefore(&$bEndRequest)
145
    {
146
        // Call the user defined callback
147
        if(($xCallback = $this->xCallbackManager->before()))
0 ignored issues
show
Bug introduced by
The method before cannot be called on $this->xCallbackManager (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
148
        {
149
            call_user_func_array($xCallback, [$this->xTargetRequestPlugin->getTarget(), &$bEndRequest]);
150
        }
151
    }
152
153
    /**
154
     * This is the post-request processing callback passed to the Jaxon library.
155
     *
156
     * @return Jaxon\Response\Response  the Jaxon response
157
     */
158 View Code Duplication
    public function onAfter($bEndRequest)
159
    {
160
        if(($xCallback = $this->xCallbackManager->after()))
0 ignored issues
show
Bug introduced by
The method after cannot be called on $this->xCallbackManager (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
161
        {
162
            call_user_func_array($xCallback, [$this->xTargetRequestPlugin->getTarget(), $bEndRequest]);
163
        }
164
    }
165
166
    /**
167
     * This callback is called whenever an invalid request is processed.
168
     *
169
     * @return Jaxon\Response\Response  the Jaxon response
170
     */
171
    public function onInvalid($sMessage)
172
    {
173
        if(($xCallback = $this->xCallbackManager->invalid()))
0 ignored issues
show
Bug introduced by
The method invalid cannot be called on $this->xCallbackManager (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
174
        {
175
            call_user_func_array($xCallback, [$sMessage]);
176
        }
177
    }
178
179
    /**
180
     * This callback is called whenever an invalid request is processed.
181
     *
182
     * @return Jaxon\Response\Response  the Jaxon response
183
     */
184
    public function onError(Exception $xException)
185
    {
186
        if(($xCallback = $this->xCallbackManager->error()))
0 ignored issues
show
Bug introduced by
The method error cannot be called on $this->xCallbackManager (of type callable).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
187
        {
188
            call_user_func_array($xCallback, [$xException]);
189
        }
190
        else
191
        {
192
            throw $xException;
193
        }
194
    }
195
196
    /**
197
     * Check if the current request can be processed
198
     *
199
     * Calls each of the request plugins and determines if the current request can be processed by one of them.
200
     *
201
     * @return boolean
202
     */
203
    public function canProcessRequest()
204
    {
205
        // Return true if the request plugin was already found
206
        if(($this->xTargetRequestPlugin))
207
        {
208
            return true;
209
        }
210
211
        // Find a plugin to process the request
212
        foreach($this->xPluginManager->getRequestPlugins() as $xPlugin)
213
        {
214
            if($xPlugin->getName() != Jaxon::FILE_UPLOAD && $xPlugin->canProcessRequest())
215
            {
216
                $this->xTargetRequestPlugin = $xPlugin;
217
                return true;
218
            }
219
        }
220
221
        // If no other plugin than the upload plugin can process the request,
222
        // then it is a HTTP (not ajax) upload request
223
        $this->xUploadRequestPlugin->noRequestPluginFound();
224
        return $this->xUploadRequestPlugin->canProcessRequest();
225
    }
226
227
    /**
228
     * Process the current request
229
     *
230
     * Calls each of the request plugins to request that they process the current request.
231
     * If any plugin processes the request, it will return true.
232
     *
233
     * @return boolean
234
     */
235
    public function processRequest()
236
    {
237
        // Check to see if headers have already been sent out, in which case we can't do our job
238
        if(headers_sent($filename, $linenumber))
239
        {
240
            echo $this->trans('errors.output.already-sent', [
241
                'location' => $filename . ':' . $linenumber
242
            ]), "\n", $this->trans('errors.output.advice');
243
            exit();
244
        }
245
246
        // Check if there is a plugin to process this request
247
        if(!$this->canProcessRequest())
248
        {
249
            return;
250
        }
251
252
        $bEndRequest = false;
253
254
        // Handle before processing event
255
        if(($this->xTargetRequestPlugin))
256
        {
257
            $this->onBefore($bEndRequest);
258
        }
259
260
        if(!$bEndRequest)
261
        {
262
            try
263
            {
264
                // Process uploaded files
265
                $this->xUploadRequestPlugin->processRequest();
266
267
                // Process the request
268
                if(($this->xTargetRequestPlugin))
269
                {
270
                    $this->xTargetRequestPlugin->processRequest();
271
                }
272
            }
273
            catch(Exception $e)
274
            {
275
                // An exception was thrown while processing the request.
276
                // The request missed the corresponding handler function,
277
                // or an error occurred while attempting to execute the handler.
278
279
                $this->xResponseManager->error($e->getMessage());
280
281
                if($e instanceof \Jaxon\Exception\Error)
282
                {
283
                    $this->onInvalid($e->getMessage());
284
                }
285
                else
286
                {
287
                    $this->onError($e);
288
                }
289
            }
290
        }
291
292
        // Clean the processing buffer
293
        if(($this->getOption('core.process.clean')))
294
        {
295
            $er = error_reporting(0);
296
            while(ob_get_level() > 0)
297
            {
298
                ob_end_clean();
299
            }
300
            error_reporting($er);
301
        }
302
303
        if(($this->xTargetRequestPlugin))
304
        {
305
            // Handle after processing event
306
            $this->onAfter($bEndRequest);
307
        }
308
309
        // If the called function returned no response, take the the global response
310
        if(!$this->xResponseManager->getResponse())
311
        {
312
            $this->xResponseManager->append(jaxon()->getResponse());
313
        }
314
315
        $this->xResponseManager->printDebug();
316
317
        if(($this->getOption('core.response.send')))
318
        {
319
            $this->xResponseManager->sendOutput();
320
321
            if(($this->getOption('core.process.exit')))
322
            {
323
                exit();
324
            }
325
        }
326
    }
327
}
328