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 ( 86dce3...98cf71 )
by Nur
02:40
created

Loader::loadHelper()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 18
nop 1
dl 0
loc 35
rs 8.4444
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\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...
19
use O2System\Psr\Loader\AutoloadInterface;
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 (class_exists('O2System', false)) {
83
            $this->addNamespace('O2System\Reactor', PATH_FRAMEWORK);
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
        // Append the custom modular PSR4 autoloader.
100
        spl_autoload_register([&$this, 'loadModuleClass'], true, false);
101
    }
102
103
    // ------------------------------------------------------------------------
104
105
    /**
106
     * Adds a base directory for a namespace prefix.
107
     *
108
     * @param string $namespace     The namespace prefix.
109
     * @param string $baseDirectory A base directory for class files in the
110
     *                              namespace.
111
     * @param bool   $prepend       If true, prepend the base directory to the stack
112
     *                              instead of appending it; this causes it to be searched first rather
113
     *                              than last.
114
     *
115
     * @return void
116
     */
117
    public function addNamespace($namespace, $baseDirectory, $prepend = false)
118
    {
119
        // normalize namespace prefix
120
        $namespace = trim($namespace, '\\') . '\\';
121
122
        if (empty($namespace) OR $namespace === '\\') {
123
            return;
124
        }
125
126
        // normalize the base directory with a trailing separator
127
        $baseDirectory = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $baseDirectory);
