From 5eb64075f4341ce654b7ff8d7e18e5c27a529e37 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 14 Jul 2025 10:07:33 +0800 Subject: [PATCH] MDL-83424 core: Make \core\component more resilient outside of install --- public/lib/classes/component.php | 43 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/public/lib/classes/component.php b/public/lib/classes/component.php index b51bc3c8508..c97c1a31025 100644 --- a/public/lib/classes/component.php +++ b/public/lib/classes/component.php @@ -342,7 +342,7 @@ class component { return false; } - $path = $CFG->root . '/' . $path; + $path = self::get_path($path); // Get the relative class name. $relativeclass = substr($class, $len); @@ -701,7 +701,7 @@ $cache = ' . var_export($cache, true) . '; } } - $info[$subsystem] = empty($path) ? null : "{$CFG->root}/{$path}"; + $info[$subsystem] = empty($path) ? null : self::get_path($path); } return $info; @@ -744,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->root}/{$path}"; + $plugintypesmap[$sourcekey][$plugintype] = self::get_path($path); } } @@ -880,8 +880,9 @@ $cache = ' . var_export($cache, true) . '; $types = []; $subplugins = []; - if (str_contains($ownerdir, $CFG->root)) { - $plugindir = substr($ownerdir, strlen($CFG->root) + 1); + $root = self::get_path(); + if (str_contains($ownerdir, $root)) { + $plugindir = substr($ownerdir, strlen($root) + 1); } else { $realownerdir = realpath($ownerdir); $realroot = realpath(dirname(__DIR__, 2)); @@ -977,11 +978,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->root/$dir")) { + if (!is_dir(self::get_path($dir))) { error_log("Invalid subtype directory '$dir' detected in '$ownerdir'."); continue; } - $types[$key][$subtype] = "$CFG->root/$dir"; + $types[$key][$subtype] = self::get_path($dir); } } @@ -2043,6 +2044,34 @@ $cache = ' . var_export($cache, true) . '; $haspngmonologo = $theme->resolve_image_location('monologo', $component) !== null; return $haspngmonologo || $hassvgmonologo; } + + /** + * Returns a path relative to the Moodle root directory. + * + * @param string $path The child path + * @return string The full path within the root directory. + */ + protected static function get_path(string $path = ''): string { + global $CFG; + + if (property_exists($CFG, 'root')) { + // If the root property exists, use it. + $root = $CFG->root; + } else if (property_exists($CFG, 'dirroot')) { + $root = dirname($CFG->dirroot); + } else { + throw new \RuntimeException( + 'The $CFG->root or $CFG->dirroot property must be set to use the component class.', + ); + } + + if ($path === '') { + // If no path is provided, return the root directory. + return rtrim($root, '/'); + } + + return rtrim($root, '/') . '/' . ltrim($path, '/'); + } } // Alias this class to the old name.