From 3a0d155d3532227bee73a751e3c96e16af0df610 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 13 Nov 2024 12:11:51 +0800 Subject: [PATCH] Moodle: Use plugin types from project metadata Moodle maintains a list of valid plugin types in lib/components.json, and of valid subplugin types in relevant plugins. These can be used to fetch the correct list of plugin types and their paths for the current installation target rather than maintaining a static list. --- src/Composer/Installers/MoodleInstaller.php | 64 +++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/Composer/Installers/MoodleInstaller.php b/src/Composer/Installers/MoodleInstaller.php index eb2b8acf..0a24bf4a 100644 --- a/src/Composer/Installers/MoodleInstaller.php +++ b/src/Composer/Installers/MoodleInstaller.php @@ -2,6 +2,10 @@ namespace Composer\Installers; +use Composer\IO\IOInterface; +use Composer\Composer; +use Composer\Package\PackageInterface; + class MoodleInstaller extends BaseInstaller { /** @var array */ @@ -70,4 +74,64 @@ class MoodleInstaller extends BaseInstaller 'workshopeval' => 'mod/workshop/eval/{$name}/', 'workshopform' => 'mod/workshop/form/{$name}/' ); + + /** + * Initializes base installer. + */ + public function __construct(PackageInterface $package = null, Composer $composer = null, IOInterface $io = null) + { + parent::__construct($package, $composer, $io); + + $componentsfile = getcwd() . '/lib/components.json'; + if (!file_exists($componentsfile)) { + // Must be a very old version of Moodle. + // Fall back on the default install path list. + return; + } + + $locations = []; + + // Moodle maintains a list of plugin types and their location in a + // components.json file. + // This is the authoritative list and should be used wherever possible. + $components = json_decode(file_get_contents($componentsfile), true); + $locations = array_map( + function(string $path) { + return $path . '/{$name}'; + }, + $components['plugintypes'] + ); + + // This could be a subplugin. + // Plugins can define subplugins in a db/subplugins.json file. + foreach (array_values($components['plugintypes']) as $path) { + $iterator = new \DirectoryIterator($path); + foreach ($iterator as $plugin) { + $subpluginFile = $plugin->getPathname() . '/db/subplugins.json'; + if ($plugin->isDir() && is_file($subpluginFile)) { + $subplugins = json_decode(file_get_contents($subpluginFile), true); + + if (array_key_exists('subplugintypes', $subplugins)) { + // In Moodle 5.0, subplugins are defined in a + // 'subplugintypes' array. + // This value is relative to the plugin directory. + $subpluginTypes = $subplugins['subplugintypes']; + foreach ($subpluginTypes as $pluginType => $subpluginPath) { + $locations[$pluginType] = $plugin->getPathname() . '/' . $subpluginPath . '/{$name}'; + } + } else if (array_key_exists('plugintypes', $subplugins)) { + // Before Moodle 5.0, subplugins are defined + // in a 'plugintypes' array. + // This value is relative to the project root. + $subpluginTypes = $subplugins['plugintypes']; + foreach ($subpluginTypes as $pluginType => $subpluginPath) { + $locations[$pluginType] = $subpluginPath. '/{$name}'; + } + } + } + } + } + + $this->locations = $locations; + } }