Passed
Push — master ( 291d13...46262d )
by Thierry
02:24
created

CallableRepository::getProtectedMethods()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
/**
4
 * CallableRepository.php - Jaxon callable object repository
5
 *
6
 * This class stores all the callable object already created.
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 2019 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 Jaxon\App\CallableClass;
18
use Jaxon\App\I18n\Translator;
19
use Jaxon\Di\Container;
20
use Jaxon\Exception\SetupException;
21
22
use ReflectionClass;
23
use ReflectionMethod;
24
25
use function array_merge;
26
use function is_string;
27
use function is_subclass_of;
28
use function strlen;
29
use function strncmp;
30
31
class CallableRepository
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CallableRepository
Loading history...
32
{
33
    /**
34
     * The DI container
35
     *
36
     * @var Container
37
     */
38
    protected $di;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
39
40
    /**
41
     * @var Translator
42
     */
43
    protected $xTranslator;
44
45
    /**
46
     * The namespace options
47
     *
48
     * These are the options of the registered namespaces.
49
     *
50
     * @var array
51
     */
52
    protected $aNamespaceOptions = [];
53
54
    /**
55
     * The directory options
56
     *
57
     * These are the options of the registered directories.
58
     *
59
     * @var array
60
     */
61
    protected $aDirectoryOptions = [];
62
63
    /**
64
     * The classes
65
     *
66
     * These are all the classes, both registered and found in registered directories.
67
     *
68
     * @var array
69
     */
70
    protected $aClasses = [];
71
72
    /**
73
     * The namespaces
74
     *
75
     * These are all the namespaces found in registered directories.
76
     *
77
     * @var array
78
     */
79
    protected $aNamespaces = [];
80
81
    /**
82
     * The string that will be used to compute the js file hash
83
     *
84
     * @var string
85
     */
86
    protected $sHash = '';
87
88
    /**
89
     * @var array
90
     */
91
    private $aDefaultClassOptions = ['separator' => '.', 'protected' => [], 'functions' => [], 'timestamp' => 0];
92
93
    /**
94
     * The methods that must not be exported to js
95
     *
96
     * @var array
97
     */
98
    private $aProtectedMethods = [];
99
100
    /**
101
     * The constructor
102
     *
103
     * @param Container $di
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...
104
     * @param Translator $xTranslator
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
105
     */
106
    public function __construct(Container $di, Translator $xTranslator)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
