GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Loader   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 331
Duplicated Lines 0 %

Importance

Changes 4
Bugs 2 Features 1
Metric Value
eloc 85
c 4
b 2
f 1
dl 0
loc 331
rs 9.6
wmc 35

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassNamespaceDirs() 0 10 2
A __construct() 0 9 2
A getDirNamespace() 0 12 2
B loadHelper() 0 31 7
A getNamespaceDirs() 0 9 2
A loadClass() 0 27 3
A register() 0 4 1
A loadHelpers() 0 4 2
A requireFile() 0 9 2
A loadMappedFile() 0 26 4
B addNamespace() 0 39 8
1
<?php
2
/**
3
 * This file is part of the O2System PHP Framework package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author         Steeve Andrian Salim
9
 * @copyright      Copyright (c) Steeve Andrian Salim
10
 */
11
12
// ------------------------------------------------------------------------
13
14
namespace O2System\Reactor\Services;
15
16
// ------------------------------------------------------------------------
17
18
use O2System\Psr\Loader\AutoloadInterface;
19
use O2System\Reactor\DataStructures\Module;
0 ignored issues
show
Bug introduced by
The type O2System\Reactor\DataStructures\Module 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...
20
21
/**
22
 * O2System Loader
23
 *
24
 * Class and files loader based on PSR-4 Autoloader
25
 *
26
 * @see     http://www.php-fig.org/psr/psr-4/
27
 *
28
 * @package O2System\Kernel
29
 */
