MDL-6786 Improved dropping of block and module tables during uninstall; merged from MOODLE_19_STABLE
This commit is contained in:
+3
-19
@@ -100,25 +100,9 @@
|
||||
notify("Error occurred while deleting the $strblockname record from blocks table");
|
||||
}
|
||||
|
||||
// Then the tables themselves
|
||||
if ($tables = $db->Metatables()) {
|
||||
$prefix = $CFG->prefix.$block->name;
|
||||
$prefix2 = $CFG->prefix.'block_'.$block->name;
|
||||
foreach ($tables as $table) {
|
||||
if (strpos($table, $prefix) === 0 || strpos($table, $prefix2) === 0) {
|
||||
/// If the match has been due to the 1st condition, debug to developers
|
||||
if (strpos($table, $prefix) === 0) {
|
||||
debugging('This block has some wrongly named tables. See Moodle Docs coding guidelines (and MDL-6786)', DEBUG_DEVELOPER);
|
||||
}
|
||||
/// Strip prefix from $table
|
||||
$table = preg_replace("/^{$CFG->prefix}/", '', $table);
|
||||
$xmldb_table = new XMLDBTable($table);
|
||||
if (!drop_table($xmldb_table, true, false)) {
|
||||
notify("ERROR: while trying to drop table $table");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
drop_plugin_tables($block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false); // old obsoleted table names
|
||||
drop_plugin_tables('block_'.$block->name, "$CFG->dirroot/blocks/$block->name/db/install.xml", false);
|
||||
|
||||
// Delete the capabilities that were defined by this block
|
||||
capabilities_cleanup('block/'.$block->name);
|
||||
|
||||
|
||||
+2
-10
@@ -5,6 +5,7 @@
|
||||
require_once('../course/lib.php');
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->libdir.'/tablelib.php');
|
||||
require_once($CFG->libdir.'/ddllib.php');
|
||||
|
||||
// defines
|
||||
define('MODULE_TABLE','module_administration_table');
|
||||
@@ -139,17 +140,8 @@
|
||||
}
|
||||
|
||||
// Then the tables themselves
|
||||
drop_plugin_tables($module->name, "$CFG->dirroot/mod/$module->name/db/install.xml", false);
|
||||
|
||||
if ($tables = $db->Metatables()) {
|
||||
$prefix = $CFG->prefix.$module->name;
|
||||
foreach ($tables as $table) {
|
||||
if (strpos($table, $prefix) === 0) {
|
||||
if (!execute_sql("DROP TABLE $table", false)) {
|
||||
notify("ERROR: while trying to drop table $table");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Delete the capabilities that were defined by this module
|
||||
capabilities_cleanup('mod/'.$module->name);
|
||||
|
||||
|
||||
@@ -70,111 +70,17 @@ class get_db_directories extends XMLDBAction {
|
||||
if (!isset($XMLDB->dbdirs)) {
|
||||
$XMLDB->dbdirs = array();
|
||||
}
|
||||
/// First, the main one (lib/db)
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->libdir . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
|
||||
/// Now, activity modules (mod/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('mod')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/mod/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, assignment submodules (mod/assignment/type/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('mod/assignment/type')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/mod/assignment/type/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, question types (question/type/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('question/type')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/question/type/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, backup/restore stuff (backup/db)
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/backup/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
|
||||
/// Now, block system stuff (blocks/db)
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/blocks/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
|
||||
/// Now, blocks (blocks/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('blocks', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/blocks/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, course formats (course/format/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('course/format', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/course/format/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, enrolment plugins (enrol/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('enrol', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/enrol/' . $plugin . '/db';
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Local database changes, if the local folder exists.
|
||||
if (file_exists($CFG->dirroot . '/local')) {
|
||||
/// get list of all dirs and create objects with status
|
||||
$db_direcotries = get_db_directories();
|
||||
foreach ($db_direcotries as $path) {
|
||||
$dbdir = new stdClass;
|
||||
$dbdir->path = $CFG->dirroot . '/local/db';
|
||||
$dbdir->path = $path;
|
||||
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
|
||||
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
|
||||
}
|
||||
}
|
||||
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
|
||||
}
|
||||
}
|
||||
|
||||
/// Sort by key
|
||||
ksort($XMLDB->dbdirs);
|
||||
|
||||
+187
@@ -635,6 +635,193 @@ function install_from_xmldb_file($file) {
|
||||
return execute_sql_arr($sqlarr);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will all tables found in XMLDB file from db
|
||||
*
|
||||
* @uses $CFG, $db
|
||||
* @param $file full path to the XML file to be used
|
||||
* @param $feedback
|
||||
* @return boolean (true on success, false on error)
|
||||
*/
|
||||
function delete_tables_from_xmldb_file($file, $feedback=true ) {
|
||||
|
||||
global $CFG, $db;
|
||||
|
||||
$status = true;
|
||||
|
||||
|
||||
$xmldb_file = new XMLDBFile($file);
|
||||
|
||||
if (!$xmldb_file->fileExists()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$loaded = $xmldb_file->loadXMLStructure();
|
||||
$structure =& $xmldb_file->getStructure();
|
||||
|
||||
if (!$loaded || !$xmldb_file->isLoaded()) {
|
||||
/// Show info about the error if we can find it
|
||||
if ($feedback and $structure) {
|
||||
if ($errors = $structure->getAllErrors()) {
|
||||
notify('Errors found in XMLDB file: '. implode (', ', $errors));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($tables = $structure->getTables()) {
|
||||
foreach($tables as $table) {
|
||||
if (table_exists($table)) {
|
||||
drop_table($table, true, $feedback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all plugin tables
|
||||
* @name string name of plugin, used as table prefix
|
||||
* @file string path to install.xml file
|
||||
* @feedback boolean
|
||||
*/
|
||||
function drop_plugin_tables($name, $file, $feedback=true) {
|
||||
global $CFG, $db;
|
||||
|
||||
// first try normal delete
|
||||
if (delete_tables_from_xmldb_file($file, $feedback)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// then try to find all tables that start with name and are not in any xml file
|
||||
$used_tables = get_used_table_names();
|
||||
|
||||
$tables = $db->MetaTables();
|
||||
/// Iterate over, fixing id fields as necessary
|
||||
foreach ($tables as $table) {
|
||||
if (strlen($CFG->prefix)) {
|
||||
if (strpos($table, $CFG->prefix) !== 0) {
|
||||
continue;
|
||||
}
|
||||
$table = substr($table, strlen($CFG->prefix));
|
||||
}
|
||||
$table = strtolower($table);
|
||||
if (strpos($table, $name) !== 0) {
|
||||
continue;
|
||||
}
|
||||
if (in_array($table, $used_tables)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// found orphan table --> delete it
|
||||
$table = new XMLDBTable($table);
|
||||
if (table_exists($table)) {
|
||||
drop_table($table, true, $feedback);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns names of all known tables == tables that moodle knowns about.
|
||||
* @return array of lowercase table names
|
||||
*/
|
||||
function get_used_table_names() {
|
||||
$table_names = array();
|
||||
$dbdirs = get_db_directories();
|
||||
|
||||
foreach ($dbdirs as $dbdir) {
|
||||
$file = $dbdir.'/install.xml';
|
||||
|
||||
$xmldb_file = new XMLDBFile($file);
|
||||
|
||||
if (!$xmldb_file->fileExists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$loaded = $xmldb_file->loadXMLStructure();
|
||||
$structure =& $xmldb_file->getStructure();
|
||||
|
||||
if ($loaded and $tables = $structure->getTables()) {
|
||||
foreach($tables as $table) {
|
||||
$table_names[] = strtolower($table->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $table_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all directories where we expect install.xml files
|
||||
* @return array of paths
|
||||
*/
|
||||
function get_db_directories() {
|
||||
global $CFG;
|
||||
|
||||
$dbdirs = array();
|
||||
|
||||
/// First, the main one (lib/db)
|
||||
$dbdirs[] = $CFG->libdir.'/db';
|
||||
|
||||
/// Now, activity modules (mod/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('mod')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/mod/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, assignment submodules (mod/assignment/type/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('mod/assignment/type')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/mod/assignment/type/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, question types (question/type/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('question/type')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/question/type/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, backup/restore stuff (backup/db)
|
||||
$dbdirs[] = $CFG->dirroot.'/backup/db';
|
||||
|
||||
/// Now, block system stuff (blocks/db)
|
||||
$dbdirs[] = $CFG->dirroot.'/blocks/db';
|
||||
|
||||
/// Now, blocks (blocks/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('blocks', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/blocks/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, course formats (course/format/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('course/format', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/course/format/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Now, enrolment plugins (enrol/xxx/db)
|
||||
if ($plugins = get_list_of_plugins('enrol', 'db')) {
|
||||
foreach ($plugins as $plugin) {
|
||||
$dbdirs[] = $CFG->dirroot.'/enrol/'.$plugin.'/db';
|
||||
}
|
||||
}
|
||||
|
||||
/// Local database changes, if the local folder exists.
|
||||
if (file_exists($CFG->dirroot . '/local')) {
|
||||
$dbdirs[] = $CFG->dirroot.'/local/db';
|
||||
}
|
||||
|
||||
return $dbdirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will create the table passed as argument with all its
|
||||
* fields/keys/indexes/sequences, everything based in the XMLDB object
|
||||
|
||||
Reference in New Issue
Block a user