diff --git a/lib/classes/plugin_manager.php b/lib/classes/plugin_manager.php index 9ad0ca43357..05b72efd902 100644 --- a/lib/classes/plugin_manager.php +++ b/lib/classes/plugin_manager.php @@ -356,6 +356,13 @@ class core_plugin_manager { $types = core_component::get_plugin_types(); + if (!isset($types[$type])) { + // Orphaned subplugins! + $plugintypeclass = self::resolve_plugininfo_class($type); + $this->pluginsinfo[$type] = $plugintypeclass::get_plugins($type, null, $plugintypeclass); + return $this->pluginsinfo[$type]; + } + /** @var \core\plugininfo\base $plugintypeclass */ $plugintypeclass = self::resolve_plugininfo_class($type); $plugins = $plugintypeclass::get_plugins($type, $types[$type], $plugintypeclass); @@ -386,6 +393,14 @@ class core_plugin_manager { foreach ($plugintypes as $plugintype => $plugintyperootdir) { $this->pluginsinfo[$plugintype] = null; } + + // Add orphaned subplugin types. + $this->load_installed_plugins(); + foreach ($this->installedplugins as $plugintype => $unused) { + if (!isset($plugintypes[$plugintype])) { + $this->pluginsinfo[$plugintype] = null; + } + } } /** @@ -395,6 +410,11 @@ class core_plugin_manager { * @return string name of pluginfo class for give plugin type */ public static function resolve_plugininfo_class($type) { + $plugintypes = core_component::get_plugin_types(); + if (!isset($plugintypes[$type])) { + return '\core\plugininfo\orphaned'; + } + $parent = core_component::get_subtype_parent($type); if ($parent) { diff --git a/lib/classes/plugininfo/orphaned.php b/lib/classes/plugininfo/orphaned.php new file mode 100644 index 00000000000..ec78d3931e1 --- /dev/null +++ b/lib/classes/plugininfo/orphaned.php @@ -0,0 +1,89 @@ +. + +/** + * Defines class used for orphaned subplugins. + * + * @package core + * @copyright 2013 Petr Skoda {@link http://skodak.org} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +namespace core\plugininfo; + +defined('MOODLE_INTERNAL') || die(); + + +/** + * Orphaned subplugins class. + */ +class orphaned extends base { + public function is_uninstall_allowed() { + return true; + } + + /** + * We do not know if orphaned subplugins are enabled. + * @return bool + */ + public function is_enabled() { + return null; + } + + /** + * No lang strings are present. + */ + public function init_display_name() { + $this->displayname = $this->component; + } + + /** + * Oprhaned plugins can not be enabled. + * @return array|null of enabled plugins $pluginname=>$pluginname, null means unknown + */ + public static function get_enabled_plugins() { + return null; + } + + /** + * Gathers and returns the information about all plugins of the given type, + * either on disk or previously installed. + * + * @param string $type the name of the plugintype, eg. mod, auth or workshopform + * @param string $typerootdir full path to the location of the plugin dir + * @param string $typeclass the name of the actually called class + * @return array of plugintype classes, indexed by the plugin name + */ + public static function get_plugins($type, $typerootdir, $typeclass) { + $return = array(); + $manager = \core_plugin_manager::instance(); + $plugins = $manager->get_installed_plugins($type); + + foreach ($plugins as $name => $version) { + $plugin = new $typeclass(); + $plugin->type = $type; + $plugin->typerootdir = $typerootdir; + $plugin->name = $name; + $plugin->rootdir = null; + $plugin->displayname = $name; + $plugin->versiondb = $version; + $plugin->init_is_standard(); + + $return[$name] = $plugin; + } + + return $return; + } +}