diff options
author | Angie Byron <webchick@24967.no-reply.drupal.org> | 2010-11-20 03:34:30 +0000 |
---|---|---|
committer | Angie Byron <webchick@24967.no-reply.drupal.org> | 2010-11-20 03:34:30 +0000 |
commit | aa10522336e69d462176e7505f3cdc00c3cf85d7 (patch) | |
tree | c9e413cfd4e16605957ef12ae8b218e4e47b0de9 /includes/install.inc | |
parent | 2f7600c1c512adcc36bc088d98de392dac102f1e (diff) | |
download | brdo-aa10522336e69d462176e7505f3cdc00c3cf85d7.tar.gz brdo-aa10522336e69d462176e7505f3cdc00c3cf85d7.tar.bz2 |
#151452 by David_Rothstein, Dave Reid, tstoeckler: Fixed uninstalling modules does not follow dependencies.
Diffstat (limited to 'includes/install.inc')
-rw-r--r-- | includes/install.inc | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/includes/install.inc b/includes/install.inc index 3c51dc123..6e0b7dc7b 100644 --- a/includes/install.inc +++ b/includes/install.inc @@ -175,6 +175,9 @@ function drupal_set_installed_schema_version($module, $version) { ->fields(array('schema_version' => $version)) ->condition('name', $module) ->execute(); + + // Reset the static cache of module schema versions. + drupal_get_installed_schema_version(NULL, TRUE); } /** @@ -608,12 +611,53 @@ function drupal_install_system() { } /** - * Calls the uninstall function and updates the system table for a given module. + * Uninstalls a given list of modules. * * @param $module_list * The modules to uninstall. + * @param $uninstall_dependents + * If TRUE, the function will check that all modules which depend on the + * passed-in module list either are already uninstalled or contained in the + * list, and it will ensure that the modules are uninstalled in the correct + * order. This incurs a significant performance cost, so use FALSE if you + * know $module_list is already complete and in the correct order. + * + * @return + * FALSE if one or more dependent modules are missing from the list, TRUE + * otherwise. */ -function drupal_uninstall_modules($module_list = array()) { +function drupal_uninstall_modules($module_list = array(), $uninstall_dependents = TRUE) { + if ($uninstall_dependents) { + // Get all module data so we can find dependents and sort. + $module_data = system_rebuild_module_data(); + // Create an associative array with weights as values. + $module_list = array_flip(array_values($module_list)); + + $profile = drupal_get_profile(); + while (list($module) = each($module_list)) { + if (!isset($module_data[$module]) || drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED) { + // This module doesn't exist or is already uninstalled, skip it. + unset($module_list[$module]); + continue; + } + $module_list[$module] = $module_data[$module]->sort; + + // If the module has any dependents which are not already uninstalled and + // not included in the passed-in list, abort. It is not safe to uninstall + // them automatically because uninstalling a module is a destructive + // operation. + foreach (array_keys($module_data[$module]->required_by) as $dependent) { + if (!isset($module_list[$dependent]) && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED && $dependent != $profile) { + return FALSE; + } + } + } + + // Sort the module list by pre-calculated weights. + asort($module_list); + $module_list = array_keys($module_list); + } + foreach ($module_list as $module) { // First, retrieve all the module's menu paths from db. drupal_load('module', $module); @@ -660,6 +704,8 @@ function drupal_uninstall_modules($module_list = array()) { // Call hook_module_uninstall to let other modules act module_invoke_all('modules_uninstalled', $module_list); } + + return TRUE; } /** |