Passed
Push — master ( 68b778...1b1614 )
by Thierry
07:15 queued 04:29
created

CallableObject::configure()   B

Complexity

Conditions 11
Paths 10

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 23
c 6
b 1
f 0
dl 0
loc 39
rs 7.3166
cc 11
nc 10
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * CallableObject.php - Jaxon callable object
5
 *
6
 * This class stores a reference to an object whose methods can be called from
7
 * the client via an Jaxon request
8
 *
9
 * The Jaxon plugin manager will call <CallableObject->getClientScript> so that
10
 * stub functions can be generated and sent to the browser.
11
 *
12
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
13
 * @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...
14
 * @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...
15
 * @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...
16
 * @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...
17
 * @author Thierry Feuzeu <[email protected]>
18
 * @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...
19
 * @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...
20
 * @copyright 2016 Thierry Feuzeu <[email protected]>
21
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
22
 * @link https://github.com/jaxon-php/jaxon-core
23
 */
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...
24
25
namespace Jaxon\Request\Support;
26
27
use Jaxon\Request\Request;
0 ignored issues
show
Bug introduced by
The type Jaxon\Request\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Jaxon\Response\Response;
29
30
class CallableObject
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CallableObject
Loading history...
31
{
32
    /**
33
     * A reference to the callable object the user has registered
34
     *
35
     * @var object
36
     */
37
    private $xRegisteredObject = null;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
38
39
    /**
40
     * The reflection class of the user registered callable object
41
     *
42
     * @var \ReflectionClass
43
     */
44
    private $xReflectionClass;
45
46
    /**
47
     * A list of methods of the user registered callable object the library must not export to javascript
48
     *
49
     * @var array
50
     */
51
    private $aProtectedMethods = [];
52
53
    /**
54
     * A list of methods to call before processing the request
55
     *
56
     * @var array
57
     */
58
    private $aBeforeMethods = [];
59
60
    /**
61
     * A list of methods to call after processing the request
62
     *
63
     * @var array
64
     */
65
    private $aAfterMethods = [];
66
67
    /**
68
     * The namespace the callable class was registered from
69
     *
70
     * @var string
71
     */
72
    private $sNamespace = '';
73
74
    /**
75
     * The character to use as separator in javascript class names
76
     *
77
     * @var string
78
     */
79
    private $sSeparator = '.';
80
81
    /**
82
     * The class constructor
83
     *
84
     * @param string            $sCallable               The callable object instance or class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 12 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 15 found
Loading history...
85
     *
86
     */
87
    public function __construct($sCallable)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
88
    {
89
        $this->xReflectionClass = new \ReflectionClass($sCallable);
90
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
91
92
    /**
93
     * Return the class name of this callable object, without the namespace if any
94
     *
95
     * @return string
96
     */
97
    public function getClassName()
98
    {
99
        // Get the class name without the namespace.
100
        return $this->xReflectionClass->getShortName();
101
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
102
103
    /**
104
     * Return the name of this callable object
105
     *
106
     * @return string
107
     */
108
    public function getName()
109
    {
110
        // Get the class name with the namespace.
111
        return $this->xReflectionClass->getName();
112
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
113
114
    /**
115
     * Return the name of the corresponding javascript class
116
     *
117
     * @return string
118
     */
119
    public function getJsName()
120
    {
121
        return str_replace('\\', $this->sSeparator, $this->getName());
122
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
123
124
    /**
125
     * Return the namespace of this callable object
126
     *
127
     * @return string
128
     */
129
    public function getNamespace()
130
    {
131
        // The namespace of the registered class.
132
        return $this->xReflectionClass->getNamespaceName();
133
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
134
135
    /**
136
     * Return the namespace the callable class was registered from
137
     *
138
     * @return string
139
     */
140
    public function getRootNamespace()
141
    {
142
        // The namespace the callable class was registered from.
143
        return $this->sNamespace;
144
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
145
146
    /**
147
     * Set hook methods
148
     *
149
     * @param array         $aHookMethods      The array of hook methods
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 6 found
Loading history...
150
     * @param string|array  $xValue             The value of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter name; 13 found
Loading history...
151
     *
152
     * @return void
153
     */
154
    public function setHookMethods(&$aHookMethods, $xValue)
155
    {
156
        foreach($xValue as $sCalledMethods => $xMethodToCall)
157
        {
158
            $aCalledMethods = explode(',', $sCalledMethods);
159
            if(is_array($xMethodToCall))
160
            {
161
                foreach($aCalledMethods as $sCalledMethod)
162
                {
163
                    $aHookMethods[$sCalledMethod] = $xMethodToCall;
164
                }
165
            }
166
            elseif(is_string($xMethodToCall))
167
            {
168
                foreach($aCalledMethods as $sCalledMethod)
169
                {
170
                    $aHookMethods[$sCalledMethod] = [$xMethodToCall];
171
                }
172
            }
173
        }
174
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
175
176
    /**
177
     * Set configuration options / call options for each method
178
     *
179
     * @param string        $sName              The name of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 14 found
Loading history...
180
     * @param string|array  $xValue             The value of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 13 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
181
     *
182
     * @return void
183
     */
184
    public function configure($sName, $xValue)
185
    {
186
        switch($sName)
187
        {
188
        // Set the separator
189
        case 'separator':
190
            if($xValue == '_' || $xValue == '.')
191
            {
192
                $this->sSeparator = $xValue;
193
            }
194
            break;
195
        // Set the namespace
196
        case 'namespace':
197
            if(is_string($xValue))
198
            {
199
                $this->sNamespace = $xValue;
200
            }
201
            break;
202
        // Set the protected methods
203
        case 'protected':
204
            if(is_array($xValue))
205
            {
206
                $this->aProtectedMethods = array_merge($this->aProtectedMethods, $xValue);
207
            }
208
            elseif(is_string($xValue))
0 ignored issues
show
introduced by
The condition is_string($xValue) is always true.
Loading history...
209
            {
210
                $this->aProtectedMethods[] = $xValue;
211
            }
212
            break;
213
        // Set the methods to call before processing the request
214
        case '__before':
215
            $this->setHookMethods($this->aBeforeMethods, $xValue);
216
            break;
217
        // Set the methods to call after processing the request
218
        case '__after':
219
            $this->setHookMethods($this->aAfterMethods, $xValue);
220
            break;
221
        default:
222
            break;
223
        }
224
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
225
226
    /**
227
     * Return a list of methods of the callable object to export to javascript
228
     *
229
     * @return array
230
     */
231
    public function getMethods()
232
    {
233
        $aMethods = [];
234
        foreach($this->xReflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $xMethod)
235
        {
236
            $sMethodName = $xMethod->getShortName();
237
            // Don't take magic __call, __construct, __destruct methods
238
            if(strlen($sMethodName) > 2 && substr($sMethodName, 0, 2) == '__')
239
            {
240
                continue;
241
            }
242
            // Don't take excluded methods
243
            if(in_array($sMethodName, $this->aProtectedMethods))
244
            {
245
                continue;
246
            }
247
            $aMethods[] = $sMethodName;
248
        }
249
        return $aMethods;
250
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
251
252
    /**
253
     * Return the registered callable object
254
     *
255
     * @return null|object
256
     */
257
    public function getRegisteredObject()
258
    {
259
        if($this->xRegisteredObject == null)
260
        {
261
            $di = jaxon()->di();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 22 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
            $this->xRegisteredObject = $di->make($this->xReflectionClass);
263
            // Initialize the object
264
            if($this->xRegisteredObject instanceof \Jaxon\CallableClass)
265
            {
266
                // Set the members of the object
267
                $cSetter = function($xCallable, $xResponse) {
268
                    $this->callable = $xCallable;
0 ignored issues
show
Bug Best Practice introduced by
The property callable does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
269
                    $this->response = $xResponse;
0 ignored issues
show
Bug Best Practice introduced by
The property response does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
270
                };
271
                $cSetter = $cSetter->bindTo($this->xRegisteredObject, $this->xRegisteredObject);
272
                // Can now access protected attributes
273
                \call_user_func($cSetter, $this, jaxon()->getResponse());
274
            }
275
276
            // Run the callback for class initialisation
277
            if(($xCallback = $di->getRequestHandler()->getCallbackManager()->init()))
0 ignored issues
show
Coding Style introduced by
Variable assignment found within a condition. Did you mean to do a comparison ?
Loading history...
278
            {
279
                \call_user_func($xCallback, $this->xRegisteredObject);
280
            }
281
        }
282
        return $this->xRegisteredObject;
283
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
284
285
    /**
286
     * Check if the specified method name is one of the methods of the registered callable object
287
     *
288
     * @param string        $sMethod            The name of the method to check
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 12 found
Loading history...
289
     *
290
     * @return boolean
291
     */
292
    public function hasMethod($sMethod)
293
    {
294
        return $this->xReflectionClass->hasMethod($sMethod)/* || $this->xReflectionClass->hasMethod('__call')*/;
0 ignored issues
show
Coding Style introduced by
Single line block comment not allowed; use inline ("// text") comment instead
Loading history...
295
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
296
297
    /**
298
     * Call the specified method of the registered callable object using the specified array of arguments
299
     *
300
     * @param array     $aClassMethods      The methods config options
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter type; 5 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 6 found
Loading history...
301
     * @param string    $sMethod            The method called by the request
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter type; 4 found
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter name; 12 found
Loading history...
302
     * @param Response  $xResponse          The response returned by the method
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 10 found
Loading history...
Coding Style introduced by
Superfluous parameter comment
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
303
     *
304
     * @return void
305
     */
306
    private function callHookMethods($aClassMethods, $sMethod)
307
    {
308
        $aMethods = [];
309
        if(key_exists($sMethod, $aClassMethods))
310
        {
311
            $aMethods = $aClassMethods[$sMethod];
312
        }
313
        elseif(key_exists('*', $aClassMethods))
314
        {
315
            $aMethods = $aClassMethods['*'];
316
        }
317
        foreach($aMethods as $xKey => $xValue)
318
        {
319
            $sMethodName = $xValue;
320
            $aMethodArgs = [];
321
            if(is_string($xKey))
322
            {
323
                $sMethodName = $xKey;
324
                $aMethodArgs = is_array($xValue) ? $xValue : [$xValue];
325
            }
326
            if(!$this->xReflectionClass->hasMethod($sMethodName))
327
            {
328
                continue;
329
            }
330
            $reflectionMethod = $this->xReflectionClass->getMethod($sMethodName);
331
            $reflectionMethod->setAccessible(true); // Make it possible to call protected methods
332
            $reflectionMethod->invokeArgs($this->getRegisteredObject(), $aMethodArgs);
333
        }
334
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
335
336
    /**
337
     * Call the specified method of the registered callable object using the specified array of arguments
338
     *
339
     * @param string        $sMethod            The name of the method to call
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 12 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
340
     * @param array         $aArgs              The arguments to pass to the method
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 14 found
Loading history...
341
     *
342
     * @return null|Response
343
     */
344
    public function call($sMethod, $aArgs)
345
    {
346
        if(!$this->hasMethod($sMethod))
347
        {
348
            return null;
349
        }
350
351
        // Methods to call before processing the request
352
        $this->callHookMethods($this->aBeforeMethods, $sMethod);
353
354
        $reflectionMethod = $this->xReflectionClass->getMethod($sMethod);
355
        $xResponse = $reflectionMethod->invokeArgs($this->getRegisteredObject(), $aArgs);
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...
356
357
        // Methods to call after processing the request
358
        $this->callHookMethods($this->aAfterMethods, $sMethod);
359
360
        return $xResponse;
361
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
362
}
363