MDL-83424 core: Update component/plugin resolution to include new paths

This commit is contained in:
Andrew Nicols
2024-11-08 23:52:59 +08:00
parent efe3582d4a
commit 3133520615
13 changed files with 281 additions and 126 deletions
+8 -7
View File
@@ -47,8 +47,6 @@ const fetchComponentData = () => {
const components = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/components.json`));
const pluginData = JSON.parse(fs.readFileSync(`${gruntFilePath}/lib/plugins.json`));
componentData.pluginTypes = components.plugintypes;
const standardPlugins = Object.entries(pluginData.standard).map(
([pluginType, pluginNames]) => {
return pluginNames.map(pluginName => `${pluginType}_${pluginName}`);
@@ -56,18 +54,21 @@ const fetchComponentData = () => {
).reduce((acc, val) => acc.concat(val), []);
// Build the list of moodle subsystems.
componentData.subsystems.lib = 'core';
componentData.pathList.push(process.cwd() + path.sep + 'lib');
componentData.subsystems['public/lib'] = 'core';
componentData.pathList.push(`${process.cwd()}/public/lib`);
for (const [component, thisPath] of Object.entries(components.subsystems)) {
if (thisPath) {
// Prefix "core_" to the front of the subsystems.
componentData.subsystems[thisPath] = `core_${component}`;
componentData.pathList.push(process.cwd() + path.sep + thisPath);
componentData.pathList.push(`${process.cwd()}/${thisPath}`);
}
}
// The list of components includes the list of subsystems.
componentData.components = {...componentData.subsystems};
componentData.components = Object.fromEntries(
Object.entries(componentData.subsystems)
.map(([path, name]) => ([path, name]))
);
const subpluginAdder = (subpluginType, subpluginTypePath) => {
glob.sync(`${subpluginTypePath}/*/version.php`).forEach(versionPath => {
@@ -104,7 +105,7 @@ const fetchComponentData = () => {
});
} else if (subpluginList.plugintypes) {
Object.entries(subpluginList.plugintypes).forEach(([subpluginType, subpluginTypePath]) => {
subpluginAdder(subpluginType, subpluginTypePath);
subpluginAdder(subpluginType, `public/${subpluginTypePath}`);
});
}
}
+2 -2
View File
@@ -30,7 +30,7 @@ module.exports = grunt => {
* @param {string} path
* @returns {string}
*/
const getCLPath = path => `admin/tool/componentlibrary/${path}`;
const getCLPath = path => `public/admin/tool/componentlibrary/${path}`;
/**
* Get a spawn handler.
@@ -97,7 +97,7 @@ module.exports = grunt => {
'--source-map',
'--embed-sources',
'--precision', 6,
'--load-path', process.cwd(),
'--load-path', `${process.cwd()}/public`,
getCLPath('hugo/scss/docs.scss'),
getCLPath('hugo/dist/css/docs.css'),
]);
+3 -3
View File
@@ -84,10 +84,10 @@ module.exports = grunt => {
const stylelintIgnores = [
'# Generated by "grunt ignorefiles"',
'**/yui/build/*',
'theme/boost/style/moodle.css',
'theme/classic/style/moodle.css',
'public/theme/boost/style/moodle.css',
'public/theme/classic/style/moodle.css',
'jsdoc/styles/*.css',
'admin/tool/componentlibrary/hugo/dist/css/docs.css',
'public/admin/tool/componentlibrary/hugo/dist/css/docs.css',
].concat(thirdPartyPaths);
grunt.file.write('.stylelintignore', stylelintIgnores.join('\n') + '\n');
+2 -2
View File
@@ -43,8 +43,8 @@ module.exports = (grunt) => {
const componentData = fetchComponentData().components;
for (const [thisPath, component] of Object.entries(componentData)) {
jsconfigData.compilerOptions.paths[`${component}/*`] = [`${thisPath}/amd/src/*`];
jsconfigData.include.push(`${thisPath}/amd/src/**/*`);
jsconfigData.compilerOptions.paths[`${component}/*`] = [`public/${thisPath}/amd/src/*`];
jsconfigData.include.push(`public/${thisPath}/amd/src/**/*`);
}
grunt.file.write('jsconfig.json', JSON.stringify(jsconfigData, null, " ") + "\n");
+6 -3
View File
@@ -27,13 +27,16 @@ module.exports = grunt => {
sass: {
dist: {
files: {
"theme/boost/style/moodle.css": "theme/boost/scss/preset/default.scss",
"theme/classic/style/moodle.css": "theme/classic/scss/classicgrunt.scss"
"public/theme/boost/style/moodle.css": "public/theme/boost/scss/preset/default.scss",
"public/theme/classic/style/moodle.css": "public/theme/classic/scss/classicgrunt.scss"
}
},
options: {
implementation: require('sass'),
includePaths: ["theme/boost/scss/", "theme/classic/scss/"]
includePaths: [
"public/theme/boost/scss/",
"public/theme/classic/scss/",
]
}
},
});
+2 -2
View File
@@ -22,8 +22,8 @@
"Moodle\\BehatExtension": "lib/behat/extension/"
},
"psr-4": {
"core_testing\\": "lib/testing/classes/",
"core_phpunit\\": "lib/phpunit/classes/"
"core_testing\\": "public/lib/testing/classes/",
"core_phpunit\\": "public/lib/phpunit/classes/"
}
},
"minimum-stability": "dev",
+135
View File
@@ -0,0 +1,135 @@
{
"plugintypes": {
"aiplacement": "public/ai/placement",
"aiprovider": "public/ai/provider",
"antivirus": "public/lib/antivirus",
"availability": "public/availability/condition",
"qtype": "public/question/type",
"mod": "public/mod",
"auth": "public/auth",
"calendartype": "public/calendar/type",
"communication": "public/communication/provider",
"customfield": "public/customfield/field",
"enrol": "public/enrol",
"message": "public/message/output",
"block": "public/blocks",
"media": "public/media/player",
"filter": "public/filter",
"editor": "public/lib/editor",
"format": "public/course/format",
"dataformat": "public/dataformat",
"profilefield": "public/user/profile/field",
"report": "public/report",
"coursereport": "public/course/report",
"gradeexport": "public/grade/export",
"gradeimport": "public/grade/import",
"gradepenalty": "public/grade/penalty",
"gradereport": "public/grade/report",
"gradingform": "public/grade/grading/form",
"mlbackend": "public/lib/mlbackend",
"webservice": "public/webservice",
"repository": "public/repository",
"portfolio": "public/portfolio",
"search": "public/search/engine",
"qbank": "public/question/bank",
"qbehaviour": "public/question/behaviour",
"qformat": "public/question/format",
"plagiarism": "public/plagiarism",
"tool": "public/admin/tool",
"cachestore": "public/cache/stores",
"cachelock": "public/cache/locks",
"fileconverter": "public/files/converter",
"contenttype": "public/contentbank/contenttype",
"theme": "public/theme",
"local": "public/local",
"h5plib": "public/h5p/h5plib",
"paygw": "public/payment/gateway",
"smsgateway": "public/sms/gateway"
},
"subsystems": {
"ai": "public/ai",
"access": null,
"admin": "public/admin",
"adminpresets": "public/admin/presets",
"analytics": "public/analytics",
"antivirus": "public/lib/antivirus",
"auth": "public/auth",
"availability": "public/availability",
"backup": "public/backup/util/ui",
"badges": "public/badges",
"block": "public/blocks",
"blog": "public/blog",
"bulkusers": null,
"cache": "public/cache",
"calendar": "public/calendar",
"cohort": "public/cohort",
"comment": "public/comment",
"communication": "public/communication",
"competency": "public/competency",
"completion": "public/completion",
"contentbank": "public/contentbank",
"countries": null,
"course": "public/course",
"courseformat": "public/course/format",
"currencies": null,
"customfield": "public/customfield",
"dbtransfer": null,
"debug": null,
"editor": "public/lib/editor",
"edufields": null,
"enrol": "public/enrol",
"error": null,
"external": "public/lib/external",
"favourites": "public/favourites",
"filepicker": null,
"fileconverter": "public/files/converter",
"files": "public/files",
"filters": "public/filter",
"form": "public/lib/form",
"grades": "public/grade",
"grading": "public/grade/grading",
"group": "public/group",
"help": null,
"hub": null,
"h5p": "public/h5p",
"imscc": null,
"install": null,
"iso6392": null,
"langconfig": null,
"license": null,
"mathslib": null,
"media": "public/media",
"message": "public/message",
"mimetypes": null,
"mnet": "public/mnet",
"my": "public/my",
"notes": "public/notes",
"pagetype": null,
"payment" : "public/payment",
"pix": null,
"plagiarism": "public/plagiarism",
"plugin": null,
"portfolio": "public/portfolio",
"privacy": "public/privacy",
"question": "public/question",
"rating": "public/rating",
"report": "public/report",
"reportbuilder": "public/reportbuilder",
"repository": "public/repository",
"rss": "public/rss",
"role": "public/admin/roles",
"search": "public/search",
"sms": "public/sms",
"table": "public/lib/table",
"tag": "public/tag",
"timezones": null,
"user": "public/user",
"userkey": "public/lib/userkey",
"webservice": "public/webservice",
"xapi": "public/lib/xapi"
},
"deprecatedplugintypes":
{
"mnetservice": "public/mnet/service"
}
}
+74 -65
View File
@@ -110,64 +110,64 @@ class component {
protected static $filestomap = ['lib.php', 'settings.php'];
/** @var array associative array of PSR-0 namespaces and corresponding paths. */
protected static $psr0namespaces = [
'Mustache' => 'lib/mustache/src/Mustache',
'Mustache' => 'public/lib/mustache/src/Mustache',
];
/** @var array<string|array<string>> associative array of PRS-4 namespaces and corresponding paths. */
protected static $psr4namespaces = [
\Aws::class => 'lib/aws-sdk/src',
\CFPropertyList::class => 'lib/plist/src/CFPropertyList',
\Complex::class => 'lib/phpspreadsheet/markbaker/complex/classes/src',
\Composer\Pcre::class => 'lib/composer/pcre/src',
\DI::class => 'lib/php-di/php-di/src',
\GeoIp2::class => 'lib/maxmind/GeoIp2/src',
\FastRoute::class => 'lib/nikic/fast-route/src',
\Firebase\JWT::class => 'lib/php-jwt/src',
\GuzzleHttp::class => 'lib/guzzlehttp/guzzle/src',
\GuzzleHttp\Promise::class => 'lib/guzzlehttp/promises/src',
\GuzzleHttp\Psr7::class => 'lib/guzzlehttp/psr7/src',
\Html2Text::class => 'lib/html2text/src',
\IMSGlobal\LTI::class => 'lib/ltiprovider/src',
\Invoker::class => 'lib/php-di/invoker/src',
\JmesPath::class => 'lib/jmespath/src',
\Kevinrob\GuzzleCache::class => 'lib/guzzlehttp/kevinrob/guzzlecache/src',
\Laravel\SerializableClosure::class => 'lib/laravel/serializable-closure/src',
\lbuchs\WebAuthn::class => 'lib/webauthn/src',
\libphonenumber::class => 'lib/giggsey/libphonenumber-for-php-lite/src',
\Matrix::class => 'lib/phpspreadsheet/markbaker/matrix/classes/src',
\MatthiasMullie\Minify::class => 'lib/minify/matthiasmullie-minify/src',
\MatthiasMullie\PathConverter::class => 'lib/minify/matthiasmullie-pathconverter/src',
\MaxMind\Db::class => 'lib/maxmind/MaxMind/src/MaxMind/Db',
\Michelf::class => 'lib/markdown/Michelf',
\Aws::class => 'public/lib/aws-sdk/src',
\CFPropertyList::class => 'public/lib/plist/src/CFPropertyList',
\Complex::class => 'public/lib/phpspreadsheet/markbaker/complex/classes/src',
\Composer\Pcre::class => 'public/lib/composer/pcre/src',
\DI::class => 'public/lib/php-di/php-di/src',
\GeoIp2::class => 'public/lib/maxmind/GeoIp2/src',
\FastRoute::class => 'public/lib/nikic/fast-route/src',
\Firebase\JWT::class => 'public/lib/php-jwt/src',
\GuzzleHttp::class => 'public/lib/guzzlehttp/guzzle/src',
\GuzzleHttp\Promise::class => 'public/lib/guzzlehttp/promises/src',
\GuzzleHttp\Psr7::class => 'public/lib/guzzlehttp/psr7/src',
\Html2Text::class => 'public/lib/html2text/src',
\IMSGlobal\LTI::class => 'public/lib/ltiprovider/src',
\Invoker::class => 'public/lib/php-di/invoker/src',
\JmesPath::class => 'public/lib/jmespath/src',
\Kevinrob\GuzzleCache::class => 'public/lib/guzzlehttp/kevinrob/guzzlecache/src',
\Laravel\SerializableClosure::class => 'public/lib/laravel/serializable-closure/src',
\lbuchs\WebAuthn::class => 'public/lib/webauthn/src',
\libphonenumber::class => 'public/lib/giggsey/libphonenumber-for-php-lite/src',
\Matrix::class => 'public/lib/phpspreadsheet/markbaker/matrix/classes/src',
\MatthiasMullie\Minify::class => 'public/lib/minify/matthiasmullie-minify/src',
\MatthiasMullie\PathConverter::class => 'public/lib/minify/matthiasmullie-pathconverter/src',
\MaxMind\Db::class => 'public/lib/maxmind/MaxMind/src/MaxMind/Db',
\Michelf::class => 'public/lib/markdown/Michelf',
\MoodleHQ::class => [
'lib/rtlcss/src/MoodleHQ',
'public/lib/rtlcss/src/MoodleHQ',
],
\OpenSpout::class => 'lib/openspout/src',
\Packback\Lti1p3::class => 'lib/lti1p3/src',
\PHPMailer\PHPMailer::class => 'lib/phpmailer/src',
\PhpOffice\PhpSpreadsheet::class => 'lib/phpspreadsheet/phpspreadsheet/src/PhpSpreadsheet',
\PhpXmlRpc::class => 'lib/phpxmlrpc/src',
\Phpml::class => 'lib/mlbackend/php/phpml/src/Phpml',
\Psr\Clock::class => 'lib/psr/clock/src',
\Psr\Container::class => 'lib/psr/container/src',
\Psr\EventDispatcher::class => 'lib/psr/event-dispatcher/src',
\Psr\Http\Client::class => 'lib/psr/http-client/src',
\OpenSpout::class => 'public/lib/openspout/src',
\Packback\Lti1p3::class => 'public/lib/lti1p3/src',
\PHPMailer\PHPMailer::class => 'public/lib/phpmailer/src',
\PhpOffice\PhpSpreadsheet::class => 'public/lib/phpspreadsheet/phpspreadsheet/src/PhpSpreadsheet',
\PhpXmlRpc::class => 'public/lib/phpxmlrpc/src',
\Phpml::class => 'public/lib/mlbackend/php/phpml/src/Phpml',
\Psr\Clock::class => 'public/lib/psr/clock/src',
\Psr\Container::class => 'public/lib/psr/container/src',
\Psr\EventDispatcher::class => 'public/lib/psr/event-dispatcher/src',
\Psr\Http\Client::class => 'public/lib/psr/http-client/src',
\Psr\Http\Message::class => [
'lib/psr/http-factory/src',
'lib/psr/http-message/src',
'public/lib/psr/http-factory/src',
'public/lib/psr/http-message/src',
],
\Psr\Http\Server::class => [
"lib/psr/http-server-handler/src",
"lib/psr/http-server-middleware/src",
"public/lib/psr/http-server-handler/src",
"public/lib/psr/http-server-middleware/src",
],
\Psr\Log::class => "lib/psr/log/src",
\Psr\SimpleCache::class => 'lib/psr/simple-cache/src',
\RedeyeVentures::class => 'lib/geopattern-php/src',
\Sabberworm\CSS::class => 'lib/php-css-parser/src',
\ScssPhp\ScssPhp::class => 'lib/scssphp/src',
\SimplePie::class => 'lib/simplepie/src',
\Slim::class => 'lib/slim/slim/Slim',
\Spatie\Cloneable::class => 'lib/spatie/php-cloneable/src',
\ZipStream::class => 'lib/zipstream/src',
\Psr\Log::class => "public/lib/psr/log/src",
\Psr\SimpleCache::class => 'public/lib/psr/simple-cache/src',
\RedeyeVentures::class => 'public/lib/geopattern-php/src',
\Sabberworm\CSS::class => 'public/lib/php-css-parser/src',
\ScssPhp\ScssPhp::class => 'public/lib/scssphp/src',
\SimplePie::class => 'public/lib/simplepie/src',
\Slim::class => 'public/lib/slim/slim/Slim',
\Spatie\Cloneable::class => 'public/lib/spatie/php-cloneable/src',
\ZipStream::class => 'public/lib/zipstream/src',
];
/**
@@ -180,13 +180,13 @@ class component {
* @var array<string>
*/
protected static $composerautoloadfiles = [
'lib/aws-sdk/src/functions.php',
'lib/guzzlehttp/guzzle/src/functions_include.php',
'lib/jmespath/src/JmesPath.php',
'lib/nikic/fast-route/src/functions.php',
'lib/php-di/php-di/src/functions.php',
'lib/ralouphie/getallheaders/src/getallheaders.php',
'lib/symfony/deprecation-contracts/function.php',
'public/lib/aws-sdk/src/functions.php',
'public/lib/guzzlehttp/guzzle/src/functions_include.php',
'public/lib/jmespath/src/JmesPath.php',
'public/lib/nikic/fast-route/src/functions.php',
'public/lib/php-di/php-di/src/functions.php',
'public/lib/ralouphie/getallheaders/src/getallheaders.php',
'public/lib/symfony/deprecation-contracts/function.php',
];
/**
@@ -202,7 +202,7 @@ class component {
// Load any composer-driven autoload files.
// This is intended to mimic the behaviour of the standard Composer Autoloader.
foreach (static::$composerautoloadfiles as $file) {
$path = dirname(__DIR__, 2) . '/' . $file;
$path = dirname(__DIR__, 3) . '/' . $file;
if (file_exists($path)) {
require_once($path);
}
@@ -341,7 +341,8 @@ class component {
// No, move to the next prefix.
return false;
}
$path = $CFG->dirroot . '/' . $path;
$path = $CFG->root . '/' . $path;
// Get the relative class name.
$relativeclass = substr($class, $len);
@@ -700,7 +701,7 @@ $cache = ' . var_export($cache, true) . ';
}
}
$info[$subsystem] = empty($path) ? null : "{$CFG->dirroot}/{$path}";
$info[$subsystem] = empty($path) ? null : "{$CFG->root}/{$path}";
}
return $info;
@@ -743,7 +744,7 @@ $cache = ' . var_export($cache, true) . ';
if ($CFG->admin !== 'admin' && strpos($path, 'admin/') === 0) {
$path = $CFG->admin . substr($path, 5);
}
$plugintypesmap[$sourcekey][$plugintype] = "{$CFG->dirroot}/{$path}";
$plugintypesmap[$sourcekey][$plugintype] = "{$CFG->root}/{$path}";
}
}
@@ -863,7 +864,7 @@ $cache = ' . var_export($cache, true) . ';
*/
protected static function fetch_component_source(string $key) {
if (null === self::$componentsource) {
self::$componentsource = (array) json_decode(file_get_contents(__DIR__ . '/../components.json'));
self::$componentsource = (array) json_decode(file_get_contents(dirname(__DIR__, 3) . '/lib/components.json'));
}
return !empty(self::$componentsource[$key]) ? (array) self::$componentsource[$key] : [];
@@ -879,8 +880,8 @@ $cache = ' . var_export($cache, true) . ';
$types = [];
$subplugins = [];
if (str_contains($ownerdir, $CFG->dirroot)) {
$plugindir = substr($ownerdir, strlen($CFG->dirroot) + 1);
if (str_contains($ownerdir, $CFG->root)) {
$plugindir = substr($ownerdir, strlen($CFG->root) + 1);
} else {
$realownerdir = realpath($ownerdir);
$realroot = realpath(dirname(__DIR__, 2));
@@ -908,6 +909,10 @@ $cache = ' . var_export($cache, true) . ';
"See MDL-83705 for further information.",
);
$subplugins = (array) $subpluginsjson->plugintypes;
array_walk(
$subplugins,
fn (string &$path): string => $path = str_starts_with($path, 'public/') ? $path : "public/{$path}",
);
} else if (empty($subpluginjson->deprecatedplugintypes) && empty($subpluginsjson->deletedplugintypes)) {
error_log("No plugintypes defined in $ownerdir/db/subplugins.json");
}
@@ -932,6 +937,10 @@ $cache = ' . var_export($cache, true) . ';
if (property_exists($subpluginsjson, 'subplugintypes') && property_exists($subpluginsjson, 'plugintypes')) {
$subplugintypes = (array) $subpluginsjson->subplugintypes;
$plugintypes = (array) $subpluginsjson->plugintypes;
array_walk(
$plugintypes,
fn (string &$path): string => $path = str_starts_with($path, 'public/') ? $path : "public/{$path}",
);
if (count($subplugintypes) !== count(($plugintypes))) {
error_log("Subplugintypes and plugintypes are not in sync in $ownerdir/db/subplugins.json");
}
@@ -968,11 +977,11 @@ $cache = ' . var_export($cache, true) . ';
if ($CFG->admin !== 'admin' && strpos($dir, 'admin/') === 0) {
$dir = preg_replace('|^admin/|', "$CFG->admin/", $dir);
}
if (!is_dir("$CFG->dirroot/$dir")) {
if (!is_dir("$CFG->root/$dir")) {
error_log("Invalid subtype directory '$dir' detected in '$ownerdir'.");
continue;
}
$types[$key][$subtype] = "$CFG->dirroot/$dir";
$types[$key][$subtype] = "$CFG->root/$dir";
}
}
+1 -1
View File
@@ -347,7 +347,7 @@ class plugin_manager {
*/
protected static function load_standard_plugins(): stdClass {
if (static::$standardplugincache === null) {
$data = file_get_contents(dirname(__DIR__) . '/plugins.json');
$data = file_get_contents(dirname(__DIR__, 3) . '/lib/plugins.json');
static::$standardplugincache = json_decode($data, false);
}
+2 -2
View File
@@ -90,11 +90,11 @@ function get_plugin_types($fullpaths = true) {
debugging('Short paths are deprecated when using get_plugin_types(), please fix the code to use fullpaths instead.', DEBUG_DEVELOPER);
$dlength = strlen($CFG->dirroot);
$dlength = strlen($CFG->root);
foreach ($types as $k => $v) {
if ($k === 'theme') {
$types[$k] = 'theme';
$types[$k] = 'public/theme';
continue;
}
$types[$k] = substr($v, $dlength+1);
+1
View File
@@ -60,6 +60,7 @@ if (!isset($CFG)) {
// We can detect real dirroot path reliably since PHP 4.0.2,
// it can not be anything else, there is no point in having this in config.php
$CFG->dirroot = dirname(__DIR__);
$CFG->root = dirname($CFG->dirroot);
// File permissions on created directories in the $CFG->dataroot
if (!isset($CFG->directorypermissions)) {
+45 -39
View File
@@ -148,7 +148,7 @@ final class component_test extends \advanced_testcase {
$plugintypes = component::get_plugin_types();
foreach ($plugintypes as $plugintype => $fulldir) {
$this->assertStringStartsWith("$CFG->dirroot/", $fulldir);
$this->assertStringStartsWith("$CFG->root/", $fulldir);
}
}
@@ -170,7 +170,7 @@ final class component_test extends \advanced_testcase {
$this->resetDebugging();
foreach ($plugintypes as $plugintype => $fulldir) {
$this->assertSame($fulldir, $CFG->dirroot . '/' . $realplugintypes[$plugintype]);
$this->assertSame($fulldir, $CFG->root . '/' . $realplugintypes[$plugintype]);
}
}
@@ -747,12 +747,12 @@ final class component_test extends \advanced_testcase {
$directory = str_replace('\\', '/', $CFG->dirroot) . "/lib/tests/fixtures/component/";
$psr0 = [
'psr0' => 'lib/tests/fixtures/component/psr0',
'overlap' => 'lib/tests/fixtures/component/overlap',
'psr0' => 'public/lib/tests/fixtures/component/psr0',
'overlap' => 'public/lib/tests/fixtures/component/overlap',
];
$psr4 = [
'psr4' => 'lib/tests/fixtures/component/psr4',
'overlap' => 'lib/tests/fixtures/component/overlap',
'psr4' => 'public/lib/tests/fixtures/component/psr4',
'overlap' => 'public/lib/tests/fixtures/component/overlap',
];
return [
'PSR-0 Classloading - Root' => [
@@ -1038,21 +1038,21 @@ final class component_test extends \advanced_testcase {
'prefix' => "Test",
'path' => 'test/src',
'separators' => ['_'],
'result' => $CFG->dirroot . "/test/src/With/Underscores.php",
'result' => $CFG->root . "/test/src/With/Underscores.php",
],
'Getting a file with slashes' => [
'classname' => 'Test\\With\\Slashes',
'prefix' => "Test",
'path' => 'test/src',
'separators' => ['\\'],
'result' => $CFG->dirroot . "/test/src/With/Slashes.php",
'result' => $CFG->root . "/test/src/With/Slashes.php",
],
'Getting a file with multiple namespaces' => [
'classname' => 'Test\\With\\Multiple\\Namespaces',
'prefix' => "Test\\With",
'path' => 'test/src',
'separators' => ['\\'],
'result' => $CFG->dirroot . "/test/src/Multiple/Namespaces.php",
'result' => $CFG->root . "/test/src/Multiple/Namespaces.php",
],
'Getting a file with multiple namespaces (non-existent)' => [
'classname' => 'Nonexistent\\Namespace\\Test',
@@ -1287,7 +1287,7 @@ final class component_test extends \advanced_testcase {
foreach ($xml as $lib) {
$base = realpath(dirname($xmlpath));
$fullpath = "{$base}/{$lib->location}";
$relativepath = substr($fullpath, strlen($CFG->dirroot));
$relativepath = substr($fullpath, strlen($CFG->root));
$libs[$relativepath] = [
'name' => (string) $lib->name,
@@ -1421,23 +1421,26 @@ final class component_test extends \advanced_testcase {
$this->resetAfterTest();
$vfileroot = \org\bovigo\vfs\vfsStream::setup('root', null, [
'plugintype' => [
'exampleplugin' => [
'db' => [
'subplugins.json' => json_encode([
'subplugintypes' => [
'exampleplugina' => 'apples',
],
]),
'subplugins.php' => '',
'public' => [
'plugintype' => [
'exampleplugin' => [
'db' => [
'subplugins.json' => json_encode([
'subplugintypes' => [
'exampleplugina' => 'apples',
],
]),
'subplugins.php' => '',
],
'apples' => [],
],
'apples' => [],
],
],
]);
$CFG->dirroot = $vfileroot->url();
$pluginroot = $vfileroot->getChild('plugintype/exampleplugin');
$CFG->root = $vfileroot->url();
$CFG->dirroot = $vfileroot->getChild('public')->url();
$pluginroot = $vfileroot->getChild('public/plugintype/exampleplugin');
$rcm = new \ReflectionMethod(\core\component::class, 'fetch_subtypes');
$subplugins = $rcm->invoke(null, $pluginroot->url());
@@ -1457,23 +1460,26 @@ final class component_test extends \advanced_testcase {
$this->resetAfterTest();
$vfileroot = \org\bovigo\vfs\vfsStream::setup('root', null, [
'plugintype' => [
'exampleplugin' => [
'db' => [
'subplugins.json' => json_encode([
'plugintypes' => [
'exampleplugina' => 'plugintype/exampleplugin/apples',
],
]),
'subplugins.php' => '',
'public' => [
'plugintype' => [
'exampleplugin' => [
'db' => [
'subplugins.json' => json_encode([
'plugintypes' => [
'exampleplugina' => 'plugintype/exampleplugin/apples',
],
]),
'subplugins.php' => '',
],
'apples' => [],
],
'apples' => [],
],
],
]);
$CFG->dirroot = $vfileroot->url();
$pluginroot = $vfileroot->getChild('plugintype/exampleplugin');
$CFG->root = $vfileroot->url();
$CFG->dirroot = $vfileroot->getchild('public')->url();
$pluginroot = $vfileroot->getChild('public/plugintype/exampleplugin');
$logdir = make_request_directory();
$logfile = "{$logdir}/error.log";
@@ -1643,7 +1649,7 @@ final class component_test extends \advanced_testcase {
// Inject the 'fake' plugin type.
$this->add_full_mocked_plugintype(
plugintype: 'fake',
path: 'lib/tests/fixtures/fakeplugins/fake'
path: 'public/lib/tests/fixtures/fakeplugins/fake',
);
$componenthashbefore = component::get_all_component_hash();
@@ -1715,7 +1721,7 @@ final class component_test extends \advanced_testcase {
// Inject the 'fake' plugin type.
$this->add_full_mocked_plugintype(
plugintype: 'fake',
path: 'lib/tests/fixtures/fakeplugins/fake',
path: 'public/lib/tests/fixtures/fakeplugins/fake',
);
// Delete the fake plugintype via mocking component sources.
@@ -1766,7 +1772,7 @@ final class component_test extends \advanced_testcase {
// 3. fulldeletedsubtype_demo: a deleted subplugin type.
$this->add_full_mocked_plugintype(
plugintype: 'fake',
path: 'lib/tests/fixtures/fakeplugins/fake',
path: 'public/lib/tests/fixtures/fakeplugins/fake',
subpluginsupport: true
);
$this->assert_deprecation_apis_subplugins();
@@ -1787,7 +1793,7 @@ final class component_test extends \advanced_testcase {
// 3. fulldeletedsubtype_demo: a deleted subplugin type.
$this->add_full_mocked_plugintype(
plugintype: 'fake',
path: 'lib/tests/fixtures/fakeplugins/fake',
path: 'public/lib/tests/fixtures/fakeplugins/fake',
subpluginsupport: true
);
@@ -1816,7 +1822,7 @@ final class component_test extends \advanced_testcase {
// 3. fulldeletedsubtype_demo: a deleted subplugin type.
$this->add_full_mocked_plugintype(
plugintype: 'fake',
path: 'lib/tests/fixtures/fakeplugins/fake',
path: 'public/lib/tests/fixtures/fakeplugins/fake',
subpluginsupport: true
);