Passed
Push — master ( 8eafb5...9551a9 )
by Thierry
02:09
created

ClassPlugin::__construct()   A

Complexity

Conditions 6
Paths 32

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 19
nc 32
nop 8
dl 0
loc 35
rs 9.0111
c 1
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * ClassPlugin.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\CallableClass;
23
24
use Jaxon\Jaxon;
25
use Jaxon\CallableClass;
26
use Jaxon\Plugin\Request as RequestPlugin;
27
use Jaxon\Request\Handler\Handler as RequestHandler;
28
use Jaxon\Request\Target;
29
use Jaxon\Request\Validator;
30
use Jaxon\Response\Manager as ResponseManager;
31
use Jaxon\Utils\Config\Config;
32
use Jaxon\Utils\Template\Engine as TemplateEngine;
33
use Jaxon\Utils\Translation\Translator;
34
use Jaxon\Exception\RequestException;
35
use Jaxon\Exception\SetupException;
36
37
use ReflectionException;
38
39
use function is_array;
40
use function is_string;
41
use function is_subclass_of;
42
use function md5;
43
use function strlen;
44
use function trim;
45
use function uksort;
46
47
class ClassPlugin extends RequestPlugin
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class ClassPlugin
Loading history...
48
{
49
    /**
50
     * @var Config
51
     */
52
    protected $xConfig;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
53
54
    /**
55
     * The request handler
56
     *
57
     * @var RequestHandler
58
     */
59
    protected $xRequestHandler;
60
61
    /**
62
     * The response manager
63
     *
64
     * @var ResponseManager
65
     */
66
    protected $xResponseManager;
67
68
    /**
69
     * The callable registry
70
     *
71
     * @var Registry
72
     */
73
    protected $xRegistry;
74
75
    /**
76
     * The callable repository
77
     *
78
     * @var Repository
79
     */
80
    protected $xRepository;
81
82
    /**
83
     * The request data validator
84
     *
85
     * @var Validator
86
     */
87
    protected $xValidator;
88
89
    /**
90
     * @var TemplateEngine
91
     */
92
    protected $xTemplateEngine;
93
94
    /**
95
     * @var Translator
96
     */
97
    protected $xTranslator;
98
99
    /**
100
     * The value of the class parameter of the incoming Jaxon request
101
     *
102
     * @var string
103
     */
104
    protected $sRequestedClass = '';
105
106
    /**
107
     * The value of the method parameter of the incoming Jaxon request
108
     *
109
     * @var string
110
     */
111
    protected $sRequestedMethod = '';
112
113
    /**
114
     * The methods that must not be exported to js
115
     *
116
     * @var array
117
     */
118
    protected $aProtectedMethods = [];
119
120
    /**
121
     * The class constructor
122
     *
123
     * @param Config  $xConfig
0 ignored issues
show
Coding Style introduced by
Expected 10 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
124
     * @param RequestHandler  $xRequestHandler
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
125
     * @param ResponseManager  $xResponseManager
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
126
     * @param Registry $xRegistry    The callable class registry
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 4 found
Loading history...
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
127
     * @param Repository $xRepository    The callable object repository
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 6 spaces after parameter name; 4 found
Loading history...
128
     * @param TemplateEngine  $xTemplateEngine
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
129
     * @param Translator  $xTranslator
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
130
     * @param Validator  $xValidator
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter type; 2 found
Loading history...
131
     */
132
    public function __construct(Config $xConfig, RequestHandler $xRequestHandler,
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
133
        ResponseManager $xResponseManager, Registry $xRegistry, Repository $xRepository,
134
        TemplateEngine  $xTemplateEngine, Translator $xTranslator, Validator $xValidator)
135
    {
136
        $this->xConfig = $xConfig;
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...
137
        $this->xRequestHandler = $xRequestHandler;
138
        $this->xResponseManager = $xResponseManager;
139
        $this->xRegistry = $xRegistry;
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...
140
        $this->xRepository = $xRepository;
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...
141
        $this->xTemplateEngine = $xTemplateEngine;
142
        $this->xTranslator = $xTranslator;
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...
143
        $this->xValidator = $xValidator;
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...
144
145
        if(isset($_GET['jxncls']))
146
        {
147
            $this->sRequestedClass = trim($_GET['jxncls']);
148
        }
149
        if(isset($_GET['jxnmthd']))
150
        {
151
            $this->sRequestedMethod = trim($_GET['jxnmthd']);
152
        }
153
        if(isset($_POST['jxncls']))
154
        {
155
            $this->sRequestedClass = trim($_POST['jxncls']);
156
        }
157
        if(isset($_POST['jxnmthd']))
158
        {
159
            $this->sRequestedMethod = trim($_POST['jxnmthd']);
160
        }
161
162
        // The methods of the \Jaxon\ClassPlugin class must not be exported
163
        $xCallableClass = new \ReflectionClass(CallableClass::class);
164
        foreach($xCallableClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $xMethod)
165
        {
166
            $this->aProtectedMethods[] = $xMethod->getName();
167
        }
168
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
169
170
    /**
171
     * @inheritDoc
172
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
173
    public function getName(): string
174
    {
175
        return Jaxon::CALLABLE_CLASS;
176
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
177
178
    /**
179
     * @inheritDoc
180
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
181
    public function getTarget(): ?Target
182
    {
183
        if(!$this->sRequestedClass || !$this->sRequestedMethod)
184
        {
185
            return null;
186
        }
187
        return Target::makeClass($this->sRequestedClass, $this->sRequestedMethod);
188
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
189
190
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $xOptions should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $sCallable should have a doc-comment as per coding-style.
Loading history...
191
     * @inheritDoc
192
     * @throws SetupException
193
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
194
    public function checkOptions(string $sCallable, $xOptions): array
195
    {
196
        if(!$this->xValidator->validateClass(trim($sCallable)))
197
        {
198
            throw new SetupException($this->xTranslator->trans('errors.objects.invalid-declaration'));
199
        }
200
        if(is_string($xOptions))
201
        {
202
            $xOptions = ['include' => $xOptions];
203
        }
204
        elseif(!is_array($xOptions))
205
        {
206
            throw new SetupException($this->xTranslator->trans('errors.objects.invalid-declaration'));
207
        }
208
        return $xOptions;
209
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
210
211
    /**
212
     * Register a callable class
213
     *
214
     * @param string $sType    The type of request handler being registered
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
215
     * @param string $sCallable    The name of the class being registered
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
216
     * @param array $aOptions    The associated options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 4 found
Loading history...
217
     *
218
     * @return bool
219
     */
220
    public function register(string $sType, string $sCallable, array $aOptions): bool
221
    {
222
        $sClassName = trim($sCallable);
223
        $this->xRepository->addClass($sClassName, $aOptions);
224
        return true;
225
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
226
227
    /**
228
     * @inheritDoc
229
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
230
    public function getHash(): string
231
    {
232
        $this->xRegistry->parseCallableClasses();
233
        $aNamespaces = $this->xRepository->getNamespaces();
234
        $aClasses = $this->xRepository->getClasses();
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...
235
        $sHash = '';
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...
236
237
        foreach($aNamespaces as $sNamespace => $aOptions)
238
        {
239
            $sHash .= $sNamespace . $aOptions['separator'];
240
        }
241
        foreach($aClasses as $sClassName => $aOptions)
242
        {
243
            $sHash .= $sClassName . $aOptions['timestamp'];
244
        }
245
246
        return md5($sHash);
247
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
248
249
    /**
250
     * Generate client side javascript code for namespaces
251
     *
252
     * @return string
253
     */
254
    private function getNamespacesScript(): string
255
    {
256
        $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...
257
        $sPrefix = $this->xConfig->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...
258
        $aJsClasses = [];
259
        $aNamespaces = array_keys($this->xRepository->getNamespaces());
260
        foreach($aNamespaces as $sNamespace)
261
        {
262
            $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...
263
            $sJsNamespace = str_replace('\\', '.', $sNamespace);
264
            $sJsNamespace .= '.Null'; // This is a sentinel. The last token is not processed in the while loop.
265
            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...
266
            {
267
                $sJsClass = substr($sJsNamespace, 0, $dotPosition);
268
                // Generate code for this object
269
                if(!isset($aJsClasses[$sJsClass]))
270
                {
271
                    $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...
272
                    $aJsClasses[$sJsClass] = $sJsClass;
273
                }
274
                $offset = $dotPosition + 1;
275
            }
276
        }
277
        return $sCode;
278
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
279
280
    /**
281
     * Generate client side javascript code for a callable class
282
     *
283
     * @param string $sClassName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
284
     * @param CallableObject $xCallableObject The corresponding callable object
285
     *
286
     * @return string
287
     */
288
    private function getCallableScript(string $sClassName, CallableObject $xCallableObject): string
289
    {
290
        $aProtectedMethods = is_subclass_of($sClassName, CallableClass::class) ? $this->aProtectedMethods : [];
291
        return $this->xTemplateEngine->render('jaxon::support/object.js', [
292
            'sPrefix' => $this->xConfig->getOption('core.prefix.class'),
293
            'sClass' => $xCallableObject->getJsName(),
294
            'aMethods' => $xCallableObject->getMethods($aProtectedMethods),
295
        ]);
296
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
297
298
    /**
299
     * Generate client side javascript code for the registered callable objects
300
     *
301
     * @return string
302
     */
303
    public function getScript(): string
304
    {
305
        $this->xRegistry->registerCallableClasses();
306
307
        $sCode = $this->getNamespacesScript();
308
309
        $aClassNames = $this->xRepository->getClassNames();
310
        // Sort the options by key length asc
311
        uksort($aClassNames, function($name1, $name2) {
312
            return strlen($name1) - strlen($name2);
313
        });
314
        foreach($aClassNames as $sClassName)
315
        {
316
            $xCallableObject = $this->xRegistry->getCallableObject($sClassName);
317
            $sCode .= $this->getCallableScript($sClassName, $xCallableObject);
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...
318
        }
319
320
        return $sCode;
321
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
322
323
    /**
324
     * @inheritDoc
325
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
326
    public function canProcessRequest(): bool
327
    {
328
        // Check the validity of the class name
329
        if(($this->sRequestedClass !== null && !$this->xValidator->validateClass($this->sRequestedClass)) ||
330
            ($this->sRequestedMethod !== null && !$this->xValidator->validateMethod($this->sRequestedMethod)))
331
        {
332
            $this->sRequestedClass = null;
333
            $this->sRequestedMethod = null;
334
        }
335
        return ($this->sRequestedClass !== null && $this->sRequestedMethod !== null);
336
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
337
338
    /**
339
     * @inheritDoc
340
     * @throws RequestException
341
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
342
    public function processRequest(): bool
343
    {
344
        if(!$this->canProcessRequest())
345
        {
346
            return false;
347
        }
348
349
        // Find the requested method
350
        $xCallableObject = $this->xRegistry->getCallableObject($this->sRequestedClass);
351
        if(!$xCallableObject || !$xCallableObject->hasMethod($this->sRequestedMethod))
0 ignored issues
show
introduced by
$xCallableObject is of type Jaxon\Request\Plugin\CallableClass\CallableObject, thus it always evaluated to true.
Loading history...
352
        {
353
            // Unable to find the requested object or method
354
            throw new RequestException($this->xTranslator->trans('errors.objects.invalid',
355
                ['class' => $this->sRequestedClass, 'method' => $this->sRequestedMethod]));
356
        }
357
358
        // Call the requested method
359
        $aArgs = $this->xRequestHandler->processArguments();
360
        try
361
        {
362
            $xResponse = $xCallableObject->call($this->sRequestedMethod, $aArgs);
363
            if(($xResponse))
364
            {
365
                $this->xResponseManager->append($xResponse);
366
            }
367
        }
368
        catch(ReflectionException $e)
369
        {
370
            // Unable to find the requested class
371
            throw new RequestException($this->xTranslator->trans('errors.objects.invalid',
372
                ['class' => $this->sRequestedClass, 'method' => $this->sRequestedMethod]));
373
        }
374
        return true;
375
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
376
}
377