Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
81.08% covered (warning)
81.08%
30 / 37
50.00% covered (danger)
50.00%
4 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Autoloader
83.33% covered (warning)
83.33%
30 / 36
50.00% covered (danger)
50.00%
4 / 8
23.04
0.00% covered (danger)
0.00%
0 / 1
 __construct
n/a
0 / 0
n/a
0 / 0
1
 addPath
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addClassMap
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 inPaths
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 inClassMap
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 findPaths
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 defaultAutoloader
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
6
 exists
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 invalidate
57.14% covered (warning)
57.14%
4 / 7
0.00% covered (danger)
0.00%
0 / 1
5.26
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS;
16
17\spl_autoload_register('\phpOMS\Autoloader::defaultAutoloader');
18
19/**
20 * Autoloader class.
21 *
22 * @package phpOMS
23 * @license OMS License 2.0
24 * @link    https://jingga.app
25 * @since   1.0.0
26 */
27final class Autoloader
28{
29    /**
30     * Use class map before paths
31     *
32     * @var bool
33     * @since 1.0.0
34     */
35    public static bool $useClassMap = true;
36
37    /**
38     * Base paths for autoloading
39     *
40     * @var string[]
41     * @since 1.0.0
42     */
43    private static $paths = [
44        __DIR__ . '/../',
45    ];
46
47    /**
48     * Base paths for autoloading
49     *
50     * @var string[]
51     * @since 1.0.0
52     */
53    private static $classmap = [
54        'phpOMS'  => __DIR__ . '/../',
55        'Modules' => __DIR__ . '/../',
56        'Models'  => __DIR__ . '/../',
57    ];
58
59    /**
60     * Constructor.
61     *
62     * @since 1.0.0
63     * @codeCoverageIgnore
64     */
65    private function __construct()
66    {
67    }
68
69    /**
70     * Add base path for autoloading
71     *
72     * @param string $path Absolute base path with / at the end
73     *
74     * @return void
75     *
76     * @since 1.0.0
77     */
78    public static function addPath(string $path) : void
79    {
80        self::$paths[] = \rtrim($path, '/\\') . '/';
81    }
82
83    /**
84     * Add base path for autoloading
85     *
86     * @param string $map  Namespace start
87     * @param string $path Absolute base path with / at the end
88     *
89     * @return void
90     *
91     * @since 1.0.0
92     */
93    public static function addClassMap(string $map, string $path) : void
94    {
95        self::$classmap[$map] = \rtrim($path, '/\\') . '/';
96    }
97
98    /**
99     * Check if a path is already in the path list
100     *
101     * @param string $path Absolute base path with / at the end
102     *
103     * @return bool
104     *
105     * @since 1.0.0
106     */
107    public static function inPaths(string $path) : bool
108    {
109        return \in_array(\rtrim($path, '/\\') . '/', self::$paths);
110    }
111
112    /**
113     * Check if a namespace map is already in the classpath list
114     *
115     * @param string $map Namespace start
116     *
117     * @return bool
118     *
119     * @since 1.0.0
120     */
121    public static function inClassMap(string $map) : bool
122    {
123        return isset(self::$classmap[$map]);
124    }
125
126    /**
127     * Find include paths for class
128     *
129     * @param string $class Class name
130     *
131     * @return array
132     *
133     * @since 1.0.0
134     */
135    public static function findPaths(string $class) : array
136    {
137        $found = [];
138        $class = \ltrim($class, '\\');
139        $class = \strtr($class, '_\\', '//');
140
141        foreach (self::$paths as $path) {
142            if (\is_file($file = $path . $class . '.php')) {
143                $found[] = $file;
144            }
145        }
146
147        return $found;
148    }
149
150    /**
151     * Loading classes by namespace + class name.
152     *
153     * @param string $class Class name
154     *
155     * @example Autoloader::defaultAutoloader('\phpOMS\Autoloader') // void
156     *
157     * @return void
158     *
159     * @since 1.0.0
160     */
161    public static function defaultAutoloader(string $class) : void
162    {
163        $class = \ltrim($class, '\\');
164        $class = \strtr($class, '_\\', '//');
165
166        if (self::$useClassMap) {
167            $nspacePos = \strpos($class, '/');
168            $subclass  = $nspacePos === false ? '' : \substr($class, 0, $nspacePos);
169
170            if (isset(self::$classmap[$subclass])) {
171                include_once self::$classmap[$subclass] . $class . '.php';
172
173                return;
174            }
175
176            /*
177            if (!isset($valid[$subclass])) {
178                foreach (self::$classmap as $map => $path) {
179                    if (\str_starts_with($class, $map)) {
180                        include_once $path . $class . '.php';
181
182                        return;
183                    }
184                }
185            }
186            */
187        }
188
189        foreach (self::$paths as $path) {
190            if (\is_file($file = $path . $class . '.php')) {
191                include_once $file;
192
193                return;
194            }
195        }
196    }
197
198    /**
199     * Check if class exists.
200     *
201     * @param string $class Class path
202     *
203     * @example Autoloader::exists('\phpOMS\Autoloader') // true
204     *
205     * @return bool Returns true if the namespace/class exists, otherwise false
206     *
207     * @since 1.0.0
208     */
209    public static function exists(string $class) : bool
210    {
211        $class = \ltrim($class, '\\');
212        $class = \strtr($class, '_\\', '//');
213
214        foreach (self::$paths as $path) {
215            if (\is_file($path . $class . '.php')) {
216                return true;
217            }
218        }
219
220        return false;
221    }
222
223    /**
224     * Invalidate a already loaded file
225     *
226     * IMPORTANT: This does not reload an already loaded file, this is not possible.
227     *
228     * @param string $class Class to invalidate
229     *
230     * @return bool
231     *
232     * @since 1.0.0
233     */
234    public static function invalidate(string $class) : bool
235    {
236        if (!\extension_loaded('zend opcache')
237            || !\opcache_is_script_cached($class)
238            || \opcache_get_status() === false
239        ) {
240            return false;
241        }
242
243        \opcache_invalidate($class);
244        \opcache_compile_file($class);
245
246        return true;
247    }
248}