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.
Passed
Push — master ( e22738...bc2961 )
by
unknown
01:53
created

Loader::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
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 (method_exists(modules(), 'current')) {
0 ignored issues
show
Bug introduced by
The function modules was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

251
        if (method_exists(/** @scrutinizer ignore-call */ modules(), 'current')) {
Loading history...
252
            array_push($helperDirectories, modules()->current()->getPath() . 'Helpers' . DIRECTORY_SEPARATOR);
253
        }
254
255
        if ( ! array_key_exists($helper, $this->loadedHelpers)) {
256
            $this->loadedHelpers[ $helper ] = [];
257
        }
258
259
        foreach ($helperDirectories as $helperDirectory) {
260
261
            $helperFilePath = $helperDirectory . studlycase($helper) . '.php';
262
263
            if (in_array($helperFilePath, $this->loadedHelpers[ $helper ])) {
264
                continue;
265
            } elseif ($this->requireFile($helperFilePath)) {
266
                $this->loadedHelpers[ $helper ][] = $helperFilePath;
267
            }
268
        }
269
    }
270
271
    /**
272
     * If a file exists, require it from the file system.
273
     *
274
     * @param string $file The file to require.
275
     *
276
     * @return bool True if the file exists, false if not.
277
     */
278
    public function requireFile($file)
279
    {
280
        if (is_file($file)) {
281
            require_once $file;
282
283
            return true;
284
        }
285
286
        return false;
287
    }
288
289
    // ------------------------------------------------------------------------
290
291
    /**
292
     * Loads the class file for a given class name.
293
     *
294
     * @param string $class The fully-qualified class name.
295
     *
296
     * @return mixed The mapped file name on success, or boolean false on
297
     * failure.
298
     */
299
    public function loadClass($class)
300
    {
301
        // the current namespace prefix
302
        $namespace = $class;
303
304
        // work backwards through the namespace names of the fully-qualified
305
        // class name to find a mapped file name
306
        while (false !== $pos = strrpos($namespace, '\\')) {
307
            // retain the trailing namespace separator in the prefix
308
            $namespace = substr($class, 0, $pos + 1);
309
310
            // the rest is the relative class name
311
            $relativeClass = substr($class, $pos + 1);
312
313
            // try to load a mapped file for the prefix and relative class
314
            $mappedFile = $this->loadMappedFile($namespace, $relativeClass);
315
            if ($mappedFile) {
316
                return $mappedFile;
317
            }
318
319
            // remove the trailing namespace separator for the next iteration
320
            // of strrpos()
321
            $namespace = rtrim($namespace, '\\');
322
        }
323
324
        // never found a mapped file
325
        return false;
326
    }
327
328
    // ------------------------------------------------------------------------
329
330
    /**
331
     * Load the mapped file for a namespace prefix and relative class.
332
     *
333
     * @param string $namespace     The namespace prefix.
334
     * @param string $relativeClass The relative class name.
335
     *
336
     * @return mixed Boolean false if no mapped file can be loaded, or the
337
     * name of the mapped file that was loaded.
338
     */
339
    public function loadMappedFile($namespace, $relativeClass)
340
    {
341
        // are there any base directories for this namespace prefix?
342
        if (isset($this->namespaceDirs[ $namespace ]) === false) {
343
            return false;
344
        }
345
346
        // look through base directories for this namespace prefix
347
        foreach ($this->namespaceDirs[ $namespace ] as $namespaceDirectory) {
348
349
            // replace the namespace prefix with the base directory,
350
            // replace namespace separators with directory separators
351
            // in the relative class name, append with .php
352
            $file = $namespaceDirectory
353
                . str_replace('\\', '/', $relativeClass)
354
                . '.php';
355
356
            // if the mapped file exists, require it
357
            if ($this->requireFile($file)) {
358
                // yes, we're done
359
                return $file;
360
            }
361
        }
362
363
        // never found it
364
        return false;
365
    }
366
}