summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorSteven Wittens <steven@10.no-reply.drupal.org>2006-08-03 01:02:51 +0000
committerSteven Wittens <steven@10.no-reply.drupal.org>2006-08-03 01:02:51 +0000
commit38e4c1ae91545d0c45885966cad694660010068d (patch)
tree8edc167d1723e2f9ec3033779007fbc13a8adbe2 /includes
parent8b820834e5c7ee12668c8f3a172dabc3af0455ba (diff)
downloadbrdo-38e4c1ae91545d0c45885966cad694660010068d.tar.gz
brdo-38e4c1ae91545d0c45885966cad694660010068d.tar.bz2
#76209: (Eaton et al)
- Make installer code integrate better with module.inc / system.module - Fix schema version bug when installing core
Diffstat (limited to 'includes')
-rw-r--r--includes/bootstrap.inc7
-rw-r--r--includes/install.inc117
-rw-r--r--includes/module.inc92
3 files changed, 157 insertions, 59 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 826818a55..fd4f7bd54 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -192,11 +192,14 @@ function conf_init() {
* @param $filename
* The filename of the item if it is to be set explicitly rather
* than by consulting the database.
+ * @param $check_db
+ * Allows the database search to be skipped (useful for pre-bootstrap
+ * checks where configuration paths must still be respected).
*
* @return
* The filename of the requested item.
*/
-function drupal_get_filename($type, $name, $filename = NULL) {
+function drupal_get_filename($type, $name, $filename = NULL, $check_db = TRUE) {
static $files = array();
if (!isset($files[$type])) {
@@ -209,7 +212,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
elseif (isset($files[$type][$name])) {
// nothing
}
- elseif (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file)) {
+ elseif ($check_db && (($file = db_result(db_query("SELECT filename FROM {system} WHERE name = '%s' AND type = '%s'", $name, $type))) && file_exists($file))) {
$files[$type][$name] = $file;
}
else {
diff --git a/includes/install.inc b/includes/install.inc
index d3aa86a4f..68593e86f 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -24,10 +24,7 @@ define('FILE_NOT_EXECUTABLE', 128);
*/
function drupal_load_updates() {
foreach (module_list() as $module) {
- $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install';
- if (is_file($install_file)) {
- include_once $install_file;
- }
+ module_load_install($module);
}
}
@@ -252,14 +249,14 @@ function drupal_get_install_files($module_list = array()) {
}
/**
- * Install a profile.
+ * Verify a profile for installation.
*
* @param profile
- * Name of profile to install.
+ * Name of profile to verify.
+ * @return
+ * The list of modules to install.
*/
-function drupal_install_profile($profile) {
- global $db_type;
-
+function drupal_verify_profile($profile) {
include_once './includes/file.inc';
$profile_file = "./profiles/$profile.profile";
@@ -270,75 +267,84 @@ function drupal_install_profile($profile) {
require_once($profile_file);
- // Get a list of modules absolutely required by Drupal.
- $bootstrap_list = array('system');
-
// Get a list of modules required by this profile.
$function = $profile .'_profile_modules';
- $module_list = $function();
-
- // If anyone has added modules that we automatically install, filter them out.
- $module_list = array_diff($module_list, $bootstrap_list);
-
+ $module_list = array_merge(array('system'), $function());
+
// Verify that all required modules exist.
- $bootstrap_modules = drupal_find_modules($bootstrap_list);
- $profile_modules = drupal_find_modules($module_list);
+ $modules_present = TRUE;
+ foreach ($module_list as $module) {
+ $module_path = dirname(drupal_get_filename('module', $module, NULL, FALSE));
+ if (!$module_path) {
+ drupal_set_message(st('The %module module is required but was not found. Please move it into the <em>modules</em> subdirectory.', array('%module' => $module)), 'error');
+ $modules_present = FALSE;
+ }
+ }
+
+ return $modules_present ? $module_list : NULL;
+}
- // Install the essential system modules and bootstrap Drupal.
- drupal_install_modules($bootstrap_list);
+/**
+ * Install a profile (i.e. a set of modules) from scratch.
+ * The profile must be verified first using drupal_verify_profile().
+ *
+ * @param profile
+ * The name of the profile to install.
+ * @param module_list
+ * An array of modules to install.
+ */
+function drupal_install_profile($profile, $module_list) {
+ // The system module is a special case; we can't bootstrap until it's
+ // installed, so we can't use the normal installation function.
+ $module_list = array_diff($module_list, array('system'));
+
+ $system_path = dirname(drupal_get_filename('module', 'system', NULL, FALSE));
+ require_once './' . $system_path . '/system.install';
+ module_invoke('system', 'install');
+ $system_versions = drupal_get_schema_versions('system');
+ $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED;
+ db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', 'module', '', 1, 0, 0, %d)", $system_path . '/system.module', 'system', $system_version);
+
+ // Now that we've installed things properly, bootstrap the full Drupal environment
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
// Install schemas for profile and all its modules.
+ module_rebuild_cache();
+ drupal_install_modules($module_list);
+
+ // And now, run the profile's install function.
$function = $profile .'_install';
if (function_exists($function)) {
$function();
}
-
- drupal_install_modules($module_list);
-
- // Enable the modules required by the profile.
- db_query("DELETE FROM {system} WHERE type = 'module'");
- $modules = array_merge($bootstrap_modules, $profile_modules);
- foreach ($modules as $module) {
- db_query("INSERT INTO {system} (filename, name, type, description, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', 'module', '', 1, 0, 0, 0)", $module->filename, $module->name);
- }
}
/**
- * Finds the file paths for a set of modules.
+ * Execute the install scripts for a set of modules.
*
* @param module_list
- * The modules to locate.
- * @return
- * An array containing file information for the modules.
+ * The modules to install.
*/
-function drupal_find_modules($module_list = array()) {
- $modules = array();
- foreach ($module_list as $current) {
- $module = file_scan_directory('./modules', "^$current.module$", array('.', '..', 'CVS'), 0, TRUE, 'name', 0);
- if (empty($module)) {
- drupal_set_message(st('The %module module is required but was not found. Please move the file %file into the <em>modules</em> subdirectory.', array('%module' => $current, '%file' => $current .'.module')), 'error');
- }
- else {
- $modules = array_merge($modules, $module);
- }
+function drupal_install_modules($module_list = array()) {
+ foreach ($module_list as $module) {
+ drupal_install_module($module);
}
- return $modules;
}
/**
- * Execute the install scripts for a set of modules.
+ * Calls the install function and updates the system table for a given module.
*
- * @param module_list
- * The modules to install.
+ * @param module
+ * The module to install.
*/
-function drupal_install_modules($module_list = array()) {
- // Get a list of all .install files.
- $installs = drupal_get_install_files($module_list);
- foreach ($installs as $install) {
- require_once $install->filename;
- module_invoke($install->name, 'install');
+function drupal_install_module($module) {
+ if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) {
+ module_load_install($module);
+ module_invoke($module, 'install');
+ $versions = drupal_get_schema_versions($module);
+ drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED);
+ module_enable($module);
}
}
@@ -349,9 +355,6 @@ function drupal_install_modules($module_list = array()) {
* The file to check for.
* @param $mask
* An optional bitmask created from various FILE_* constants.
- * @param $message_type
- * The type of message to create, can be error or status. Passed on to drupal_set_message as second parameter.
- * Set to NULL to not output any messages at all.
* @param $type
* The type of file. Can be file (default), dir, or link.
* @return
diff --git a/includes/module.inc b/includes/module.inc
index 5a05283b6..b4136aaa3 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -88,6 +88,47 @@ function module_list($refresh = FALSE, $bootstrap = TRUE, $sort = FALSE, $fixed_
}
/**
+ * Rebuild the database cache of module files.
+ *
+ * @return
+ * The array of filesystem objects used to rebuild the cache.
+ */
+function module_rebuild_cache() {
+ // Get current list of modules
+ $files = system_listing('\.module$', 'modules', 'name', 0);
+
+ // Extract current files from database.
+ system_get_files_database($files, 'module');
+
+ ksort($files);
+
+ foreach ($files as $filename => $file) {
+ drupal_get_filename('module', $file->name, $file->filename);
+ drupal_load('module', $file->name);
+
+ // log the critical hooks implemented by this module
+ $bootstrap = 0;
+ foreach (bootstrap_hooks() as $hook) {
+ if (module_hook($file->name, $hook)) {
+ $bootstrap = 1;
+ break;
+ }
+ }
+
+ // Update the contents of the system table:
+ if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) {
+ db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->description, $file->name, $file->filename, $bootstrap, $file->old_filename);
+ }
+ else {
+ // This is a new module.
+ db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->description, 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
+ }
+ }
+
+ return $files;
+}
+
+/**
* Determine whether a given module exists.
*
* @param $module
@@ -101,6 +142,57 @@ function module_exist($module) {
}
/**
+ * Load a module's installation hooks.
+ */
+function module_load_install($module) {
+ // Make sure the installation API is available
+ include_once './includes/install.inc';
+
+ $install_file = './'. drupal_get_path('module', $module) .'/'. $module .'.install';
+ if (is_file($install_file)) {
+ include_once $install_file;
+ }
+}
+
+/**
+ * Enable a given module.
+ *
+ * @param $module
+ * Enable a given module and call its enable hook.
+ */
+function module_enable($module) {
+ $existing = db_fetch_object(db_query("SELECT name, status FROM {system} WHERE type = 'module' AND name = '%s'", $module));
+ if ($existing->status === '0') {
+ module_load_install($module);
+ db_query("UPDATE {system} SET status = 1, throttle = 0 WHERE type = 'module' AND name = '%s'", $module);
+ drupal_load('module', $module);
+ module_invoke($module, 'enable');
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+/**
+ * Disable a given module and call its disable hook.
+ *
+ * @param $module
+ * The name of the module (without the .module extension).
+ */
+function module_disable($module) {
+ if (module_exist($module)) {
+ module_load_install($module);
+ module_invoke($module, 'disable');
+ db_query("UPDATE {system} SET status = 0, throttle = 0 WHERE type = 'module' AND name = '%s'", $module);
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+/**
* @defgroup hooks Hooks
* @{
* Allow modules to interact with the Drupal core.