summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/install.inc73
-rw-r--r--includes/module.inc9
-rw-r--r--modules/simpletest/tests/system_test.module36
-rw-r--r--modules/system/system.admin.inc5
-rw-r--r--modules/system/system.test12
5 files changed, 99 insertions, 36 deletions
diff --git a/includes/install.inc b/includes/install.inc
index c472e1ce1..164002a9c 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -506,7 +506,10 @@ function drupal_install_modules($module_list = array()) {
} while ($moved);
asort($module_list);
$module_list = array_keys($module_list);
- array_filter($module_list, '_drupal_install_module');
+ $modules_installed = array_filter($module_list, '_drupal_install_module');
+ if (!empty($modules_installed)) {
+ module_invoke_all('modules_installed', $modules_installed);
+ }
module_enable($module_list);
}
@@ -574,46 +577,52 @@ function drupal_install_system() {
module_rebuild_cache();
}
-
/**
* Calls the uninstall function and updates the system table for a given module.
*
- * @param $module
- * The machine name of the module to uninstall.
- */
-function drupal_uninstall_module($module) {
- // First, retrieve all the module's menu paths from db.
- drupal_load('module', $module);
- $paths = module_invoke($module, 'menu');
-
- // Uninstall the module(s).
- module_load_install($module);
- module_invoke($module, 'uninstall');
-
- // Now remove the menu links for all paths declared by this module.
- if (!empty($paths)) {
- $paths = array_keys($paths);
- // Clean out the names of load functions.
- foreach ($paths as $index => $path) {
- $parts = explode('/', $path, MENU_MAX_PARTS);
- foreach ($parts as $k => $part) {
- if (preg_match('/^%[a-z_]*$/', $part)) {
- $parts[$k] = '%';
+ * @param $module_list
+ * The modules to uninstall.
+ */
+function drupal_uninstall_modules($module_list = array()) {
+ foreach ($module_list as $module) {
+ // First, retrieve all the module's menu paths from db.
+ drupal_load('module', $module);
+ $paths = module_invoke($module, 'menu');
+
+ // Uninstall the module.
+ module_load_install($module);
+ module_invoke($module, 'uninstall');
+
+ // Now remove the menu links for all paths declared by this module.
+ if (!empty($paths)) {
+ $paths = array_keys($paths);
+ // Clean out the names of load functions.
+ foreach ($paths as $index => $path) {
+ $parts = explode('/', $path, MENU_MAX_PARTS);
+ foreach ($parts as $k => $part) {
+ if (preg_match('/^%[a-z_]*$/', $part)) {
+ $parts[$k] = '%';
+ }
}
+ $paths[$index] = implode('/', $parts);
}
- $paths[$index] = implode('/', $parts);
- }
- $placeholders = implode(', ', array_fill(0, count($paths), "'%s'"));
+ $placeholders = implode(', ', array_fill(0, count($paths), "'%s'"));
- $result = db_query('SELECT * FROM {menu_links} WHERE router_path IN (' . $placeholders . ') AND external = 0 ORDER BY depth DESC', $paths);
- // Remove all such items. Starting from those with the greatest depth will
- // minimize the amount of re-parenting done by menu_link_delete().
- while ($item = db_fetch_array($result)) {
- _menu_delete_item($item, TRUE);
+ $result = db_query('SELECT * FROM {menu_links} WHERE router_path IN (' . $placeholders . ') AND external = 0 ORDER BY depth DESC', $paths);
+ // Remove all such items. Starting from those with the greatest depth will
+ // minimize the amount of re-parenting done by menu_link_delete().
+ while ($item = db_fetch_array($result)) {
+ _menu_delete_item($item, TRUE);
+ }
}
+
+ drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED);
}
- drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED);
+ if (!empty($module_list)) {
+ // Call hook_module_uninstall to let other modules act
+ module_invoke_all('modules_uninstalled', $module_list);
+ }
}
/**
diff --git a/includes/module.inc b/includes/module.inc
index 612754888..835d77db5 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -297,6 +297,12 @@ function module_enable($module_list) {
node_access_needs_rebuild(TRUE);
}
}
+
+ if (!empty($invoke_modules)) {
+ // Invoke the hook_module_enable after all the modules have been
+ // enabled.
+ module_invoke_all('modules_enabled', $invoke_modules);
+ }
}
/**
@@ -322,6 +328,9 @@ function module_disable($module_list) {
}
if (!empty($invoke_modules)) {
+ // Invoke hook_module_disable before disabling modules,
+ // so we can still call module hooks to get information.
+ module_invoke_all('modules_disabled', $invoke_modules);
// Refresh the module list to exclude the disabled modules.
module_list(TRUE, FALSE);
// Force to regenerate the stored list of hook implementations.
diff --git a/modules/simpletest/tests/system_test.module b/modules/simpletest/tests/system_test.module
index d3db9b587..188facc96 100644
--- a/modules/simpletest/tests/system_test.module
+++ b/modules/simpletest/tests/system_test.module
@@ -84,3 +84,39 @@ function system_test_redirect_invalid_scheme() {
function system_test_destination() {
return 'The destination: ' . drupal_get_destination();
}
+
+/**
+ * Implementation of hook_modules_installed().
+ */
+function system_test_modules_installed($modules) {
+ if (in_array('aggregator', $modules)) {
+ drupal_set_message(t('hook_modules_installed fired for aggregator'));
+ }
+}
+
+/**
+ * Implementation of hook_modules_enabled().
+ */
+function system_test_modules_enabled($modules) {
+ if (in_array('aggregator', $modules)) {
+ drupal_set_message(t('hook_modules_enabled fired for aggregator'));
+ }
+}
+
+/**
+ * Implementation of hook_modules_disabled().
+ */
+function system_test_modules_disabled($modules) {
+ if (in_array('aggregator', $modules)) {
+ drupal_set_message(t('hook_modules_disabled fired for aggregator'));
+ }
+}
+
+/**
+ * Implementation of hook_modules_uninstalled().
+ */
+function system_test_modules_uninstalled($modules) {
+ if (in_array('aggregator', $modules)) {
+ drupal_set_message(t('hook_modules_uninstalled fired for aggregator'));
+ }
+}
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index ae11a4557..307653bda 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -1083,9 +1083,8 @@ function system_modules_uninstall_submit($form, &$form_state) {
if (!empty($form['#confirmed'])) {
// Call the uninstall routine for each selected module.
- foreach (array_filter($form_state['values']['uninstall']) as $module => $value) {
- drupal_uninstall_module($module);
- }
+ $modules = array_keys($form_state['values']['uninstall']);
+ drupal_uninstall_modules($modules);
drupal_set_message(t('The selected modules have been uninstalled.'));
unset($form_state['storage']);
diff --git a/modules/system/system.test b/modules/system/system.test
index dbf6c0dbd..8934316ac 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -19,7 +19,7 @@ class EnableDisableCoreTestCase extends DrupalWebTestCase {
* Implementation of setUp().
*/
function setUp() {
- parent::setUp();
+ parent::setUp('system_test');
$this->admin_user = $this->drupalCreateUser(array('access administration pages', 'administer site configuration'));
$this->drupalLogin($this->admin_user);
@@ -28,17 +28,22 @@ class EnableDisableCoreTestCase extends DrupalWebTestCase {
/**
* Enable a module, check the database for related tables, disable module,
* check for related tables, unistall module, check for related tables.
+ * Also check for invocation of the hook_module_action hook.
*/
function testEnableDisable() {
// Enable aggregator, and check tables.
$this->assertModules(array('aggregator'), FALSE);
$this->assertTableCount('aggregator', FALSE);
+ // Install (and enable) aggregator module.
$edit = array();
$edit['modules[Core][aggregator][enable]'] = 'aggregator';
$this->drupalPost('admin/build/modules', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
+ // Check that hook_modules_installed and hook_modules_enabled hooks were invoked and check tables.
+ $this->assertText(t('hook_modules_installed fired for aggregator'), t('hook_modules_installed fired.'));
+ $this->assertText(t('hook_modules_enabled fired for aggregator'), t('hook_modules_enabled fired.'));
$this->assertModules(array('aggregator'), TRUE);
$this->assertTableCount('aggregator', TRUE);
@@ -48,9 +53,12 @@ class EnableDisableCoreTestCase extends DrupalWebTestCase {
$this->drupalPost('admin/build/modules', $edit, t('Save configuration'));
$this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
+ // Check that hook_modules_disabled hook was invoked and check tables.
+ $this->assertText(t('hook_modules_disabled fired for aggregator'), t('hook_modules_disabled fired.'));
$this->assertModules(array('aggregator'), FALSE);
$this->assertTableCount('aggregator', TRUE);
+ // Uninstall the module.
$edit = array();
$edit['uninstall[aggregator]'] = 'aggregator';
$this->drupalPost('admin/build/modules/uninstall', $edit, t('Uninstall'));
@@ -58,6 +66,8 @@ class EnableDisableCoreTestCase extends DrupalWebTestCase {
$this->drupalPost(NULL, NULL, t('Uninstall'));
$this->assertText(t('The selected modules have been uninstalled.'), t('Modules status has been updated.'));
+ // Check that hook_modules_uninstalled hook was invoked and check tables.
+ $this->assertText(t('hook_modules_uninstalled fired for aggregator'), t('hook_modules_uninstalled fired.'));
$this->assertModules(array('aggregator'), FALSE);
$this->assertTableCount('aggregator', FALSE);
}