Passed
Push — main ( ea93ae...aa41db )
by Thierry
02:59 queued 10s
created

CallableObjectOptions::__construct()   B

Complexity

Conditions 8
Paths 26

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 28
rs 8.4444
cc 8
nc 26
nop 2
1
<?php
2
3
/**
4
 * CallableObjectOptions.php
5
 *
6
 * Options of a callable object.
7
 *
8
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2024 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
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...
14
15
namespace Jaxon\Plugin\Request\CallableClass;
16
17
use function array_merge;
18
use function array_unique;
19
use function is_array;
20
use function is_string;
21
use function substr;
22
use function trim;
23
24
class CallableObjectOptions
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CallableObjectOptions
Loading history...
25
{
26
    /**
27
     * Check if the js code for this object must be generated
28
     *
29
     * @var bool
0 ignored issues
show
Bug introduced by
Expected "boolean" but found "bool" for @var tag in member variable comment
Loading history...
30
     */
31
    private $bExcluded = false;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
32
33
    /**
34
     * The character to use as separator in javascript class names
35
     *
36
     * @var string
37
     */
38
    private $sSeparator = '.';
39
40
    /**
41
     * A list of methods of the user registered callable object the library must not export to javascript
42
     *
43
     * @var array
44
     */
45
    private $aProtectedMethods = [];
46
47
    /**
48
     * A list of methods to call before processing the request
49
     *
50
     * @var array
51
     */
52
    private $aBeforeMethods = [];
53
54
    /**
55
     * A list of methods to call after processing the request
56
     *
57
     * @var array
58
     */
59
    private $aAfterMethods = [];
60
61
    /**
62
     * The javascript class options
63
     *
64
     * @var array
65
     */
66
    private $aJsOptions = [];
67
68
    /**
69
     * The DI options
70
     *
71
     * @var array
72
     */
73
    private $aDiOptions = [];
74
75
    /**
76
     * The constructor
77
     *
78
     * @param array $aOptions
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
79
     * @param array $aAnnotations
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
80
     */
81
    public function __construct(array $aOptions, array $aAnnotations)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
