summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/install.core.inc3
-rw-r--r--includes/install.inc25
-rw-r--r--includes/module.inc80
-rw-r--r--modules/node/node.module11
-rw-r--r--modules/rdf/rdf.install5
-rw-r--r--modules/shortcut/shortcut.install9
-rw-r--r--modules/simpletest/tests/module.test40
-rw-r--r--modules/simpletest/tests/module_test.install43
-rw-r--r--modules/system/system.module2
9 files changed, 144 insertions, 74 deletions
diff --git a/includes/install.core.inc b/includes/install.core.inc
index 8fcb5ca71..7c4bc1057 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -1493,8 +1493,7 @@ function install_finished(&$install_state) {
* Batch callback for batch installation of modules.
*/
function _install_module_batch($module, $module_name, &$context) {
- _drupal_install_module($module);
- // We enable the installed module right away, so that the module will be
+ // Install and enable the module right away, so that the module will be
// loaded by drupal_bootstrap in subsequent batch requests, and other
// modules possibly depending on it can safely perform their installation
// steps.
diff --git a/includes/install.inc b/includes/install.inc
index c3e0536c3..17225f562 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -542,31 +542,6 @@ function drupal_verify_profile($install_state) {
}
/**
- * Callback to install an individual install profile module.
- *
- * Used during installation to install modules one at a time and then
- * enable them, or to install a number of modules at one time
- * from admin/modules.
- *
- * @param $module
- * The machine name of the module to install.
- * @return
- * TRUE if the module got installed.
- */
-function _drupal_install_module($module) {
- if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
- drupal_load('module', $module);
- drupal_install_schema($module);
- // Now allow the module to perform install tasks.
- module_invoke($module, 'install');
- $versions = drupal_get_schema_versions($module);
- drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED);
- system_list_reset();
- return TRUE;
- }
-}
-
-/**
* Manually include all files for the active database.
*
* Because we have no registry yet, we need to manually include the
diff --git a/includes/module.inc b/includes/module.inc
index 313f71253..f5f66d7e9 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -336,63 +336,69 @@ function module_enable($module_list, $enable_dependencies = TRUE, $disable_modul
$module_list = array_keys($module_list);
}
- $invoke_modules = array();
-
- // Required for _drupal_install_module().
+ // Required for module installation checks.
include_once DRUPAL_ROOT . '/includes/install.inc';
- // Try to install the enabled modules and collect which were installed.
- // $module_list is not changed and already installed modules are ignored.
- $modules_installed = array_filter($module_list, '_drupal_install_module');
+
+ $modules_installed = array();
+ $modules_enabled = array();
foreach ($module_list as $module) {
+ // Only process modules that are not already enabled.
$existing = db_query("SELECT status FROM {system} WHERE type = :type AND name = :name", array(
':type' => 'module',
':name' => $module))
->fetchObject();
if ($existing->status == 0) {
+ // Load the module's code.
+ drupal_load('module', $module);
module_load_install($module);
+
+ // Update the database and module list to reflect the new module. This
+ // needs to be done first so that the module's hook implementations,
+ // hook_schema() in particular, can be called while it is being
+ // installed.
db_update('system')
->fields(array('status' => 1))
->condition('type', 'module')
->condition('name', $module)
->execute();
- drupal_load('module', $module);
- $invoke_modules[] = $module;
- watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
- }
- }
+ // Refresh the module list to include it.
+ system_list_reset();
+ module_list(TRUE);
+ module_implements('', FALSE, TRUE);
+ _system_update_bootstrap_status();
+ // Update the registry to include it.
+ registry_update();
+ // Refresh the schema to include it.
+ drupal_get_schema(NULL, TRUE);
+
+ // Now install the module if necessary.
+ if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
+ drupal_install_schema($module);
+ // Allow the module to perform install tasks.
+ module_invoke($module, 'install');
+ $versions = drupal_get_schema_versions($module);
+ drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED);
+ // Record the fact that it was installed.
+ $modules_installed[] = $module;
+ }
- if (!empty($invoke_modules)) {
- // Refresh the module list to exclude the disabled modules.
- system_list_reset();
- module_list(TRUE);
- module_implements('', FALSE, TRUE);
- // Update the registry to include the new enabled module.
- registry_update();
- // Refresh the schema to include the new enabled module.
- drupal_get_schema(NULL, TRUE);
+ // Enable the module.
+ module_invoke($module, 'enable');
- // If any modules were newly installed, execute the hook for them.
- if (!$disable_modules_installed_hook && !empty($modules_installed)) {
- module_invoke_all('modules_installed', $modules_installed);
+ // Record the fact that it was enabled.
+ $modules_enabled[] = $module;
+ watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
}
- _system_update_bootstrap_status();
}
- foreach ($invoke_modules as $module) {
- module_invoke($module, 'enable');
- // Check if node_access table needs rebuilding.
- // We check for the existence of node_access_needs_rebuild() since
- // at install time, module_enable() could be called while node.module
- // is not enabled yet.
- if (function_exists('node_access_needs_rebuild') && !node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
- node_access_needs_rebuild(TRUE);
- }
+ // If any modules were newly installed, invoke hook_modules_installed().
+ if (!$disable_modules_installed_hook && !empty($modules_installed)) {
+ module_invoke_all('modules_installed', $modules_installed);
}
- if (!empty($invoke_modules)) {
- // Invoke hook_modules_enabled after all the modules have been
- // enabled.
- module_invoke_all('modules_enabled', $invoke_modules);
+ // If any modules were newly enabled, invoke hook_modules_enabled().
+ if (!empty($modules_enabled)) {
+ module_invoke_all('modules_enabled', $modules_enabled);
}
return TRUE;
diff --git a/modules/node/node.module b/modules/node/node.module
index 9e6b76045..36cc76dcd 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -3536,6 +3536,17 @@ function node_requirements($phase) {
}
/**
+ * Implements hook_modules_enabled().
+ */
+function node_modules_enabled($modules) {
+ // Check if any of the newly enabled modules require the node_access table to
+ // be rebuilt.
+ if (!node_access_needs_rebuild() && array_intersect($modules, module_implements('node_grants'))) {
+ node_access_needs_rebuild(TRUE);
+ }
+}
+
+/**
* Controller class for nodes.
*
* This extends the DrupalDefaultEntityController class, adding required
diff --git a/modules/rdf/rdf.install b/modules/rdf/rdf.install
index ec553fcda..905c24771 100644
--- a/modules/rdf/rdf.install
+++ b/modules/rdf/rdf.install
@@ -43,8 +43,9 @@ function rdf_schema() {
* Implements hook_install().
*/
function rdf_install() {
- // The installer does not trigger hook_modules_installed(), so it needs to be
- // triggered manually for modules defining RDF mappings.
+ // Collect any RDF mappings that were declared by modules installed before
+ // this one.
$modules = module_implements('rdf_mapping');
rdf_modules_installed($modules);
}
+
diff --git a/modules/shortcut/shortcut.install b/modules/shortcut/shortcut.install
index 634ee51fb..5c49322ee 100644
--- a/modules/shortcut/shortcut.install
+++ b/modules/shortcut/shortcut.install
@@ -7,14 +7,9 @@
*/
/**
- * Implements hook_enable().
+ * Implements hook_install().
*/
-function shortcut_enable() {
- if (shortcut_set_load(SHORTCUT_DEFAULT_SET_NAME)) {
- // Quit out; this module has already been installed before.
- return;
- }
-
+function shortcut_install() {
$t = get_t();
// Create an initial default shortcut set.
$shortcut_set = new StdClass();
diff --git a/modules/simpletest/tests/module.test b/modules/simpletest/tests/module.test
index 242910c7f..31c0bb028 100644
--- a/modules/simpletest/tests/module.test
+++ b/modules/simpletest/tests/module.test
@@ -126,13 +126,50 @@ class ModuleUnitTest extends DrupalWebTestCase {
}
/**
+ * Unit tests for module installation.
+ */
+class ModuleInstallTestCase extends DrupalWebTestCase {
+ public static function getInfo() {
+ return array(
+ 'name' => 'Module installation',
+ 'description' => 'Tests the installation of modules.',
+ 'group' => 'Module',
+ );
+ }
+
+ function setUp() {
+ parent::setUp('module_test');
+ }
+
+ /**
+ * Test that calls to drupal_write_record() work during module installation.
+ *
+ * This is a useful function to test because modules often use it to insert
+ * initial data in their database tables when they are being installed or
+ * enabled. Furthermore, drupal_write_record() relies on the module schema
+ * information being available, so this also checks that the data from one of
+ * the module's hook implementations, in particular hook_schema(), is
+ * properly available during this time. Therefore, this test helps ensure
+ * that modules are fully functional while Drupal is installing and enabling
+ * them.
+ */
+ function testDrupalWriteRecord() {
+ // Check for data that was inserted using drupal_write_record() while the
+ // 'module_test' module was being installed and enabled.
+ $data = db_query("SELECT data FROM {module_test}")->fetchCol();
+ $this->assertTrue(in_array('Data inserted in hook_install()', $data), t('Data inserted using drupal_write_record() in hook_install() is correctly saved.'));
+ $this->assertTrue(in_array('Data inserted in hook_enable()', $data), t('Data inserted using drupal_write_record() in hook_enable() is correctly saved.'));
+ }
+}
+
+/**
* Unit tests for module uninstallation and related hooks.
*/
class ModuleUninstallTestCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Module uninstallation',
- 'description' => 'Checks module uninstallation',
+ 'description' => 'Tests the uninstallation of modules.',
'group' => 'Module',
);
}
@@ -147,6 +184,7 @@ class ModuleUninstallTestCase extends DrupalWebTestCase {
function testUserPermsUninstalled() {
// Uninstalls the module_test module, so hook_modules_uninstalled()
// is executed.
+ module_disable(array('module_test'));
drupal_uninstall_modules(array('module_test'));
// Are the perms defined by module_test removed from {role_permission}.
diff --git a/modules/simpletest/tests/module_test.install b/modules/simpletest/tests/module_test.install
new file mode 100644
index 000000000..5f8e76b70
--- /dev/null
+++ b/modules/simpletest/tests/module_test.install
@@ -0,0 +1,43 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Install, update and uninstall functions for the module_test module.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+function module_test_schema() {
+ $schema['module_test'] = array(
+ 'description' => 'Dummy table to test the behavior of hook_schema() during module installation.',
+ 'fields' => array(
+ 'data' => array(
+ 'type' => 'varchar',
+ 'length' => 255,
+ 'not null' => TRUE,
+ 'default' => '',
+ 'description' => 'An example data column for the module.',
+ ),
+ ),
+ );
+ return $schema;
+}
+
+/**
+ * Implements hook_install().
+ */
+function module_test_install() {
+ $record = array('data' => 'Data inserted in hook_install()');
+ drupal_write_record('module_test', $record);
+}
+
+/**
+ * Implements hook_enable().
+ */
+function module_test_enable() {
+ $record = array('data' => 'Data inserted in hook_enable()');
+ drupal_write_record('module_test', $record);
+}
+
diff --git a/modules/system/system.module b/modules/system/system.module
index 18ada5af7..f598fc590 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -2226,6 +2226,8 @@ function _system_update_bootstrap_status() {
$query->condition('name', $bootstrap_modules, 'NOT IN');
}
$query->execute();
+ // Reset the cached list of bootstrap modules.
+ system_list_reset();
}
/**