128
        $baseDirectory = rtrim($baseDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
129
130
        if (is_dir($baseDirectory)) {
131
            // initialize the namespace prefix array
132
            if (isset($this->namespaceDirs[ $namespace ]) === false) {
133
                $this->namespaceDirs[ $namespace ] = [];
134
            }
135
136
            // retain the base directory for the namespace prefix
137
            if ( ! in_array($baseDirectory, $this->namespaceDirs[ $namespace ])) {
138
                if ($prepend) {
139
                    array_unshift($this->namespaceDirs[ $namespace ], $baseDirectory);
140
                } else {
141
                    array_push($this->namespaceDirs[ $namespace ], $baseDirectory);
142
                }
143
            }
144
145
            $this->namespaceDirsMap[ $baseDirectory ] = $namespace;
146
147
            // Register Namespace Language
148
            language()->addFilePath($baseDirectory);
149
150
            // Register Namespace Output FilePath
151
            output()->addFilePath($baseDirectory);
152
153
            // Register Namespace Views FilePath
154
            if (o2system()->hasService('view')) {
0 ignored issues
show
Bug introduced by
The method hasService() does not exist on O2System\Reactor. ( Ignorable by Annotation )

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

154
            if (o2system()->/** @scrutinizer ignore-call */ hasService('view')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
155
                view()->addFilePath($baseDirectory);
0 ignored issues
show
Bug introduced by
The function view 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

155
                /** @scrutinizer ignore-call */ 
156
                view()->addFilePath($baseDirectory);
Loading history...
156
            }
157
158
            // Autoload Composer
159
            if (is_file($baseDirectory . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php')) {
160
                require($baseDirectory . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php');
161
            }
162
        }
163
    }
164
165
    // ------------------------------------------------------------------------
166
167
    /**
168
     * Loader::addPublicDir
169
     *
170
     * Adds a public directory for assets.
171
     *
172
     * @param string $publicDir
173
     */
174
    public function addPublicDir($publicDir, $offset = null)
175
    {
176
        // normalize the public directory with a trailing separator
177
        $publicDir = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $publicDir);
178
        $publicDir = PATH_PUBLIC . str_replace(PATH_PUBLIC, '', $publicDir);
179
        $publicDir = rtrim($publicDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
180
181
        if (is_dir($publicDir) and ! in_array($publicDir, $this->publicDirs)) {
182
            if (isset($offset)) {
183
                $this->publicDirs[ $offset ] = $publicDir;
184
            } else {
185
                $this->publicDirs[] = $publicDir;
186
            }
187
        }
188
    }
189
190
    // ------------------------------------------------------------------------
191
192
    /**
193
     * Loader::getPublicDirs
194
     *
195
     * Gets all public directories
196
     *
197
     * @param bool $reverse
198
     *
199
     * @return array
200
     */
201
    public function getPublicDirs($reverse = false)
202
    {
203
        return $reverse === true ? array_reverse($this->publicDirs) : $this->publicDirs;
204
    }
205
206
    // ------------------------------------------------------------------------
207
208
    /**
209
     * Get Namespace
210
     *
211
     * Get PSR4 Directory base on directory path
212
     *
213
     * @param string $dir
214
     *
215
     * @return string|bool
216
     */
217
    public function getDirNamespace($dir)
218
    {
219
        $dir = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $dir);
220
221
        $dir = realpath($dir);
222
        $dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
223
224
        if (array_key_exists($dir, $this->namespaceDirsMap)) {
225
            return $this->namespaceDirsMap[ $dir ];
226
        }
227
228
        return false;
229
    }
230
231
    // ------------------------------------------------------------------------
232
233
    /**
234
     * Get Namespace Class Directory
235
     *
236
     * @param string $className
237
     *
238
     * @return string|null
239
     */
240
    public function getClassNamespaceDirs($className)
241
    {
242
        $className = ltrim($className, '\\');
243
        $namespace = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $namespace is dead and can be removed.
Loading history...
244
245
        if ($lastNsPos = strripos($className, '\\')) {
246
            return $this->getNamespaceDirs(substr($className, 0, $lastNsPos));
247
        }
248
249
        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...
250
    }
251
252
    // ------------------------------------------------------------------------
253
254
    /**
255
     * Get Namespace Directory
256
     *
257
     * @param string $namespace
258
     *
259
     * @return string
260
     */
261
    public function getNamespaceDirs($namespace)
262
    {
263
        $namespace = trim($namespace, '\\') . '\\';
264
265
        if (array_key_exists($namespace, $this->namespaceDirs)) {
266
            return $this->namespaceDirs[ $namespace ];
267
        }
268
269
        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...
270
    }
271
272
    // ------------------------------------------------------------------------
273
274
    public function loadHelpers(array $helpers)
275
    {
276
        foreach ($helpers as $helper) {
277
            $this->loadHelper($helper);
278
        }
279
    }
280
281
    public function loadHelper($helper)
282
    {
283
        if (array_key_exists($helper, $this->loadedHelpers)) {
284
285
            return;
286
        }
287
288
        if ($this->requireFile($helper)) {
289
            $this->loadedHelpers[ pathinfo($helper, PATHINFO_FILENAME) ][] = $helper;
290
291
            return;
292
        }
293
294
        $helperDirectories = [
295
            PATH_KERNEL . 'Helpers' . DIRECTORY_SEPARATOR,
296
            PATH_FRAMEWORK . 'Helpers' . DIRECTORY_SEPARATOR,
297
            PATH_APP . 'Helpers' . DIRECTORY_SEPARATOR,
298
        ];
299
300
        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

300
        if (method_exists(/** @scrutinizer ignore-call */ modules(), 'current')) {
Loading history...
301
            array_push($helperDirectories, modules()->current()->getPath() . 'Helpers' . DIRECTORY_SEPARATOR);
302
        }
303
304
        if ( ! array_key_exists($helper, $this->loadedHelpers)) {
305
            $this->loadedHelpers[ $helper ] = [];
306
        }
307
308
        foreach ($helperDirectories as $helperDirectory) {
309
310
            $helperFilePath = $helperDirectory . studlycase($helper) . '.php';
311
312
            if (in_array($helperFilePath, $this->loadedHelpers[ $helper ])) {
313
                continue;
314
            } elseif ($this->requireFile($helperFilePath)) {
315
                $this->loadedHelpers[ $helper ][] = $helperFilePath;
316
            }
317
        }
318
    }
319
320
    /**
321
     * If a file exists, require it from the file system.
322
     *
323
     * @param string $file The file to require.
324
     *
325
     * @return bool True if the file exists, false if not.
326
     */
327
    public function requireFile($file)
328
    {
329
        if (is_file($file)) {
330
            require_once $file;
331
332
            return true;
333
        }
334
335
        return false;
336
    }
337
338
    // ------------------------------------------------------------------------
339
340
    public function loadModuleClass($class)
341
    {
342
        static $namespaceModules = [];
343
344
        // class namespace
345
        $namespaceParts = explode('\\', get_namespace($class));
346
        $namespaceParts = array_filter($namespaceParts);
347
348
        $namespace = reset($namespaceParts) . '\\';
349
350
        if (empty($namespaceModules) && modules() !== false) {
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

350
        if (empty($namespaceModules) && /** @scrutinizer ignore-call */ modules() !== false) {
Loading history...
351
            if (false !== ($modules = modules()->getRegistry())) {
352
                foreach ($modules as $module) {
353
                    if ($module instanceof Module) {
354
                        $namespaceModules[ $module->getNamespace() ] = $module;
355
                    }
356
                }
357
            }
358
        }
359
360
        if (isset($namespaceModules[ $namespace ])) {
361
            $module = $namespaceModules[ $namespace ];
362
            $this->addNamespace($module->getNamespace(), $module->getRealPath());
363
        }
364
365
        return $this->loadClass($class);
366
    }
367
368
    /**
369
     * Loads the class file for a given class name.
370
     *
371
     * @param string $class The fully-qualified class name.
372
     *
373
     * @return mixed The mapped file name on success, or boolean false on
374
     * failure.
375
     */
376
    public function loadClass($class)
377
    {
378
        // the current namespace prefix
379
        $namespace = $class;
380
381
        // work backwards through the namespace names of the fully-qualified
382
        // class name to find a mapped file name
383
        while (false !== $pos = strrpos($namespace, '\\')) {
384
            // retain the trailing namespace separator in the prefix
385
            $namespace = substr($class, 0, $pos + 1);
386
387
            // the rest is the relative class name
388
            $relativeClass = substr($class, $pos + 1);
389
390
            // try to load a mapped file for the prefix and relative class
391
            $mappedFile = $this->loadMappedFile($namespace, $relativeClass);
392
            if ($mappedFile) {
393
                return $mappedFile;
394
            }
395
396
            // remove the trailing namespace separator for the next iteration
397
            // of strrpos()
398
            $namespace = rtrim($namespace, '\\');
399
        }
400
401
        // never found a mapped file
402
        return false;
403
    }
404
405
    // ------------------------------------------------------------------------
406
407
    /**
408
     * Load the mapped file for a namespace prefix and relative class.
409
     *
410
     * @param string $namespace     The namespace prefix.
411
     * @param string $relativeClass The relative class name.
412
     *
413
     * @return mixed Boolean false if no mapped file can be loaded, or the
414
     * name of the mapped file that was loaded.
415
     */
416
    public function loadMappedFile($namespace, $relativeClass)
417
    {
418
        // are there any base directories for this namespace prefix?
419
        if (isset($this->namespaceDirs[ $namespace ]) === false) {
420
            return false;
421
        }
422
423
        // look through base directories for this namespace prefix
424
        foreach ($this->namespaceDirs[ $namespace ] as $namespaceDirectory) {
425
426
            // replace the namespace prefix with the base directory,
427
            // replace namespace separators with directory separators
428
            // in the relative class name, append with .php
429
            $file = $namespaceDirectory
430
                . str_replace('\\', '/', $relativeClass)
431
                . '.php';
432
433
            // if the mapped file exists, require it
434
            if ($this->requireFile($file)) {
435
                // yes, we're done
436
                return $file;
437
            }
438
        }
439
440
        // never found it
441
        return false;
442
    }
443
444
    // ------------------------------------------------------------------------
445
446
    public function view($file, array $vars = [], $return = false)
447
    {
448
        return view($file, $vars, $return);
0 ignored issues
show
Bug introduced by
The function view 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

448
        return /** @scrutinizer ignore-call */ view($file, $vars, $return);
Loading history...
449
    }
450
451
    // ------------------------------------------------------------------------
452
453
    public function page($file, array $vars = [], $return = false)
454
    {
455
        return view()->page($file, $vars, $return);
0 ignored issues
show
Bug introduced by
The function view 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

455
        return /** @scrutinizer ignore-call */ view()->page($file, $vars, $return);
Loading history...
456
    }
457
}