Passed
Push — master ( 0602c9...8f96ba )
by Thierry
02:02
created

CallableRepository::parseNamespaces()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 33
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 33
rs 9.0777
c 0
b 0
f 0
cc 6
nc 5
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\Request\Support;
16
17
use Jaxon\Container\Container;
18
19
use RecursiveDirectoryIterator;
20
use RecursiveIteratorIterator;
21
22
use function explode;
23
use function strncmp;
24
use function strlen;
25
use function array_merge;
26
use function key_exists;
27
28
class CallableRepository
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class CallableRepository
Loading history...
29
{
30
    /**
31
     * The DI container
32
     *
33
     * @var Container
34
     */
35
    protected $di;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
36
37
    /**
38
     * The classes
39
     *
40
     * These are all the registered classes.
41
     *
42
     * @var array
43
     */
44
    protected $aClasses = [];
45
46
    /**
47
     * The namespaces
48
     *
49
     * These are all the namespaces found in registered directories.
50
     *
51
     * @var array
52
     */
53
    protected $aNamespaces = [];
54
55
    /**
56
     * The constructor
57
     *
58
     * @param Container         $di
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
59
     */
60
    public function __construct(Container $di)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
61
    {
62
        $this->di = $di;
63
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
64
65
    /**
66
     * Get a given class options from specified directory options
67
     *
68
     * @param string        $sClassName         The class name
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 9 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
69
     * @param array         $aClassOptions      The default class options
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 6 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
70
     * @param array         $aDirectoryOptions  The directory options
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
71
     *
72
     * @return array
73
     */
74
    public function makeClassOptions($sClassName, array $aClassOptions, array $aDirectoryOptions)
75
    {
76
        if(!key_exists('functions', $aClassOptions))
77
        {
78
            $aClassOptions['functions'] = [];
79
        }
80
        foreach(['separator', 'protected'] as $sName)
81
        {
82
            if(key_exists($sName, $aDirectoryOptions))
83
            {
84
                $aClassOptions[$sName] = $aDirectoryOptions[$sName];
85
            }
86
        }
87
88
        $aFunctionOptions = key_exists('classes', $aDirectoryOptions) ? $aDirectoryOptions['classes'] : [];
89
        foreach($aFunctionOptions as $sName => $xValue)
90
        {
91
            if($sName === '*' || strncmp($sClassName, $sName, strlen($sName)) === 0)
92
            {
93
                $aClassOptions['functions'] = array_merge($aClassOptions['functions'], $xValue);
94
            }
95
        }
96
97
        // This value will be used to compute hash
98
        if(!key_exists('timestamp', $aClassOptions))
99
        {
100
            $aClassOptions['timestamp'] = 0;
101
        }
102
103
        return $aClassOptions;
104
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
105
106
    /**
107
     * Get all registered classes
108
     *
109
     * @return array
110
     */
111
    public function getClasses()
112
    {
113
        return $this->aClasses;
114
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
115
116
    /**
117
     * Get all registered namespaces
118
     *
119
     * @return array
120
     */
121
    public function getNamespaces()
122
    {
123
        return $this->aNamespaces;
124
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
125
126
    /**
127
     * Get the names of all registered classess
128
     *
129
     * @return array
130
     */
131
    public function getClassNames()
132
    {
133
        return array_keys($this->aClasses);
134
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
135
136
    /**
137
     *
138
     * @param string        $sClassName         The class name
0 ignored issues
show
Coding Style introduced by
Expected 8 spaces after parameter name; 9 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 8 found
Loading history...
139
     * @param array         $aClassOptions      The default class options
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 6 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
140
     * @param array         $aDirectoryOptions  The directory options
0 ignored issues
show
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
141
     *
142
     * @return void
143
     */
144
    public function addClass($sClassName, array $aClassOptions, array $aDirectoryOptions = [])
145
    {
146
        $this->aClasses[$sClassName] = $this->makeClassOptions($sClassName, $aClassOptions, $aDirectoryOptions);
147
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
148
149
    /**
150
     *
151
     * @param string        $sNamespace     The namespace
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 5 found
Loading history...
Coding Style introduced by
Expected 7 spaces after parameter type; 8 found
Loading history...
152
     * @param array|string  $aOptions       The associated options
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 7 found
Loading history...
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
153
     *
154
     * @return void
155
     */
156
    public function addNamespace($sNamespace, $aOptions)
157
    {
158
        $this->aNamespaces[$sNamespace] = $aOptions;
159
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
160
161
    /**
162
     * Find the options associated with a registered class name
163
     *
164
     * @param string        $sClassName            The class name
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...
165
     *
166
     * @return array|null
167
     */
168
    public function getClassOptions($sClassName)
169
    {
170
        if(!key_exists($sClassName, $this->aClasses))
171
        {
172
            // Class not found
173
            return null;
174
        }
175
        return $this->aClasses[$sClassName];
176
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
177
178
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $aDirectories should have a doc-comment as per coding-style.
Loading history...
179
     * Read classes from directories registered without namespaces
180
     *
181
     * @return void
182
     */
183
    public function parseDirectories(array $aDirectories)
184
    {
185
        // Browse directories without namespaces and read all the files.
186
        foreach($aDirectories as $sDirectory => $aOptions)
187
        {
188
            $itFile = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sDirectory));
189
            // Iterate on dir content
190
            foreach($itFile as $xFile)
191
            {
192
                // skip everything except PHP files
193
                if(!$xFile->isFile() || $xFile->getExtension() != 'php')
194
                {
195
                    continue;
196
                }
197
198
                $sClassName = $xFile->getBasename('.php');
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...
199
                $aClassOptions = ['timestamp' => $xFile->getMTime()];
200
                // No more classmap autoloading. The file will be included when needed.
201
                if(($aOptions['autoload']))
202
                {
203
                    $aClassOptions['include'] = $xFile->getPathname();
204
                }
205
                $this->addClass($sClassName, $aClassOptions, $aOptions);
206
            }
207
        }
208
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
209
210
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $aNamespaces should have a doc-comment as per coding-style.
Loading history...
211
     * Read classes from directories registered with namespaces
212
     *
213
     * @return void
214
     */
215
    public function parseNamespaces(array $aNamespaces)
216
    {
217
        // Browse directories with namespaces and read all the files.
218
        $sDS = DIRECTORY_SEPARATOR;
219
        foreach($aNamespaces as $sNamespace => $aOptions)
220
        {
221
            $this->addNamespace($sNamespace, ['separator' => $aOptions['separator']]);
222
223
            // Iterate on dir content
224
            $sDirectory = $aOptions['directory'];
225
            $itFile = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($sDirectory));
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...
226
            foreach($itFile as $xFile)
227
            {
228
                // skip everything except PHP files
229
                if(!$xFile->isFile() || $xFile->getExtension() != 'php')
230
                {
231
                    continue;
232
                }
233
234
                // Find the class path (the same as the class namespace)
235
                $sClassPath = $sNamespace;
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...
236
                $sRelativePath = substr($xFile->getPath(), strlen($sDirectory));
237
                $sRelativePath = trim(str_replace($sDS, '\\', $sRelativePath), '\\');
238
                if($sRelativePath != '')
239
                {
240
                    $sClassPath .= '\\' . $sRelativePath;
241
                }
242
243
                $this->addNamespace($sClassPath, ['separator' => $aOptions['separator']]);
244
245
                $sClassName = $sClassPath . '\\' . $xFile->getBasename('.php');
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...
246
                $aClassOptions = ['namespace' => $sNamespace, 'timestamp' => $xFile->getMTime()];
247
                $this->addClass($sClassName, $aClassOptions, $aOptions);
248
            }
249
        }
250
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
251
252
    /**
253
     * Check if a callable object is created
254
     *
255
     * @param string        $sClassName            The class name of the callable object
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...
256
     *
257
     * @return bool
258
     */
259
    public function hasCallableObject($sClassName)
260
    {
261
        return $this->di->has($sClassName);
262
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
263
264
    /**
265
     * Find a callable object by class name
266
     *
267
     * @param string        $sClassName            The class name of the callable object
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...
268
     *
269
     * @return CallableObject
270
     */
271
    public function getCallableObject($sClassName)
272
    {
273
        return $this->di->get($sClassName . '_CallableObject');
274
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
275
276
    /**
277
     * Create a new callable object
278
     *
279
     * @param string        $sClassName            The class name of the callable object
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...
280
     * @param array         $aOptions              The callable object options
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 14 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 9 found
Loading history...
281
     *
282
     * @return void
283
     */
284
    public function registerCallableObject($sClassName, array $aOptions)
285
    {
286
        // Make sure the registered class exists
287
        if(key_exists('include', $aOptions))
288
        {
289
            require_once($aOptions['include']);
290
        }
291
        if(!class_exists($sClassName))
292
        {
293
            return null;
294
        }
295
        // Register the callable object
296
        $this->di->registerCallableObject($sClassName, $aOptions);
297
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
298
}
299