107
    {
108
        $this->di = $di;
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...
109
        $this->xTranslator = $xTranslator;
110
111
        // The methods of the CallableClass class must not be exported
112
        $xCallableClass = new ReflectionClass(CallableClass::class);
113
        foreach($xCallableClass->getMethods(ReflectionMethod::IS_PUBLIC) as $xMethod)
114
        {
115
            $this->aProtectedMethods[] = $xMethod->getName();
116
        }
117
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
118
119
    /**
120
     * @return array
121
     */
122
    public function getDirectoryOptions(): array
123
    {
124
        return $this->aDirectoryOptions;
125
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
126
127
    /**
128
     * @param string $sDirectory
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
129
     * @param array $aOptions
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...
130
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
131
    public function setDirectoryOptions(string $sDirectory, array $aOptions): void
132
    {
133
        $this->aDirectoryOptions[$sDirectory] = $aOptions;
134
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
135
136
    /**
137
     * @return array
138
     */
139
    public function getNamespaceOptions(): array
140
    {
141
        return $this->aNamespaceOptions;
142
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
143
144
    /**
145
     * @param string $sNamespace
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
146
     * @param array $aOptions
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...
147
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
148
    public function setNamespaceOptions(string $sNamespace, array $aOptions): void
149
    {
150
        $this->aNamespaceOptions[$sNamespace] = $aOptions;
151
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
152
153
    /**
154
     * Get all registered namespaces
155
     *
156
     * @return array
157
     */
158
    public function getNamespaces(): array
159
    {
160
        return $this->aNamespaces;
161
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
162
163
    /**
164
     * Get the hash
165
     *
166
     * @return string
167
     */
168
    public function getHash(): string
169
    {
170
        return $this->sHash;
171
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
172
173
    /**
174
     * Get a given class options from specified directory options
175
     *
176
     * @param string $sClassName    The class name
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 4 found
Loading history...
177
     * @param array $aClassOptions    The default class options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
178
     * @param array $aDirectoryOptions    The directory options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
179
     *
180
     * @return array
181
     */
182
    public function makeClassOptions(string $sClassName, array $aClassOptions, array $aDirectoryOptions): array
183
    {
184
        foreach($this->aDefaultClassOptions as $sOption => $xValue)
185
        {
186
            if(!isset($aClassOptions[$sOption]))
187
            {
188
                $aClassOptions[$sOption] = $xValue;
189
            }
190
        }
191
        if(is_string($aClassOptions['protected']))
192
        {
193
            $aClassOptions['protected'] = [$aClassOptions['protected']]; // Convert to array.
194
        }
195
196
        $aDirectoryOptions['functions'] = []; // The 'functions' section is not allowed here.
197
        $aOptionGroups = [
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 18 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...
198
            $aDirectoryOptions, // Options at directory level
199
            $aDirectoryOptions['classes']['*'] ?? [], // Options for all classes
200
            $aDirectoryOptions['classes'][$sClassName] ?? [], // Options for this specific class
201
        ];
202
        foreach($aOptionGroups as $aOptionGroup)
203
        {
204
            if(isset($aOptionGroup['separator']))
205
            {
206
                $aClassOptions['separator'] = $aOptionGroup['separator'];
207
            }
208
            if(isset($aOptionGroup['protected']))
209
            {
210
                if(is_string($aOptionGroup['protected']))
211
                {
212
                    $aOptionGroup['protected'] = [$aOptionGroup['protected']]; // Convert to array.
213
                }
214
                $aClassOptions['protected'] = array_merge($aClassOptions['protected'], $aOptionGroup['protected']);
215
            }
216
            if(isset($aOptionGroup['functions']))
217
            {
218
                $aClassOptions['functions'] = array_merge($aClassOptions['functions'], $aOptionGroup['functions']);
219
            }
220
        }
221
222
        return $aClassOptions;
223
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
224
225
    /**
226
     *
227
     * @param string $sClassName    The class name
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 4 found
Loading history...
228
     * @param array $aClassOptions    The default class options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
229
     * @param array $aDirectoryOptions    The directory options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
230
     *
231
     * @return void
232
     */
233
    public function addClass(string $sClassName, array $aClassOptions, array $aDirectoryOptions = [])
234
    {
235
        $this->aClasses[$sClassName] = $this->makeClassOptions($sClassName, $aClassOptions, $aDirectoryOptions);
236
        $this->sHash .= $sClassName . $this->aClasses[$sClassName]['timestamp'];
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...
237
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
238
239
    /**
240
     *
241
     * @param string $sNamespace    The namespace
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
242
     * @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 3 spaces after parameter name; 4 found
Loading history...
243
     *
244
     * @return void
245
     */
246
    public function addNamespace(string $sNamespace, array $aOptions)
247
    {
248
        $this->aNamespaces[] = $sNamespace;
249
        $this->sHash .= $sNamespace . $aOptions['separator'];
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...
250
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
251
252
    /**
253
     * Find options for a class which is registered with namespace
254
     *
255
     * @param string $sClassName    The class name
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
256
     *
257
     * @return void
258
     */
259
    private function getNamespaceClassOptions(string $sClassName)
260
    {
261
        // Find the corresponding namespace
262
        foreach($this->aNamespaceOptions as $sNamespace => $aOptions)
263
        {
264
            // Check if the namespace matches the class.
265
            if(strncmp($sClassName, $sNamespace . '\\', strlen($sNamespace) + 1) === 0)
266
            {
267
                // Save the class options
268
                $this->aClasses[$sClassName] = $this->makeClassOptions($sClassName,
269
                    ['namespace' => $sNamespace], $aOptions);
270
                return;
271
            }
272
        }
273
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
274
275
    /**
276
     * Find the options associated with a registered class name
277
     *
278
     * @param string $sClassName The class name
279
     *
280
     * @return array
281
     * @throws SetupException
282
     */
283
    public function getClassOptions(string $sClassName): array
284
    {
285
        // Find options for a class registered with namespace.
286
        if(!isset($this->aClasses[$sClassName]))
287
        {
288
            $this->getNamespaceClassOptions($sClassName);
289
            if(!isset($this->aClasses[$sClassName]))
290
            {
291
                // Find options for a class registered without namespace.
292
                // We then need to parse all classes to be able to find one.
293
                $this->di->getCallableRegistry()->parseDirectories();
294
            }
295
        }
296
        if(isset($this->aClasses[$sClassName]))
297
        {
298
            return $this->aClasses[$sClassName];
299
        }
300
        $sMessage = $this->xTranslator->trans('errors.class.invalid', ['name' => $sClassName]);
301
        throw new SetupException($sMessage);
302
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
303
304
    /**
305
     * Find the options associated with a registered class name
306
     *
307
     * @param string $sClassName The class name
308
     *
309
     * @return array
310
     */
311
    public function getProtectedMethods(string $sClassName): array
312
    {
313
        return is_subclass_of($sClassName, CallableClass::class) ? $this->aProtectedMethods : [];
314
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
315
316
    /**
317
     * Get callable objects for known classes
318
     *
319
     * @return array
320
     * @throws SetupException
321
     */
322
    public function getCallableObjects(): array
323
    {
324
        $aCallableObjects = [];
325
        foreach($this->aClasses as $sClassName => $aOptions)
326
        {
327
            if(!$this->di->h($sClassName))
328
            {
329
                $this->di->registerCallableClass($sClassName, $aOptions);
330
            }
331
            $aCallableObjects[$sClassName] = $this->di->getCallableObject($sClassName);
332
        }
333
        return $aCallableObjects;
334
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
335
}
336