82
    {
83
        [$bExcluded, $aAnnotationOptions, $aAnnotationProtected] = $aAnnotations;
84
        $this->bExcluded = $bExcluded || (bool)($aOptions['excluded'] ?? false);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 41 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...
85
        if($this->bExcluded)
86
        {
87
            return;
88
        }
89
90
        $sSeparator = $aOptions['separator'];
91
        if($sSeparator === '_' || $sSeparator === '.')
92
        {
93
            $this->sSeparator = $sSeparator;
94
        }
95
        $this->addProtectedMethods($aOptions['protected']);
96
        $this->addProtectedMethods($aAnnotationProtected);
97
98
        foreach($aOptions['functions'] as $sNames => $aFunctionOptions)
99
        {
100
            $aFunctionNames = explode(',', $sNames); // Names are in comma-separated list.
101
            foreach($aFunctionNames as $sFunctionName)
102
            {
103
                $this->addFunctionOptions($sFunctionName, $aFunctionOptions);
104
            }
105
        }
106
        foreach($aAnnotationOptions as $sFunctionName => $aFunctionOptions)
107
        {
108
            $this->addFunctionOptions($sFunctionName, $aFunctionOptions);
109
        }
110
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
111
112
    /**
113
     * @param mixed $xMethods
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
114
     *
115
     * @return void
116
     */
117
    private function addProtectedMethods($xMethods)
118
    {
119
        if(!is_array($xMethods))
120
        {
121
            $this->aProtectedMethods[trim((string)$xMethods)] = true;
122
            return;
123
        }
124
        foreach($xMethods as $sMethod)
125
        {
126
            $this->aProtectedMethods[trim((string)$sMethod)] = true;
127
        }
128
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
129
130
    /**
131
     * Check if the js code for this object must be generated
132
     *
133
     * @return bool
134
     */
135
    public function excluded(): bool
136
    {
137
        return $this->bExcluded;
138
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
139
140
    /**
141
     * @return string
142
     */
143
    public function separator(): string
144
    {
145
        return $this->sSeparator;
146
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
147
148
    /**
149
     * @param string $sMethodName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
150
     *
151
     * @return bool
152
     */
153
    public function isProtectedMethod(string $sMethodName): bool
154
    {
155
        return isset($this->aProtectedMethods[$sMethodName]) || isset($this->aProtectedMethods['*']);
156
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
157
158
    /**
159
     * @return array
160
     */
161
    public function beforeMethods(): array
162
    {
163
        return $this->aBeforeMethods;
164
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
165
166
    /**
167
     * @return array
168
     */
169
    public function afterMethods(): array
170
    {
171
        return $this->aAfterMethods;
172
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
173
174
    /**
175
     * @return array
176
     */
177
    public function diOptions(): array
178
    {
179
        return $this->aDiOptions;
180
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
181
182
    /**
183
     * @return array
184
     */
185
    public function jsOptions(): array
186
    {
187
        return $this->aJsOptions;
188
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
189
190
    /**
191
     * Set hook methods
192
     *
193
     * @param array $aHookMethods    The array of hook methods
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
194
     * @param string|array $xValue    The value of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter name; 4 found
Loading history...
195
     *
196
     * @return void
197
     */
198
    private function setHookMethods(array &$aHookMethods, $xValue)
199
    {
200
        foreach($xValue as $sCalledMethod => $xMethodToCall)
201
        {
202
            if(is_array($xMethodToCall))
203
            {
204
                $aHookMethods[$sCalledMethod] = $xMethodToCall;
205
            }
206
            elseif(is_string($xMethodToCall))
207
            {
208
                $aHookMethods[$sCalledMethod] = [$xMethodToCall];
209
            }
210
        }
211
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
212
213
    /**
214
     * @param array $aDiOptions
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
215
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
216
    private function addDiOption(array $aDiOptions)
217
    {
218
        $this->aDiOptions = array_merge($this->aDiOptions, $aDiOptions);
219
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
220
221
    /**
222
     * Set configuration options / call options for each method
223
     *
224
     * @param string $sName    The name of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 4 found
Loading history...
225
     * @param string|array $xValue    The value of the configuration option
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
226
     *
227
     * @return void
228
     */
229
    private function addOption(string $sName, $xValue)
230
    {
231
        switch($sName)
232
        {
233
        // Set the methods to call before processing the request
234
        case '__before':
235
            $this->setHookMethods($this->aBeforeMethods, $xValue);
236
            break;
237
        // Set the methods to call after processing the request
238
        case '__after':
239
            $this->setHookMethods($this->aAfterMethods, $xValue);
240
            break;
241
        // Set the attributes to inject in the callable object
242
        case '__di':
243
            $this->addDiOption($xValue);
0 ignored issues
show
Bug introduced by
It seems like $xValue can also be of type string; however, parameter $aDiOptions of Jaxon\Plugin\Request\Cal...tOptions::addDiOption() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

243
            $this->addDiOption(/** @scrutinizer ignore-type */ $xValue);
Loading history...
244
            break;
245
        default:
246
            break;
247
        }
248
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
249
250
    /**
251
     * @param string $sFunctionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
252
     * @param string $sOptionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
253
     * @param mixed $xOptionValue
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
254
     *
255
     * @return void
256
     */
257
    private function _addJsArrayOption(string $sFunctionName, string $sOptionName, $xOptionValue)
258
    {
259
        if(is_string($xOptionValue))
260
        {
261
            $xOptionValue = [$xOptionValue];
262
        }
263
        if(!is_array($xOptionValue))
264
        {
265
            return; // Do not save.
266
        }
267
        $aOptions = $this->aJsOptions[$sFunctionName][$sOptionName] ?? [];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 39 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...
268
        $this->aJsOptions[$sFunctionName][$sOptionName] = array_merge($aOptions, $xOptionValue);
269
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
270
271
    /**
272
     * @param string $sFunctionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
273
     * @param string $sOptionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
274
     * @param mixed $xOptionValue
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
275
     *
276
     * @return void
277
     */
278
    private function _setJsOption(string $sFunctionName, string $sOptionName, $xOptionValue)
279
    {
280
        $this->aJsOptions[$sFunctionName][$sOptionName] = $xOptionValue;
281
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
282
283
    /**
284
     * @param string $sFunctionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
285
     * @param string $sOptionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
286
     * @param mixed $xOptionValue
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
287
     *
288
     * @return void
289
     */
290
    private function addJsOption(string $sFunctionName, string $sOptionName, $xOptionValue)
291
    {
292
        switch($sOptionName)
293
        {
294
        case 'excluded':
295
            if((bool)$xOptionValue)
296
            {
297
                $this->addProtectedMethods($sFunctionName);
298
            }
299
            break;
300
        // For databags, all the value are merged in a single array.
301
        case 'bags':
302
            $this->_addJsArrayOption($sFunctionName, $sOptionName, $xOptionValue);
303
            return;
304
        // For all the other options, including callback, only the last value is kept.
305
        case 'callback':
306
        default:
307
            $this->_setJsOption($sFunctionName, $sOptionName, $xOptionValue);
308
        }
309
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
310
311
    /**
312
     * @param string $sFunctionName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
313
     * @param array $aFunctionOptions
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
314
     *
315
     * @return void
316
     */
317
    private function addFunctionOptions(string $sFunctionName, array $aFunctionOptions)
318
    {
319
        foreach($aFunctionOptions as $sOptionName => $xOptionValue)
320
        {
321
            substr($sOptionName, 0, 2) === '__' ?
0 ignored issues
show
Coding Style introduced by
Expected 1 space after "?"; newline found
Loading history...
322
                // Options for PHP classes. They start with "__".
323
                $this->addOption($sOptionName, [$sFunctionName => $xOptionValue]) :
0 ignored issues
show
Coding Style introduced by
Expected 1 space after ":"; newline found
Loading history...
324
                // Options for javascript code.
325
                $this->addJsOption($sFunctionName, $sOptionName, $xOptionValue);
326
        }
327
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
328
329
    /**
330
     * @param string $sMethodName
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
331
     *
332
     * @return array
333
     */
334
    public function getMethodOptions(string $sMethodName): array
335
    {
336
        // First take the common options.
337
        $aOptions = array_merge($this->aJsOptions['*'] ?? []); // Clone the array
338
        // Then add the method options.
339
        $aMethodOptions = $this->aJsOptions[$sMethodName] ?? [];
340
        foreach($aMethodOptions as $sOptionName => $xOptionValue)
341
        {
342
            // For databags, merge the values in a single array.
343
            // For all the other options, including callback, keep the last value.
344
            $aOptions[$sOptionName] = $sOptionName !== 'bags' ? $xOptionValue :
0 ignored issues
show
Coding Style introduced by
Expected 1 space after ":"; newline found
Loading history...
345
                array_unique(array_merge($aOptions[$sOptionName] ?? [], $xOptionValue));
346
        }
347
        return $aOptions;
348
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
349
}
350