30
class Loader implements AutoloadInterface
31
{
32
    /**
33
     * Loader::$publicDirs
34
     *
35
     * Loader Public Directories.
36
     *
37
     * @var array
38
     */
39
    protected $publicDirs = [
40
        PATH_PUBLIC,
41
    ];
42
43
    /**
44
     * Loader::$namespaceDirs
45
     *
46
     * Loader Namespaces Directories.
47
     *
48
     * @var array
49
     */
50
    protected $namespaceDirs = [];
51
52
    /**
53
     * Loader::$namespaceDirsMap
54
     *
55
     * Loader Namespaces Directories Maps.
56
     *
57
     * @var array
58
     */
59
    protected $namespaceDirsMap = [];
60
61
    /**
62
     * Loader::$loadedHelpers
63
     *
64
     * Loader Loaded Helpers Registry.
65
     *
66
     * @var array
67
     */
68
    protected $loadedHelpers = [];
69
70
    // ------------------------------------------------------------------------
71
72
    /**
73
     * Loader::__construct
74
     */
75
    public function __construct()
76
    {
77
        $this->register();
78
79
        // Add Kernel Namespace
80
        $this->addNamespace('O2System\Kernel', PATH_KERNEL);
81
82
        if (defined('PATH_REACTOR')) {
83
            $this->addNamespace('O2System\Reactor', PATH_REACTOR);
84
        }
85
    }
86
87
    // ------------------------------------------------------------------------
88
89
    /**
90
     * Register loader with SPL autoloader stack.
91
     *
92
     * @return void
93
     */
94
    public function register()
95
    {
96
        // Prepend the PSR4 autoloader for maximum performance.
97
        spl_autoload_register([&$this, 'loadClass'], true, true);
98
    }
99
100
    // ------------------------------------------------------------------------
101
102
    /**
103
     * Adds a base directory for a namespace prefix.
104
     *
105
     * @param string $namespace     The namespace prefix.
106
     * @param string $baseDirectory A base directory for class files in the
107
     *                              namespace.
108
     * @param bool   $prepend       If true, prepend the base directory to the stack
109
     *                              instead of appending it; this causes it to be searched first rather
110
     *                              than last.
111
     *
112
     * @return void
113
     */
114
    public function addNamespace($namespace, $baseDirectory, $prepend = false)
115
    {
116
        // normalize namespace prefix
117
        $namespace = trim($namespace, '\\') . '\\';
118
119
        if (empty($namespace) OR $namespace === '\\') {
120
            return;
121
        }
122
123
        // normalize the base directory with a trailing separator
124
        $baseDirectory = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $baseDirectory);
125
        $baseDirectory = rtrim($baseDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
126
127
        if (is_dir($baseDirectory)) {
128
            // initialize the namespace prefix array
129
            if (isset($this->namespaceDirs[ $namespace ]) === false) {
130
                $this->namespaceDirs[ $namespace ] = [];
131
            }
132
133
            // retain the base directory for the namespace prefix
134
            if ( ! in_array($baseDirectory, $this->namespaceDirs[ $namespace ])) {
135
                if ($prepend) {
136
                    array_unshift($this->namespaceDirs[ $namespace ], $baseDirectory);
137
                } else {
138
                    array_push($this->namespaceDirs[ $namespace ], $baseDirectory);
139
                }
140
            }
141
142
            $this->namespaceDirsMap[ $baseDirectory ] = $namespace;
143
144
            // Register Namespace Language
145
            language()->addFilePath($baseDirectory);
146
147
            // Register Namespace Output FilePath
148
            output()->addFilePath($baseDirectory);
149
150
            // Autoload Composer
151
            if (is_file($baseDirectory . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) {
152
                require($baseDirectory . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php');
153
            }
154
        }
155
    }
156
157
    // ------------------------------------------------------------------------
158
159
    /**
160
     * Get Namespace
161
     *
162
     * Get PSR4 Directory base on directory path
163
     *
164
     * @param string $dir
165
     *
166
     * @return string|bool
167
     */
168
    public function getDirNamespace($dir)
169
    {
170
        $dir = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $dir);
171
172
        $dir = realpath($dir);
173
        $dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
174
175
        if (array_key_exists($dir, $this->namespaceDirsMap)) {
176
            return $this->namespaceDirsMap[ $dir ];
177
        }
178
179
        return false;
180
    }
181
182
    // ------------------------------------------------------------------------
183
184
    /**
185
     * Get Namespace Class Directory
186
     *
187
     * @param string $className
188
     *
189
     * @return string|null
190
     */
191
    public function getClassNamespaceDirs($className)
192
    {
193
        $className = ltrim($className, '\\');
194
        $namespace = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $namespace is dead and can be removed.
Loading history...
195
196
        if ($lastNsPos = strripos($className, '\\')) {
197
            return $this->getNamespaceDirs(substr($className, 0, $lastNsPos));
198
        }
199
200
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type null|string.
Loading history...
201
    }
202
203
    // ------------------------------------------------------------------------
204
205
    /**
206
     * Get Namespace Directory
207
     *
208
     * @param string $namespace
209
     *
210
     * @return string
211
     */
212
    public function getNamespaceDirs($namespace)
213
    {
214
        $namespace = trim($namespace, '\\') . '\\';
215
216
        if (array_key_exists($namespace, $this->namespaceDirs)) {
217
            return $this->namespaceDirs[ $namespace ];
218
        }
219
220
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
221
    }
222
223
    // ------------------------------------------------------------------------
224
225
    public function loadHelpers(array $helpers)
226
    {
227
        foreach ($helpers as $helper) {
228
            $this->loadHelper($helper);
229
        }
230
    }
231
232
    public function loadHelper($helper)
233
    {
234
        if (array_key_exists($helper, $this->loadedHelpers)) {
235
236
            return;
237
        }
238
239
        if ($this->requireFile($helper)) {
240
            $this->loadedHelpers[ pathinfo($helper, PATHINFO_FILENAME) ][] = $helper;
241
242
            return;
243
        }
244
245
        $helperDirectories = [
246
            PATH_KERNEL . 'Helpers' . DIRECTORY_SEPARATOR,
247
            PATH_FRAMEWORK . 'Helpers' . DIRECTORY_SEPARATOR,
0 ignored issues
show
Bug introduced by
The constant O2System\Reactor\Services\PATH_FRAMEWORK was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
248
            PATH_APP . 'Helpers' . DIRECTORY_SEPARATOR,
249
        ];
250
        
251
        if ( ! array_key_exists($helper, $this->loadedHelpers)) {
252
            $this->loadedHelpers[ $helper ] = [];
253
        }
254
255
        foreach ($helperDirectories as $helperDirectory) {
256
257
            $helperFilePath = $helperDirectory . studlycase($helper) . '.php';
258
259
            if (in_array($helperFilePath, $this->loadedHelpers[ $helper ])) {
260
                continue;
261
            } elseif ($this->requireFile($helperFilePath)) {
262
                $this->loadedHelpers[ $helper ][] = $helperFilePath;
263
            }
264
        }
265
    }
266
267
    /**
268
     * If a file exists, require it from the file system.
269
     *
270
     * @param string $file The file to require.
271
     *
272
     * @return bool True if the file exists, false if not.
273
     */
274
    public function requireFile($file)
275
    {
276
        if (is_file($file)) {
277
            require_once $file;
278
279
            return true;
280
        }
281
282
        return false;
283
    }
284
285
    // ------------------------------------------------------------------------
286
287
    /**
288
     * Loads the class file for a given class name.
289
     *
290
     * @param string $class The fully-qualified class name.
291
     *
292
     * @return mixed The mapped file name on success, or boolean false on
293
     * failure.
294
     */
295
    public function loadClass($class)
296
    {
297
        // the current namespace prefix
298
        $namespace = $class;
299
300
        // work backwards through the namespace names of the fully-qualified
301
        // class name to find a mapped file name
302
        while (false !== $pos = strrpos($namespace, '\\')) {
303
            // retain the trailing namespace separator in the prefix
304
            $namespace = substr($class, 0, $pos + 1);
305
306
            // the rest is the relative class name
307
            $relativeClass = substr($class, $pos + 1);
308
309
            // try to load a mapped file for the prefix and relative class
310
            $mappedFile = $this->loadMappedFile($namespace, $relativeClass);
311
            if ($mappedFile) {
312
                return $mappedFile;
313
            }
314
315
            // remove the trailing namespace separator for the next iteration
316
            // of strrpos()
317
            $namespace = rtrim($namespace, '\\');
318
        }
319
320
        // never found a mapped file
321
        return false;
322
    }
323
324
    // ------------------------------------------------------------------------
325
326
    /**
327
     * Load the mapped file for a namespace prefix and relative class.
328
     *
329
     * @param string $namespace     The namespace prefix.
330
     * @param string $relativeClass The relative class name.
331
     *
332
     * @return mixed Boolean false if no mapped file can be loaded, or the
333
     * name of the mapped file that was loaded.
334
     */
335
    public function loadMappedFile($namespace, $relativeClass)
336
    {
337
        // are there any base directories for this namespace prefix?
338
        if (isset($this->namespaceDirs[ $namespace ]) === false) {
339
            return false;
340
        }
341
342
        // look through base directories for this namespace prefix
343
        foreach ($this->namespaceDirs[ $namespace ] as $namespaceDirectory) {
344
345
            // replace the namespace prefix with the base directory,
346
            // replace namespace separators with directory separators
347
            // in the relative class name, append with .php
348
            $file = $namespaceDirectory
349
                . str_replace('\\', '/', $relativeClass)
350
                . '.php';
351
352
            // if the mapped file exists, require it
353
            if ($this->requireFile($file)) {
354
                // yes, we're done
355
                return $file;
356
            }
357
        }
358
359
        // never found it
360
        return false;
361
    }
362
}