MDL-26943 implement subplugin support for local plugins
This commit is contained in:
+5
-4
@@ -128,14 +128,15 @@ function uninstall_plugin($type, $name) {
|
||||
// This may take a long time.
|
||||
@set_time_limit(0);
|
||||
|
||||
// recursively uninstall all module/editor subplugins first
|
||||
if ($type === 'mod' || $type === 'editor') {
|
||||
$base = get_component_directory($type . '_' . $name);
|
||||
// Recursively uninstall all subplugins first.
|
||||
$subplugintypes = core_component::get_plugin_types_with_subplugins();
|
||||
if (isset($subplugintypes[$type])) {
|
||||
$base = core_component::get_plugin_directory($type, $name);
|
||||
if (file_exists("$base/db/subplugins.php")) {
|
||||
$subplugins = array();
|
||||
include("$base/db/subplugins.php");
|
||||
foreach ($subplugins as $subplugintype=>$dir) {
|
||||
$instances = get_plugin_list($subplugintype);
|
||||
$instances = core_component::get_plugin_list($subplugintype);
|
||||
foreach ($instances as $subpluginname => $notusedpluginpath) {
|
||||
uninstall_plugin($subplugintype, $subpluginname);
|
||||
}
|
||||
|
||||
+71
-17
@@ -29,7 +29,7 @@ class core_component {
|
||||
/** @var array list of ignored directories - watch out for auth/db exception */
|
||||
protected static $ignoreddirs = array('CVS'=>true, '_vti_cnf'=>true, 'simpletest'=>true, 'db'=>true, 'yui'=>true, 'tests'=>true, 'classes'=>true);
|
||||
/** @var array list plugin types that support subplugins, do not add more here unless absolutely necessary */
|
||||
protected static $supportsubplugins = array('mod', 'editor');
|
||||
protected static $supportsubplugins = array('mod', 'editor', 'local');
|
||||
|
||||
/** @var null cache of plugin types */
|
||||
protected static $plugintypes = null;
|
||||
@@ -326,29 +326,69 @@ $cache = '.var_export($cache, true).';
|
||||
}
|
||||
|
||||
foreach (self::$supportsubplugins as $type) {
|
||||
$subpluginowners = self::fetch_plugins($type, $types[$type]);
|
||||
foreach ($subpluginowners as $ownerdir) {
|
||||
if (file_exists("$ownerdir/db/subplugins.php")) {
|
||||
$subplugins = array();
|
||||
include("$ownerdir/db/subplugins.php");
|
||||
foreach ($subplugins as $subtype => $dir) {
|
||||
if (!preg_match('/^[a-z][a-z0-9]*$/', $subtype)) {
|
||||
error_log("Invalid subtype '$subtype'' detected in '$ownerdir', invalid characters present.");
|
||||
continue;
|
||||
}
|
||||
if (isset(self::$subsystems[$subtype])) {
|
||||
error_log("Invalid subtype '$subtype'' detected in '$ownerdir', duplicates core subsystem.");
|
||||
continue;
|
||||
}
|
||||
$types[$subtype] = $CFG->dirroot.'/'.$dir;
|
||||
}
|
||||
if ($type === 'local') {
|
||||
// Local subplugins must be after local plugins.
|
||||
continue;
|
||||
}
|
||||
$subplugins = self::fetch_subplugins($type, $types[$type]);
|
||||
foreach($subplugins as $subtype => $subplugin) {
|
||||
if (isset($types[$subtype])) {
|
||||
error_log("Invalid subtype '$subtype', duplicate detected.");
|
||||
continue;
|
||||
}
|
||||
$types[$subtype] = $subplugin;
|
||||
}
|
||||
}
|
||||
|
||||
// Local is always last!
|
||||
$types['local'] = $CFG->dirroot.'/local';
|
||||
|
||||
if (in_array('local', self::$supportsubplugins)) {
|
||||
$subplugins = self::fetch_subplugins('local', $types['local']);
|
||||
foreach($subplugins as $subtype => $subplugin) {
|
||||
if (isset($types[$subtype])) {
|
||||
error_log("Invalid subtype '$subtype', duplicate detected.");
|
||||
continue;
|
||||
}
|
||||
$types[$subtype] = $subplugin;
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of subtypes defined in given plugin type.
|
||||
* @param string $type
|
||||
* @param string $fulldir
|
||||
* @return array
|
||||
*/
|
||||
protected static function fetch_subplugins($type, $fulldir) {
|
||||
global $CFG;
|
||||
|
||||
$types = array();
|
||||
$subpluginowners = self::fetch_plugins($type, $fulldir);
|
||||
foreach ($subpluginowners as $ownerdir) {
|
||||
if (file_exists("$ownerdir/db/subplugins.php")) {
|
||||
$subplugins = array();
|
||||
include("$ownerdir/db/subplugins.php");
|
||||
foreach ($subplugins as $subtype => $dir) {
|
||||
if (!preg_match('/^[a-z][a-z0-9]*$/', $subtype)) {
|
||||
error_log("Invalid subtype '$subtype'' detected in '$ownerdir', invalid characters present.");
|
||||
continue;
|
||||
}
|
||||
if (isset(self::$subsystems[$subtype])) {
|
||||
error_log("Invalid subtype '$subtype'' detected in '$ownerdir', duplicates core subsystem.");
|
||||
continue;
|
||||
}
|
||||
if (!is_dir("$CFG->dirroot/$dir")) {
|
||||
error_log("Invalid subtype directory '$dir' detected in '$ownerdir'.");
|
||||
continue;
|
||||
}
|
||||
$types[$subtype] = "$CFG->dirroot/$dir";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $types;
|
||||
}
|
||||
|
||||
@@ -681,4 +721,18 @@ $cache = '.var_export($cache, true).';
|
||||
|
||||
return self::get_plugin_directory($type, $plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of plugin types that allow subplugins.
|
||||
* @return array as (string)plugintype => (string)fulldir
|
||||
*/
|
||||
public static function get_plugin_types_with_subplugins() {
|
||||
self::init();
|
||||
|
||||
$return = array();
|
||||
foreach (self::$supportsubplugins as $type) {
|
||||
$return[$type] = self::$plugintypes[$type];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-7
@@ -143,8 +143,8 @@ class plugin_manager {
|
||||
// Hack: include mod and editor subplugin management classes first,
|
||||
// the adminlib.php is supposed to contain extra admin settings too.
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
foreach(array('mod', 'editor') as $type) {
|
||||
foreach (get_plugin_list($type) as $dir) {
|
||||
foreach (core_component::get_plugin_types_with_subplugins() as $type => $ignored) {
|
||||
foreach (core_component::get_plugin_list($type) as $dir) {
|
||||
if (file_exists("$dir/adminlib.php")) {
|
||||
include_once("$dir/adminlib.php");
|
||||
}
|
||||
@@ -221,8 +221,6 @@ class plugin_manager {
|
||||
* Returns list of plugins that define their subplugins and the information
|
||||
* about them from the db/subplugins.php file.
|
||||
*
|
||||
* At the moment, only activity modules and editors can define subplugins.
|
||||
*
|
||||
* @param bool $disablecache force reload, cache can be used otherwise
|
||||
* @return array with keys like 'mod_quiz', and values the data from the
|
||||
* corresponding db/subplugins.php file.
|
||||
@@ -231,9 +229,8 @@ class plugin_manager {
|
||||
|
||||
if ($disablecache or is_null($this->subpluginsinfo)) {
|
||||
$this->subpluginsinfo = array();
|
||||
foreach (array('mod', 'editor') as $type) {
|
||||
$owners = get_plugin_list($type);
|
||||
foreach ($owners as $component => $ownerdir) {
|
||||
foreach (core_component::get_plugin_types_with_subplugins() as $type => $ignored) {
|
||||
foreach (core_component::get_plugin_list($type) as $component => $ownerdir) {
|
||||
$componentsubplugins = array();
|
||||
if (file_exists($ownerdir . '/db/subplugins.php')) {
|
||||
$subplugins = array();
|
||||
|
||||
@@ -327,4 +327,19 @@ class core_component_testcase extends advanced_testcase {
|
||||
$this->assertSame($fulldir, get_component_directory(('core_'.$subsystem)));
|
||||
}
|
||||
}
|
||||
|
||||
public function test_get_plugin_types_with_subplugins() {
|
||||
global $CFG;
|
||||
|
||||
$types = core_component::get_plugin_types_with_subplugins();
|
||||
|
||||
// Hardcode it here to detect if anybody hacks the code to include more types.
|
||||
$expected = array(
|
||||
'mod' => "$CFG->dirroot/mod",
|
||||
'editor' => "$CFG->dirroot/lib/editor",
|
||||
'local' => "$CFG->dirroot/local",
|
||||
);
|
||||
|
||||
$this->assertSame($expected, $types);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user