Passed
Branch master (f54e31)
by Thierry
08:21
created

CallableClass::canProcessRequest()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 4
nop 0
dl 0
loc 11
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * CallableClass.php - Jaxon callable class plugin
5
 *
6
 * This class registers user defined callable classes, generates client side javascript code,
7
 * and calls their methods on user request
8
 *
9
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
10
 * @author Jared White
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
11
 * @author J. Max Wilson
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
12
 * @author Joseph Woolley
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
13
 * @author Steffen Konerow
0 ignored issues
show
Coding Style introduced by
Content of the @author tag must be in the form "Display Name <[email protected]>"
Loading history...
14
 * @author Thierry Feuzeu <[email protected]>
15
 * @copyright Copyright (c) 2005-2007 by Jared White & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
16
 * @copyright Copyright (c) 2008-2010 by Joseph Woolley, Steffen Konerow, Jared White  & J. Max Wilson
0 ignored issues
show
Coding Style introduced by
@copyright tag must contain a year and the name of the copyright holder
Loading history...
17
 * @copyright 2016 Thierry Feuzeu <[email protected]>
18
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
19
 * @link https://github.com/jaxon-php/jaxon-core
20
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
21
22
namespace Jaxon\Request\Plugin;
23
24
use Jaxon\Jaxon;
25
use Jaxon\CallableClass as UserCallableClass;
26
use Jaxon\Plugin\Request as RequestPlugin;
27
use Jaxon\Request\Support\CallableObject;
28
use Jaxon\Request\Support\CallableRegistry;
29
use Jaxon\Request\Support\CallableRepository;
30
use Jaxon\Request\Target;
31
32
class CallableClass extends RequestPlugin
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CallableClass
Loading history...
33
{
34
    use \Jaxon\Features\Config;
35
    use \Jaxon\Features\Template;
36
    use \Jaxon\Features\Validator;
37
    use \Jaxon\Features\Translator;
38
39
    /**
40
     * The callable registrar
41
     *
42
     * @var CallableRegistry
43
     */
44
    protected $xRegistry;
45
46
    /**
47
     * The callable repository
48
     *
49
     * @var CallableRepository
50
     */
51
    protected $xRepository;
52
53
    /**
54
     * The value of the class parameter of the incoming Jaxon request
55
     *
56
     * @var string
57
     */
58
    protected $sRequestedClass = '';
59
60
    /**
61
     * The value of the method parameter of the incoming Jaxon request
62
     *
63
     * @var string
64
     */
65
    protected $sRequestedMethod = '';
66
67
    /**
68
     * The class constructor
69
     *
70
     * @param CallableRegistry      $xRegistry      The callable class registry
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter type; 6 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 6 found
Loading history...
71
     * @param CallableRepository    $xRepository    The callable object repository
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 4 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
72
     */
73
    public function __construct(CallableRegistry $xRegistry, CallableRepository $xRepository)
74
    {
75
        $this->xRegistry = $xRegistry;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
76
        $this->xRepository = $xRepository;
77
78
        if(!empty($_GET['jxncls']))
79
        {
80
            $this->sRequestedClass = trim($_GET['jxncls']);
81
        }
82
        if(!empty($_GET['jxnmthd']))
83
        {
84
            $this->sRequestedMethod = trim($_GET['jxnmthd']);
85
        }
86
        if(!empty($_POST['jxncls']))
87
        {
88
            $this->sRequestedClass = trim($_POST['jxncls']);
89
        }
90
        if(!empty($_POST['jxnmthd']))
91
        {
92
            $this->sRequestedMethod = trim($_POST['jxnmthd']);
93
        }
94
    }
95
96
    /**
97
     * Return the name of this plugin
98
     *
99
     * @return string
100
     */
101
    public function getName()
102
    {
103
        return Jaxon::CALLABLE_CLASS;
104
    }
105
106
    /**
107
     * Return the target class and method
108
     *
109
     * @return Target|null
110
     */
111
    public function getTarget()
112
    {
113
        if(!$this->sRequestedClass || !$this->sRequestedMethod)
114
        {
115
            return null;
116
        }
117
        return Target::makeClass($this->sRequestedClass, $this->sRequestedMethod);
118
    }
119
120
    /**
121
     * Register a callable class
122
     *
123
     * @param string        $sType          The type of request handler being registered
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 6 spaces after parameter name; 10 found
Loading history...
124
     * @param string        $sClassName     The name of the class being registered
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 5 found
Loading history...
125
     * @param array|string  $aOptions       The associated options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 7 found
Loading history...
126
     *
127
     * @return boolean
128
     */
129
    public function register($sType, $sClassName, $aOptions)
130
    {
131
        $sType = trim($sType);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $sType. This often makes code more readable.
Loading history...
132
        if($sType != $this->getName())
133
        {
134
            return false;
135
        }
136
137
        if(!is_string($sClassName))
138
        {
139
            throw new \Jaxon\Exception\Error($this->trans('errors.objects.invalid-declaration'));
140
        }
141
        if(is_string($aOptions))
142
        {
143
            $aOptions = ['include' => $aOptions];
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $aOptions. This often makes code more readable.
Loading history...
144
        }
145
        if(!is_array($aOptions))
146
        {
147
            throw new \Jaxon\Exception\Error($this->trans('errors.objects.invalid-declaration'));
148
        }
149
150
        $this->xRepository->addClass(trim($sClassName), $aOptions);
151
152
        return true;
153
    }
154
155
    /**
156
     * Generate a hash for the registered callable objects
157
     *
158
     * @return string
159
     */
160
    public function generateHash()
161
    {
162
        $this->xRegistry->createCallableObjects();
163
        $aNamespaces = $this->xRepository->getNamespaces();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
164
        $aCallableObjects = $this->xRepository->getCallableObjects();
165
        $sHash = '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
166
167
        foreach($aNamespaces as $sNamespace => $aOptions)
168
        {
169
            $sHash .= $sNamespace . $aOptions['separator'];
170
        }
171
        foreach($aCallableObjects as $sClassName => $xCallableObject)
172
        {
173
            $sHash .= $sClassName . implode('|', $xCallableObject->getMethods());
174
        }
175
176
        return md5($sHash);
177
    }
178
179
    /**
180
     * Generate client side javascript code for namespaces
181
     *
182
     * @return string
183
     */
184
    private function getNamespacesScript()
185
    {
186
        $sCode = '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
187
        $sPrefix = $this->getOption('core.prefix.class');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
188
        $aJsClasses = [];
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
189
        $aNamespaces = array_keys($this->xRepository->getNamespaces());
190
        foreach($aNamespaces as $sNamespace)
191
        {
192
            $offset = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
193
            $sJsNamespace = str_replace('\\', '.', $sNamespace);
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
194
            $sJsNamespace .= '.Null'; // This is a sentinel. The last token is not processed in the while loop.
195
            while(($dotPosition = strpos($sJsNamespace, '.', $offset)) !== false)
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
196
            {
197
                $sJsClass = substr($sJsNamespace, 0, $dotPosition);
198
                // Generate code for this object
199
                if(!key_exists($sJsClass, $aJsClasses))
200
                {
201
                    $sCode .= "$sPrefix$sJsClass = {};\n";
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 16 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
202
                    $aJsClasses[$sJsClass] = $sJsClass;
203
                }
204
                $offset = $dotPosition + 1;
205
            }
206
        }
207
        return $sCode;
208
    }
209
210
    /**
211
     * Generate client side javascript code for a callable class
212
     *
213
     * @param string            $sClassName         The class name
0 ignored issues
show
Coding Style introduced by
Expected 9 spaces after parameter type; 12 found
Loading history...
Coding Style introduced by
Expected 8 spaces after parameter name; 9 found
Loading history...
214
     * @param CallableObject    $xCallableObject    The corresponding callable object
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 4 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 4 found
Loading history...
215
     * @param array             $aProtectedMethods  The protected methods
0 ignored issues
show
Coding Style introduced by
Expected 10 spaces after parameter type; 13 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
216
     *
217
     * @return string
218
     */
219
    private function getCallableScript($sClassName, CallableObject $xCallableObject, array $aProtectedMethods)
220
    {
221
        $aCallableOptions = $this->xRepository->getCallableOptions();
222
        $aConfig = $aCallableOptions[$sClassName];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
223
        $aCommonConfig = key_exists('*', $aConfig) ? $aConfig['*'] : [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
224
225
        $_aProtectedMethods = is_subclass_of($sClassName, UserCallableClass::class) ? $aProtectedMethods : [];
226
        $aMethods = [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 11 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
227
        foreach($xCallableObject->getMethods() as $sMethodName)
228
        {
229
            // Don't export methods of the CallableClass class
230
            if(in_array($sMethodName, $_aProtectedMethods))
231
            {
232
                continue;
233
            }
234
            // Specific options for this method
235
            $aMethodConfig = key_exists($sMethodName, $aConfig) ?
0 ignored issues
show
Coding Style introduced by
Expected 1 space after "?"; newline found
Loading history...
236
                array_merge($aCommonConfig, $aConfig[$sMethodName]) : $aCommonConfig;
237
            $aMethods[] = [
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
238
                'name' => $sMethodName,
239
                'config' => $aMethodConfig,
240
            ];
241
        }
242
243
        $sPrefix = $this->getOption('core.prefix.class');
244
        return $this->render('jaxon::support/object.js', [
245
            'sPrefix' => $sPrefix,
246
            'sClass' => $xCallableObject->getJsName(),
247
            'aMethods' => $aMethods,
248
        ]);
249
    }
250
251
    /**
252
     * Generate client side javascript code for the registered callable objects
253
     *
254
     * @return string
255
     */
256
    public function getScript()
257
    {
258
        $this->xRegistry->createCallableObjects();
259
260
        // The methods of the \Jaxon\CallableClass class must not be exported
261
        $xCallableClass = new \ReflectionClass(UserCallableClass::class);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 4 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
262
        $aProtectedMethods = [];
263
        foreach($xCallableClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $xMethod)
264
        {
265
            $aProtectedMethods[] = $xMethod->getName();
266
        }
267
268
        $sCode = $this->getNamespacesScript();
269
270
        $aCallableObjects = $this->xRepository->getCallableObjects();
271
        foreach($aCallableObjects as $sClassName => $xCallableObject)
272
        {
273
            $sCode .= $this->getCallableScript($sClassName, $xCallableObject, $aProtectedMethods);
274
        }
275
276
        return $sCode;
277
    }
278
279
    /**
280
     * Check if this plugin can process the incoming Jaxon request
281
     *
282
     * @return boolean
283
     */
284
    public function canProcessRequest()
285
    {
286
        // Check the validity of the class name
287
        if(($this->sRequestedClass !== null && !$this->validateClass($this->sRequestedClass)) ||
288
            ($this->sRequestedMethod !== null && !$this->validateMethod($this->sRequestedMethod)))
289
        {
290
            $this->sRequestedClass = null;
1 ignored issue
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
291
            $this->sRequestedMethod = null;
292
        }
293
        return ($this->sRequestedClass !== null && $this->sRequestedMethod !== null);
294
    }
295
296
    /**
297
     * Process the incoming Jaxon request
298
     *
299
     * @return boolean
300
     */
301
    public function processRequest()
302
    {
303
        if(!$this->canProcessRequest())
304
        {
305
            return false;
306
        }
307
308
        // Find the requested method
309
        $xCallableObject = $this->xRegistry->getCallableObject($this->sRequestedClass);
310
        if(!$xCallableObject || !$xCallableObject->hasMethod($this->sRequestedMethod))
311
        {
312
            // Unable to find the requested object or method
313
            throw new \Jaxon\Exception\Error($this->trans('errors.objects.invalid',
314
                ['class' => $this->sRequestedClass, 'method' => $this->sRequestedMethod]));
315
        }
316
317
        // Call the requested method
318
        $di = jaxon()->di();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
319
        $aArgs = $di->getRequestHandler()->processArguments();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
320
        $xResponse = $xCallableObject->call($this->sRequestedMethod, $aArgs);
321
        if(($xResponse))
322
        {
323
            $di->getResponseManager()->append($xResponse);
324
        }
325
        return true;
326
    }
327
}
328