/** * Automatically clean-up all plugin data and remove the plugin DB tables * * NOTE: do not call directly, use new /admin/plugins.php?uninstall=component instead! * * @param string $type The plugin type, eg. 'mod', 'qtype', 'workshopgrading' etc. * @param string $name The plugin name, eg. 'forum', 'multichoice', 'accumulative' etc. * @uses global $OUTPUT to produce notices and other messages * @return void */ function uninstall_plugin($type, $name) { global $CFG, $DB, $OUTPUT; // This may take a long time. core_php_time_limit::raise(); // 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 = core_component::get_plugin_list($subplugintype); foreach ($instances as $subpluginname => $notusedpluginpath) { uninstall_plugin($subplugintype, $subpluginname); } } } } $component = $type . '_' . $name; // eg. 'qtype_multichoice' or 'workshopgrading_accumulative' or 'mod_forum' if ($type === 'mod') { $pluginname = $name; // eg. 'forum' if (get_string_manager()->string_exists('modulename', $component)) { $strpluginname = get_string('modulename', $component); } else { $strpluginname = $component; } } else { $pluginname = $component; if (get_string_manager()->string_exists('pluginname', $component)) { $strpluginname = get_string('pluginname', $component); } else { $strpluginname = $component; } } echo $OUTPUT->heading($pluginname); // Delete all tag instances associated with this plugin. require_once $CFG->dirroot . '/tag/lib.php'; tag_delete_instances($component); // Custom plugin uninstall. $plugindirectory = core_component::get_plugin_directory($type, $name); $uninstalllib = $plugindirectory . '/db/uninstall.php'; if (file_exists($uninstalllib)) { require_once $uninstalllib; $uninstallfunction = 'xmldb_' . $pluginname . '_uninstall'; // eg. 'xmldb_workshop_uninstall()' if (function_exists($uninstallfunction)) { // Do not verify result, let plugin complain if necessary. $uninstallfunction(); } } // Specific plugin type cleanup. $plugininfo = core_plugin_manager::instance()->get_plugin_info($component); if ($plugininfo) { $plugininfo->uninstall_cleanup(); core_plugin_manager::reset_caches(); } $plugininfo = null; // perform clean-up task common for all the plugin/subplugin types //delete the web service functions and pre-built services require_once $CFG->dirroot . '/lib/externallib.php'; external_delete_descriptions($component); // delete calendar events $DB->delete_records('event', array('modulename' => $pluginname)); // Delete scheduled tasks. $DB->delete_records('task_scheduled', array('component' => $pluginname)); // Delete Inbound Message datakeys. $DB->delete_records_select('messageinbound_datakeys', 'handler IN (SELECT id FROM {messageinbound_handlers} WHERE component = ?)', array($pluginname)); // Delete Inbound Message handlers. $DB->delete_records('messageinbound_handlers', array('component' => $pluginname)); // delete all the logs $DB->delete_records('log', array('module' => $pluginname)); // delete log_display information $DB->delete_records('log_display', array('component' => $component)); // delete the module configuration records unset_all_config_for_plugin($component); if ($type === 'mod') { unset_all_config_for_plugin($pluginname); } // delete message provider message_provider_uninstall($component); // delete the plugin tables $xmldbfilepath = $plugindirectory . '/db/install.xml'; drop_plugin_tables($component, $xmldbfilepath, false); if ($type === 'mod' or $type === 'block') { // non-frankenstyle table prefixes drop_plugin_tables($name, $xmldbfilepath, false); } // delete the capabilities that were defined by this module capabilities_cleanup($component); // remove event handlers and dequeue pending events events_uninstall($component); // Delete all remaining files in the filepool owned by the component. $fs = get_file_storage(); $fs->delete_component_files($component); // Finally purge all caches. purge_all_caches(); // Invalidate the hash used for upgrade detections. set_config('allversionshash', ''); echo $OUTPUT->notification(get_string('success'), 'notifysuccess'); }
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 subplugin types. $expected = array('mod' => "{$CFG->dirroot}/mod", 'editor' => "{$CFG->dirroot}/lib/editor", 'tool' => "{$CFG->dirroot}/{$CFG->admin}/tool", 'local' => "{$CFG->dirroot}/local"); $this->assertSame($expected, $types); }
/** * Returns list of plugins that define their subplugins and the information * about them from the db/subplugins.php file. * * @return array with keys like 'mod_quiz', and values the data from the * corresponding db/subplugins.php file. */ public function get_subplugins() { if (is_array($this->subpluginsinfo)) { return $this->subpluginsinfo; } $plugintypes = core_component::get_plugin_types(); $this->subpluginsinfo = array(); foreach (core_component::get_plugin_types_with_subplugins() as $type => $ignored) { foreach (core_component::get_plugin_list($type) as $plugin => $componentdir) { $component = $type . '_' . $plugin; $subplugins = core_component::get_subplugins($component); if (!$subplugins) { continue; } $this->subpluginsinfo[$component] = array(); foreach ($subplugins as $subplugintype => $ignored) { $subplugin = new stdClass(); $subplugin->type = $subplugintype; $subplugin->typerootdir = $plugintypes[$subplugintype]; $this->subpluginsinfo[$component][$subplugintype] = $subplugin; } } } return $this->subpluginsinfo; }
/** * Returns list of plugins that define their subplugins and the information * about them from the db/subplugins.php file. * * @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. */ public function get_subplugins($disablecache=false) { if ($disablecache or is_null($this->subpluginsinfo)) { $this->subpluginsinfo = array(); 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(); include($ownerdir . '/db/subplugins.php'); foreach ($subplugins as $subplugintype => $subplugintyperootdir) { $subplugin = new stdClass(); $subplugin->type = $subplugintype; $subplugin->typerootdir = $subplugintyperootdir; $componentsubplugins[$subplugintype] = $subplugin; } $this->subpluginsinfo[$type . '_' . $component] = $componentsubplugins; } } } } return $this->subpluginsinfo; }