284 lines
8.8 KiB
PHP
284 lines
8.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Load all internal libraries and setup class autoloader
|
|
*
|
|
* @author Andreas Gohr <andi@splitbrain.org>
|
|
*/
|
|
|
|
namespace dokuwiki;
|
|
|
|
use dokuwiki\Extension\PluginController;
|
|
|
|
return new class {
|
|
/** @var string[] Common libraries that are always loaded */
|
|
protected array $commonLibs = [
|
|
'defines.php',
|
|
'actions.php',
|
|
'changelog.php',
|
|
'common.php',
|
|
'confutils.php',
|
|
'pluginutils.php',
|
|
'form.php',
|
|
'fulltext.php',
|
|
'html.php',
|
|
'httputils.php',
|
|
'indexer.php',
|
|
'infoutils.php',
|
|
'io.php',
|
|
'mail.php',
|
|
'media.php',
|
|
'pageutils.php',
|
|
'parserutils.php',
|
|
'search.php',
|
|
'template.php',
|
|
'toolbar.php',
|
|
'utf8.php',
|
|
'auth.php',
|
|
'compatibility.php',
|
|
'deprecated.php',
|
|
'legacy.php',
|
|
];
|
|
|
|
/** @var string[] Classname to file mappings */
|
|
protected array $fixedClassNames = [
|
|
'Diff' => 'DifferenceEngine.php',
|
|
'UnifiedDiffFormatter' => 'DifferenceEngine.php',
|
|
'TableDiffFormatter' => 'DifferenceEngine.php',
|
|
'cache' => 'cache.php',
|
|
'cache_parser' => 'cache.php',
|
|
'cache_instructions' => 'cache.php',
|
|
'cache_renderer' => 'cache.php',
|
|
'Input' => 'Input.class.php',
|
|
'JpegMeta' => 'JpegMeta.php',
|
|
'SimplePie' => 'SimplePie.php',
|
|
'FeedParser' => 'FeedParser.php',
|
|
'SafeFN' => 'SafeFN.class.php',
|
|
'Mailer' => 'Mailer.class.php',
|
|
'Doku_Handler' => 'parser/handler.php',
|
|
'Doku_Renderer' => 'parser/renderer.php',
|
|
'Doku_Renderer_xhtml' => 'parser/xhtml.php',
|
|
'Doku_Renderer_code' => 'parser/code.php',
|
|
'Doku_Renderer_xhtmlsummary' => 'parser/xhtmlsummary.php',
|
|
'Doku_Renderer_metadata' => 'parser/metadata.php'
|
|
];
|
|
|
|
/**
|
|
* Load common libs and register autoloader
|
|
*/
|
|
public function __construct()
|
|
{
|
|
require_once(DOKU_INC . 'vendor/autoload.php');
|
|
spl_autoload_register([$this, 'autoload']);
|
|
$this->loadCommonLibs();
|
|
}
|
|
|
|
/**
|
|
* require all the common libraries
|
|
*
|
|
* @return true
|
|
*/
|
|
public function loadCommonLibs()
|
|
{
|
|
foreach ($this->commonLibs as $lib) {
|
|
require_once(DOKU_INC . 'inc/' . $lib);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* spl_autoload_register callback
|
|
*
|
|
* @param string $className
|
|
* @return bool
|
|
*/
|
|
public function autoload($className)
|
|
{
|
|
// namespace to directory conversion
|
|
$classPath = str_replace('\\', '/', $className);
|
|
|
|
return $this->autoloadFixedClass($className)
|
|
|| $this->autoloadTestMockClass($classPath)
|
|
|| $this->autoloadTestClass($classPath)
|
|
|| $this->autoloadPluginClass($classPath)
|
|
|| $this->autoloadTemplateClass($classPath)
|
|
|| $this->autoloadCoreClass($classPath)
|
|
|| $this->autoloadNamedPluginClass($className);
|
|
}
|
|
|
|
/**
|
|
* Check if the class is one of the fixed names
|
|
*
|
|
* @param string $className
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadFixedClass($className)
|
|
{
|
|
if (isset($this->fixedClassNames[$className])) {
|
|
require($this->fixedClassNames[$className]);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a test mock class
|
|
*
|
|
* @param string $classPath The class name using forward slashes as namespace separators
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadTestMockClass($classPath)
|
|
{
|
|
if ($this->prefixStrip($classPath, 'dokuwiki/test/mock/')) {
|
|
$file = DOKU_INC . '_test/mock/' . $classPath . '.php';
|
|
if (file_exists($file)) {
|
|
require $file;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a test mock class
|
|
*
|
|
* @param string $classPath The class name using forward slashes as namespace separators
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadTestClass($classPath)
|
|
{
|
|
if ($this->prefixStrip($classPath, 'dokuwiki/test/')) {
|
|
$file = DOKU_INC . '_test/tests/' . $classPath . '.php';
|
|
if (file_exists($file)) {
|
|
require $file;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a namespaced plugin class
|
|
*
|
|
* @param string $classPath The class name using forward slashes as namespace separators
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadPluginClass($classPath)
|
|
{
|
|
global $plugin_controller;
|
|
|
|
if ($this->prefixStrip($classPath, 'dokuwiki/plugin/')) {
|
|
$classPath = str_replace('/test/', '/_test/', $classPath); // no underscore in test namespace
|
|
$file = DOKU_PLUGIN . $classPath . '.php';
|
|
if (file_exists($file)) {
|
|
$plugin = substr($classPath, 0, strpos($classPath, '/'));
|
|
// don't load disabled plugin classes (only if plugin controller is available)
|
|
if (!defined('DOKU_UNITTEST') && $plugin_controller && plugin_isdisabled($plugin)) return false;
|
|
|
|
try {
|
|
require $file;
|
|
} catch (\Throwable $e) {
|
|
ErrorHandler::showExceptionMsg($e, "Error loading plugin $plugin");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a namespaced template class
|
|
*
|
|
* @param string $classPath The class name using forward slashes as namespace separators
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadTemplateClass($classPath)
|
|
{
|
|
// template namespace
|
|
if ($this->prefixStrip($classPath, 'dokuwiki/template/')) {
|
|
$classPath = str_replace('/test/', '/_test/', $classPath); // no underscore in test namespace
|
|
$file = DOKU_INC . 'lib/tpl/' . $classPath . '.php';
|
|
if (file_exists($file)) {
|
|
$template = substr($classPath, 0, strpos($classPath, '/'));
|
|
|
|
try {
|
|
require $file;
|
|
} catch (\Throwable $e) {
|
|
ErrorHandler::showExceptionMsg($e, "Error loading template $template");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a namespaced DokuWiki core class
|
|
*
|
|
* @param string $classPath The class name using forward slashes as namespace separators
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadCoreClass($classPath)
|
|
{
|
|
if ($this->prefixStrip($classPath, 'dokuwiki/')) {
|
|
$file = DOKU_INC . 'inc/' . $classPath . '.php';
|
|
if (file_exists($file)) {
|
|
require $file;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the class is a un-namespaced plugin class following our naming scheme
|
|
*
|
|
* @param string $className
|
|
* @return bool true if the class was loaded, false otherwise
|
|
*/
|
|
protected function autoloadNamedPluginClass($className)
|
|
{
|
|
global $plugin_controller;
|
|
|
|
if (
|
|
preg_match(
|
|
'/^(' . implode('|', PluginController::PLUGIN_TYPES) . ')_plugin_(' .
|
|
DOKU_PLUGIN_NAME_REGEX .
|
|
')(?:_([^_]+))?$/',
|
|
$className,
|
|
$m
|
|
)
|
|
) {
|
|
$c = ((count($m) === 4) ? "/{$m[3]}" : '');
|
|
$plg = DOKU_PLUGIN . "{$m[2]}/{$m[1]}$c.php";
|
|
if (file_exists($plg)) {
|
|
// don't load disabled plugin classes (only if plugin controller is available)
|
|
if (!defined('DOKU_UNITTEST') && $plugin_controller && plugin_isdisabled($m[2])) return false;
|
|
try {
|
|
require $plg;
|
|
} catch (\Throwable $e) {
|
|
ErrorHandler::showExceptionMsg($e, "Error loading plugin {$m[2]}");
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if the given string starts with the given prefix and strip it
|
|
*
|
|
* @param string $string
|
|
* @param string $prefix
|
|
* @return bool true if the prefix was found and stripped, false otherwise
|
|
*/
|
|
protected function prefixStrip(&$string, $prefix)
|
|
{
|
|
if (str_starts_with($string, $prefix)) {
|
|
$string = substr($string, strlen($prefix));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|