OpenAPI Generator. Better DocBlock parsing [WIP]
[dokuwiki.git] / inc / load.php
blob4d40609f5500906372a5e02d3d9f956d6bcab08e
1 <?php
3 /**
4 * Load all internal libraries and setup class autoloader
6 * @author Andreas Gohr <andi@splitbrain.org>
7 */
9 namespace dokuwiki;
11 use dokuwiki\Extension\PluginController;
13 return new class {
14 /** @var string[] Common libraries that are always loaded */
15 protected array $commonLibs = [
16 'defines.php',
17 'actions.php',
18 'changelog.php',
19 'common.php',
20 'confutils.php',
21 'pluginutils.php',
22 'form.php',
23 'fulltext.php',
24 'html.php',
25 'httputils.php',
26 'indexer.php',
27 'infoutils.php',
28 'io.php',
29 'mail.php',
30 'media.php',
31 'pageutils.php',
32 'parserutils.php',
33 'search.php',
34 'template.php',
35 'toolbar.php',
36 'utf8.php',
37 'auth.php',
38 'compatibility.php',
39 'deprecated.php',
40 'legacy.php',
43 /** @var string[] Classname to file mappings */
44 protected array $fixedClassNames = [
45 'Diff' => 'DifferenceEngine.php',
46 'UnifiedDiffFormatter' => 'DifferenceEngine.php',
47 'TableDiffFormatter' => 'DifferenceEngine.php',
48 'cache' => 'cache.php',
49 'cache_parser' => 'cache.php',
50 'cache_instructions' => 'cache.php',
51 'cache_renderer' => 'cache.php',
52 'Input' => 'Input.class.php',
53 'JpegMeta' => 'JpegMeta.php',
54 'SimplePie' => 'SimplePie.php',
55 'FeedParser' => 'FeedParser.php',
56 'SafeFN' => 'SafeFN.class.php',
57 'Mailer' => 'Mailer.class.php',
58 'Doku_Handler' => 'parser/handler.php',
59 'Doku_Renderer' => 'parser/renderer.php',
60 'Doku_Renderer_xhtml' => 'parser/xhtml.php',
61 'Doku_Renderer_code' => 'parser/code.php',
62 'Doku_Renderer_xhtmlsummary' => 'parser/xhtmlsummary.php',
63 'Doku_Renderer_metadata' => 'parser/metadata.php'
66 /**
67 * Load common libs and register autoloader
69 public function __construct()
71 require_once(DOKU_INC . 'vendor/autoload.php');
72 spl_autoload_register([$this, 'autoload']);
73 $this->loadCommonLibs();
76 /**
77 * require all the common libraries
79 * @return true
81 public function loadCommonLibs()
83 foreach ($this->commonLibs as $lib) {
84 require_once(DOKU_INC . 'inc/' . $lib);
86 return true;
89 /**
90 * spl_autoload_register callback
92 * @param string $className
93 * @return bool
95 public function autoload($className)
97 // namespace to directory conversion
98 $classPath = str_replace('\\', '/', $className);
100 return $this->autoloadFixedClass($className)
101 || $this->autoloadTestMockClass($classPath)
102 || $this->autoloadTestClass($classPath)
103 || $this->autoloadPluginClass($classPath)
104 || $this->autoloadTemplateClass($classPath)
105 || $this->autoloadCoreClass($classPath)
106 || $this->autoloadNamedPluginClass($className);
110 * Check if the class is one of the fixed names
112 * @param string $className
113 * @return bool true if the class was loaded, false otherwise
115 protected function autoloadFixedClass($className)
117 if (isset($this->fixedClassNames[$className])) {
118 require($this->fixedClassNames[$className]);
119 return true;
121 return false;
125 * Check if the class is a test mock class
127 * @param string $classPath The class name using forward slashes as namespace separators
128 * @return bool true if the class was loaded, false otherwise
130 protected function autoloadTestMockClass($classPath)
132 if ($this->prefixStrip($classPath, 'dokuwiki/test/mock/')) {
133 $file = DOKU_INC . '_test/mock/' . $classPath . '.php';
134 if (file_exists($file)) {
135 require $file;
136 return true;
139 return false;
143 * Check if the class is a test mock class
145 * @param string $classPath The class name using forward slashes as namespace separators
146 * @return bool true if the class was loaded, false otherwise
148 protected function autoloadTestClass($classPath)
150 if ($this->prefixStrip($classPath, 'dokuwiki/test/')) {
151 $file = DOKU_INC . '_test/tests/' . $classPath . '.php';
152 if (file_exists($file)) {
153 require $file;
154 return true;
157 return false;
161 * Check if the class is a namespaced plugin class
163 * @param string $classPath The class name using forward slashes as namespace separators
164 * @return bool true if the class was loaded, false otherwise
166 protected function autoloadPluginClass($classPath)
168 global $plugin_controller;
170 if ($this->prefixStrip($classPath, 'dokuwiki/plugin/')) {
171 $classPath = str_replace('/test/', '/_test/', $classPath); // no underscore in test namespace
172 $file = DOKU_PLUGIN . $classPath . '.php';
173 if (file_exists($file)) {
174 $plugin = substr($classPath, 0, strpos($classPath, '/'));
175 // don't load disabled plugin classes (only if plugin controller is available)
176 if (!defined('DOKU_UNITTEST') && $plugin_controller && plugin_isdisabled($plugin)) return false;
178 try {
179 require $file;
180 } catch (\Throwable $e) {
181 ErrorHandler::showExceptionMsg($e, "Error loading plugin $plugin");
183 return true;
186 return false;
190 * Check if the class is a namespaced template class
192 * @param string $classPath The class name using forward slashes as namespace separators
193 * @return bool true if the class was loaded, false otherwise
195 protected function autoloadTemplateClass($classPath)
197 // template namespace
198 if ($this->prefixStrip($classPath, 'dokuwiki/template/')) {
199 $classPath = str_replace('/test/', '/_test/', $classPath); // no underscore in test namespace
200 $file = DOKU_INC . 'lib/tpl/' . $classPath . '.php';
201 if (file_exists($file)) {
202 $template = substr($classPath, 0, strpos($classPath, '/'));
204 try {
205 require $file;
206 } catch (\Throwable $e) {
207 ErrorHandler::showExceptionMsg($e, "Error loading template $template");
209 return true;
212 return false;
216 * Check if the class is a namespaced DokuWiki core class
218 * @param string $classPath The class name using forward slashes as namespace separators
219 * @return bool true if the class was loaded, false otherwise
221 protected function autoloadCoreClass($classPath)
223 if ($this->prefixStrip($classPath, 'dokuwiki/')) {
224 $file = DOKU_INC . 'inc/' . $classPath . '.php';
225 if (file_exists($file)) {
226 require $file;
227 return true;
230 return false;
234 * Check if the class is a un-namespaced plugin class following our naming scheme
236 * @param string $className
237 * @return bool true if the class was loaded, false otherwise
239 protected function autoloadNamedPluginClass($className)
241 global $plugin_controller;
243 if (
244 preg_match(
245 '/^(' . implode('|', PluginController::PLUGIN_TYPES) . ')_plugin_(' .
246 DOKU_PLUGIN_NAME_REGEX .
247 ')(?:_([^_]+))?$/',
248 $className,
252 $c = ((count($m) === 4) ? "/{$m[3]}" : '');
253 $plg = DOKU_PLUGIN . "{$m[2]}/{$m[1]}$c.php";
254 if (file_exists($plg)) {
255 // don't load disabled plugin classes (only if plugin controller is available)
256 if (!defined('DOKU_UNITTEST') && $plugin_controller && plugin_isdisabled($m[2])) return false;
257 try {
258 require $plg;
259 } catch (\Throwable $e) {
260 ErrorHandler::showExceptionMsg($e, "Error loading plugin {$m[2]}");
263 return true;
265 return false;
269 * Check if the given string starts with the given prefix and strip it
271 * @param string $string
272 * @param string $prefix
273 * @return bool true if the prefix was found and stripped, false otherwise
275 protected function prefixStrip(&$string, $prefix)
277 if (str_starts_with($string, $prefix)) {
278 $string = substr($string, strlen($prefix));
279 return true;
281 return false;