Index: drupal/install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.53 diff -u -p -r1.53 install.php --- drupal/install.php 22 May 2007 07:42:36 -0000 1.53 +++ drupal/install.php 23 May 2007 21:48:37 -0000 @@ -714,7 +714,6 @@ function install_tasks($profile, $task) // Rebuild menu to get content type links registered by the profile, // and possibly any other menu items created through the tasks. menu_rebuild(); - variable_set('install_profile', $profile); } // Set task for user, and remember the task in the database. Index: drupal/update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.222 diff -u -p -r1.222 update.php --- drupal/update.php 16 May 2007 07:56:19 -0000 1.222 +++ drupal/update.php 23 May 2007 21:48:38 -0000 @@ -200,7 +200,7 @@ function update_fix_schema_version() { db_query('UPDATE {system} SET schema_version = 0 WHERE status = 1'); // Set schema version for core - drupal_set_installed_schema_version('system', $sql_updates[$update_start]); + drupal_set_installed_schema_version('module', 'system', $sql_updates[$update_start]); variable_del('update_start'); } } @@ -216,7 +216,7 @@ function update_fix_schema_version() { function update_fix_sessions() { $ret = array(); - if (drupal_get_installed_schema_version('system') < 130 && !variable_get('update_sessions_fixed', FALSE)) { + if (drupal_get_installed_schema_version('module', 'system') < 130 && !variable_get('update_sessions_fixed', FALSE)) { if ($GLOBALS['db_type'] == 'mysql') { db_query("ALTER TABLE {sessions} ADD cache int(11) NOT NULL default '0' AFTER timestamp"); } @@ -236,7 +236,7 @@ function update_fix_sessions() { * when update 115 is removed. It is part of the Drupal 4.5 to 4.7 migration. */ function update_fix_watchdog_115() { - if (drupal_get_installed_schema_version('system') < 115 && !variable_get('update_watchdog_115_fixed', FALSE)) { + if (drupal_get_installed_schema_version('module', 'system') < 115 && !variable_get('update_watchdog_115_fixed', FALSE)) { if ($GLOBALS['db_type'] == 'mysql') { $ret[] = update_sql("ALTER TABLE {watchdog} ADD severity tinyint(3) unsigned NOT NULL default '0'"); } @@ -259,7 +259,7 @@ function update_fix_watchdog_115() { * when update 142 is removed. It is part of the Drupal 4.6 to 4.7 migration. */ function update_fix_watchdog() { - if (drupal_get_installed_schema_version('system') < 142 && !variable_get('update_watchdog_fixed', FALSE)) { + if (drupal_get_installed_schema_version('module', 'system') < 142 && !variable_get('update_watchdog_fixed', FALSE)) { switch ($GLOBALS['db_type']) { case 'pgsql': $ret = array(); @@ -279,15 +279,24 @@ function update_fix_watchdog() { * Perform one update and store the results which will later be displayed on * the finished page. * - * @param $module - * The module whose update will be run. + * @param $type + * Type of item to be updated, e.g., 'module' or 'profile'. + * @param $name + * The item whose update will be run. * @param $number * The update number to run. * @param $context * The batch conetxt array */ -function update_do_one($module, $number, &$context) { - $function = $module .'_update_'. $number; +function update_do_one($type, $name, $number, &$context) { + switch ($type) { + case 'module': + $function = $name .'_update_'. $number; + break; + default: + $function = $name .'_'. $type .'_update_'. $number; + break; + } if (function_exists($function)) { $ret = $function($context['sandbox']); } @@ -297,20 +306,24 @@ function update_do_one($module, $number, unset($ret['#finished']); } - if (!isset($context['results'][$module])) { - $context['results'][$module] = array(); + if (!isset($context['results'][$type])) { + $context['results'][$type] = array(); } - if (!isset($context['results'][$module][$number])) { - $context['results'][$module][$number] = array(); + if (!isset($context['results'][$type][$name])) { + $context['results'][$type][$name] = array(); } - $context['results'][$module][$number] = array_merge($context['results'][$module][$number], $ret);; + + if (!isset($context['results'][$type][$name][$number])) { + $context['results'][$type][$name][$number] = array(); + } + $context['results'][$type][$name][$number] = array_merge($context['results'][$type][$name][$number], $ret);; if ($context['finished'] == 1) { // Update the installed version - drupal_set_installed_schema_version($module, $number); + drupal_set_installed_schema_version($type, $name, $number); } - $context['message'] = t('Updating @module module', array('@module' => $module)); + $context['message'] = t('Updating @name @type', array('@name' => $name, '@type' => $type)); } function update_selection_page() { @@ -335,28 +348,42 @@ function update_script_selection_form() '#collapsed' => TRUE, ); - // Ensure system.module's updates appear first - $form['start']['system'] = array(); + $items = system_list(); - foreach (module_list() as $module) { - $updates = drupal_get_schema_versions($module); - if ($updates !== FALSE) { - $updates = drupal_map_assoc($updates); - $updates[] = 'No updates available'; - $default = drupal_get_installed_schema_version($module); - foreach (array_keys($updates) as $update) { - if ($update > $default) { - $default = $update; - break; - } + foreach ($items as $item) { + list($type, $name) = $item; + if (!array_key_exists($type, $form['start'])) { + $form['start'][$type] = array( + '#tree' => TRUE, + '#type' => 'fieldset', + '#title' => $type .'updates', + '#collapsible' => TRUE, + '#collapsed' => FALSE, + ); + // Ensure system.module's updates appear first. + if ($type == 'module' && !!array_key_exists('system', $form['start']['module'])) { + $form['start']['module']['system'] = array(); } - $form['start'][$module] = array( - '#type' => 'select', - '#title' => $module .' module', - '#default_value' => $default, - '#options' => $updates, - ); + $updates = drupal_get_schema_versions($type, $name); + if ($updates !== FALSE) { + $updates = drupal_map_assoc($updates); + $updates[] = 'No updates available'; + $default = drupal_get_installed_schema_version($type, $name); + foreach (array_keys($updates) as $update) { + if ($update > $default) { + $default = $update; + break; + } + } + + $form['start'][$type][$name] = array( + '#type' => 'select', + '#title' => $name .' '. $type, + '#default_value' => $default, + '#options' => $updates, + ); + } } } @@ -377,18 +404,21 @@ function update_batch() { $operations = array(); // Set the installed version so updates start at the correct place. - foreach ($_POST['start'] as $module => $version) { - drupal_set_installed_schema_version($module, $version - 1); - $updates = drupal_get_schema_versions($module); - $max_version = max($updates); - if ($version <= $max_version) { - foreach ($updates as $update) { - if ($update >= $version) { - $operations[] = array('update_do_one', array($module, $update)); + foreach ($_POST['start'] as $type => $item) { + foreach ($item as $name => $version) { + drupal_set_installed_schema_version($type, $name, $version - 1); + $updates = drupal_get_schema_versions($type, $name); + $max_version = max($updates); + if ($version <= $max_version) { + foreach ($updates as $update) { + if ($update >= $version) { + $operations[] = array('update_do_one', array($type, $name, $update)); + } } } } } + $batch = array( 'operations' => $operations, 'title' => 'Updating', @@ -424,8 +454,8 @@ function update_results_page() { $output = '

Updates were attempted. If you see no failures below, you may proceed happily to the administration pages. Otherwise, you may need to update your database manually. All errors have been logged.

'; } else { - list($module, $version) = array_pop(reset($_SESSION['updates_remaining'])); - $output = '

The update process was aborted prematurely while running update #'. $version .' in '. $module .'.module. All other errors have been logged. You may need to check the watchdog database table manually.

'; + list($type, $name, $version) = array_pop(reset($_SESSION['updates_remaining'])); + $output = '

The update process was aborted prematurely while running update #'. $version .' in '. $name .'.'. $type .'. All other errors have been logged. You may need to check the watchdog database table manually.

'; } if ($GLOBALS['access_check'] == FALSE) { @@ -438,23 +468,25 @@ function update_results_page() { if (!empty($_SESSION['update_results'])) { $output .= '
'; $output .= '

The following queries were executed

'; - foreach ($_SESSION['update_results'] as $module => $updates) { - $output .= '

'. $module .' module

'; - foreach ($updates as $number => $queries) { - $output .= '

Update #'. $number .'

'; - $output .= ''; } } $output .= '
'; Index: drupal/includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.641 diff -u -p -r1.641 common.inc --- drupal/includes/common.inc 15 May 2007 20:19:47 -0000 1.641 +++ drupal/includes/common.inc 23 May 2007 21:48:44 -0000 @@ -2143,11 +2143,10 @@ function drupal_system_listing($mask, $d // When this function is called during Drupal's initial installation process, // the name of the profile that's about to be installed is stored in the global - // $profile variable. At all other times, the standard Drupal systems variable - // table contains the name of the current profile, and we can call variable_get() - // to determine what one is active. + // $profile variable. At all other times, the system table contains the name of + // of the current profile. if (!isset($profile)) { - $profile = variable_get('install_profile', 'default'); + $profile = system_get_installed_profile(); } $searchdir = array($directory); $files = array(); Index: drupal/includes/install.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/install.inc,v retrieving revision 1.40 diff -u -p -r1.40 install.inc --- drupal/includes/install.inc 21 May 2007 10:56:05 -0000 1.40 +++ drupal/includes/install.inc 23 May 2007 21:48:46 -0000 @@ -19,29 +19,34 @@ define('FILE_NOT_WRITABLE', 64); define('FILE_NOT_EXECUTABLE', 128); /** - * Initialize the update system by loading all installed module's .install files. + * Initialize the update system by loading all installed system items' .install files. */ function drupal_load_updates() { - foreach (module_list() as $module) { - module_load_install($module); + foreach (system_list() as $item) { + system_load_install($item['type'], $item['name']); } } /** - * Returns an array of available schema versions for a module. + * Returns an array of available schema versions for a system item. * - * @param $module - * A module name. + * @param $type + * Type of the item, e.g., 'module' or 'profile'. + * @param $name + * Name of the system item. * @return * If the module has updates, an array of available updates. Otherwise, * FALSE. */ -function drupal_get_schema_versions($module) { +function drupal_get_schema_versions($type, $name) { $updates = array(); $functions = get_defined_functions(); foreach ($functions['user'] as $function) { - if (strpos($function, $module .'_update_') === 0) { - $version = substr($function, strlen($module .'_update_')); + // Module update functions are named modulename_update_x(), while other + // system items' update functions are named, e.g., profilename_profile_update(). + $prefix = (($type == 'module') ? $name : $name .'_'. $type) .'_update_'; + if (strpos($function, $prefix) === 0) { + $version = substr($function, strlen($prefix)); if (is_numeric($version)) { $updates[] = $version; } @@ -54,41 +59,45 @@ function drupal_get_schema_versions($mod } /** - * Returns the currently installed schema version for a module. + * Returns the currently installed schema version for a system item. * - * @param $module - * A module name. + * @param $type + * Type of the item, e.g., 'module' or 'profile'. + * @param $name + * Name of the system item. * @return * The currently installed schema version. */ -function drupal_get_installed_schema_version($module, $reset = FALSE) { +function drupal_get_installed_schema_version($type, $name, $reset = FALSE) { static $versions = array(); if ($reset) { $versions = array(); } - if (!$versions) { - $versions = array(); - $result = db_query("SELECT name, schema_version FROM {system} WHERE type = 'module'"); + if (!isset($versions[$type])) { + $versions[$type] = array(); + $result = db_query("SELECT name, schema_version FROM {system} WHERE type = '%s'", $type); while ($row = db_fetch_object($result)) { - $versions[$row->name] = $row->schema_version; + $versions[$type][$row->name] = $row->schema_version; } } - return $versions[$module]; + return $versions[$type][$name]; } /** - * Update the installed version information for a module. + * Update the installed version information for a system item. * - * @param $module - * A module name. + * @param $type + * Type of the item, e.g., 'module' or 'profile'. + * @param $name + * Name of the system item. * @param $version * The new schema version. */ -function drupal_set_installed_schema_version($module, $version) { - db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s'", $version, $module); +function drupal_set_installed_schema_version($type, $name, $version) { + db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s' AND type = '%s'", $version, $name, $type); } /** @@ -250,6 +259,22 @@ function drupal_get_install_files($modul } /** + * Load a profile's include file. + * + * @param profile + * Name of profile to include. + */ +function drupal_load_profile_install($profile) { + $profile_file = "./profiles/$profile/$profile.profile"; + + if (!isset($profile) || !file_exists($profile_file)) { + install_no_profile_error(); + } + + require_once($profile_file); +} + +/** * Verify a profile for installation. * * @param profile @@ -263,13 +288,7 @@ function drupal_verify_profile($profile, include_once './includes/file.inc'; include_once './includes/common.inc'; - $profile_file = "./profiles/$profile/$profile.profile"; - - if (!isset($profile) || !file_exists($profile_file)) { - install_no_profile_error(); - } - - require_once($profile_file); + drupal_load_profile_install($profile); // Get a list of modules required by this profile. $function = $profile .'_profile_modules'; @@ -310,51 +329,61 @@ function drupal_install_profile($profile $system_path = dirname(drupal_get_filename('module', 'system', NULL)); require_once './'. $system_path .'/system.install'; module_invoke('system', 'install'); - $system_versions = drupal_get_schema_versions('system'); + $system_versions = drupal_get_schema_versions('module', 'system'); $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED; db_query("INSERT INTO {system} (filename, name, type, owner, 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. + // Populate the system table with module records. module_rebuild_cache(); - drupal_install_modules($module_list); -} + drupal_install_system_items('module', $module_list); + // Register the profile. + $profile_file = "./profiles/$profile/$profile.profile"; + db_query("INSERT INTO {system} (filename, name, type, owner, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', 'profile', '', 1, 0, 0, %d)", $profile_file, $profile, SCHEMA_UNINSTALLED); + drupal_install_system_items('profile', array($profile)); +} /** * Calls the install function and updates the system table for a given list of - * modules. + * system items. * - * @param module_list - * The modules to install. + * @param type + * The type of items to install. + * @param items + * The items to install. */ -function drupal_install_modules($module_list = array()) { - $enable_modules = array(); +function drupal_install_system_items($type, $items = array()) { + $enable_items = array(); - foreach ($module_list as $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); - $enable_modules[] = $module; + foreach ($items as $name) { + if (drupal_get_installed_schema_version($type, $name, TRUE) == SCHEMA_UNINSTALLED) { + system_load_install($type, $name); + system_item_action($type, $name, 'install'); + $versions = drupal_get_schema_versions($type, $name); + drupal_set_installed_schema_version($type, $name, $versions ? max($versions) : SCHEMA_INSTALLED); + $enable_items[] = $name; } } - module_enable($enable_modules); + system_enable($type, $enable_items); } /** - * Calls the uninstall function and updates the system table for a given module. + * Calls the uninstall function and updates the system table for a given system + * item. * - * @param $module - * The module to uninstall. + * @param type + * The type of items to install. + * @param $name + * The item to uninstall. */ -function drupal_uninstall_module($module) { - module_load_install($module); - module_invoke($module, 'uninstall'); - drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED); +function drupal_uninstall_system_item($type, $name) { + system_load_install($type, $name); + system_item_action($type, $name, 'uninstall'); + drupal_set_installed_schema_version($type, $name, SCHEMA_UNINSTALLED); } /** @@ -671,13 +700,7 @@ function _system_update_utf8($tables) { function drupal_check_profile($profile) { include_once './includes/file.inc'; - $profile_file = "./profiles/$profile/$profile.profile"; - - if (!isset($profile) || !file_exists($profile_file)) { - install_no_profile_error(); - } - - require_once($profile_file); + drupal_load_profile_install($profile); // Get a list of modules required by this profile. $function = $profile .'_profile_modules'; Index: drupal/includes/module.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/module.inc,v retrieving revision 1.101 diff -u -p -r1.101 module.inc --- drupal/includes/module.inc 7 May 2007 11:59:40 -0000 1.101 +++ drupal/includes/module.inc 23 May 2007 21:48:47 -0000 @@ -183,74 +183,6 @@ function module_exists($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 list of modules. - * - * @param $module_list - * An array of module names. - */ -function module_enable($module_list) { - $invoke_modules = array(); - foreach ($module_list as $module) { - $existing = db_fetch_object(db_query("SELECT 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); - $invoke_modules[] = $module; - } - } - - if (!empty($invoke_modules)) { - // Refresh the module list to include the new enabled module. - module_list(TRUE, FALSE); - // Force to regenerate the stored list of hook implementations. - module_implements('', FALSE, TRUE); - } - - foreach ($invoke_modules as $module) { - module_invoke($module, 'enable'); - } -} - -/** - * Disable a given set of modules. - * - * @param $module_list - * An array of module names. - */ -function module_disable($module_list) { - $invoke_modules = array(); - foreach ($module_list as $module) { - if (module_exists($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); - $invoke_modules[] = $module; - } - } - - if (!empty($invoke_modules)) { - // Refresh the module list to exclude the disabled modules. - module_list(TRUE, FALSE); - // Force to regenerate the stored list of hook implementations. - module_implements('', FALSE, TRUE); - } -} - -/** * @defgroup hooks Hooks * @{ * Allow modules to interact with the Drupal core. Index: drupal/modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.115 diff -u -p -r1.115 system.install --- drupal/modules/system/system.install 22 May 2007 05:52:17 -0000 1.115 +++ drupal/modules/system/system.install 23 May 2007 21:48:57 -0000 @@ -147,7 +147,7 @@ function system_requirements($phase) { foreach (module_list() as $module) { $updates = drupal_get_schema_versions($module); if ($updates !== FALSE) { - $default = drupal_get_installed_schema_version($module); + $default = drupal_get_installed_schema_version('module', $module); if (max($updates) > $default) { $requirements['update']['severity'] = REQUIREMENT_ERROR; $requirements['update']['value'] = $t('Out of date'); Index: drupal/modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.481 diff -u -p -r1.481 system.module --- drupal/modules/system/system.module 23 May 2007 08:00:46 -0000 1.481 +++ drupal/modules/system/system.module 23 May 2007 21:49:05 -0000 @@ -1035,14 +1035,26 @@ function system_theme_data() { // Find theme engines $engines = drupal_system_listing('\.engine$', 'themes/engines'); + // Extract current files from database. + system_get_files_database($engines, 'theme_engine'); + // Remove all theme engines from the system table db_query("DELETE FROM {system} WHERE type = 'theme_engine'"); + $new_engines = array(); foreach ($engines as $engine) { // Insert theme engine into system table drupal_get_filename('theme_engine', $engine->name, $engine->filename); drupal_load('theme_engine', $engine->name); - db_query("INSERT INTO {system} (name, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', %d, %d, %d)", $engine->name, 'theme_engine', $engine->filename, 1, 0, 0); + // Theme engines are always enabled, so set a status of 1. + db_query("INSERT INTO {system} (name, type, filename, status, throttle, bootstrap, schema_version) VALUES ('%s', '%s', '%s', %d, %d, %d, %d)", $engine->name, 'theme_engine', $engine->filename, 1, 0, 0, isset($engine->schema_version) ? $engine->schema_version : SCHEMA_UNINSTALLED); + if (drupal_get_installed_schema_version('theme_engine', $key) == SCHEMA_UNINSTALLED) { + $new_engines[] = $key; + } + } + + if (!empty($new_engines)) { + drupal_install_system_items('theme_engine', $new_themes); } $defaults = system_theme_default(); @@ -1111,7 +1123,7 @@ function system_theme_data() { $theme->owner = ''; } - db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, 0); + db_query("INSERT INTO {system} (name, owner, info, type, filename, status, throttle, bootstrap, schema_version) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d)", $theme->name, $theme->owner, serialize($theme->info), 'theme', $theme->filename, isset($theme->status) ? $theme->status : 0, 0, isset($theme->schema_version) ? $theme->schema_version : SCHEMA_UNINSTALLED); } return $themes; @@ -1362,15 +1374,24 @@ function system_themes_form_submit($form db_query("UPDATE {system} SET status = 0 WHERE type = 'theme'"); if ($form_values['op'] == t('Save configuration')) { + include_once './includes/install.inc'; if (is_array($form_values['status'])) { + $new_themes = array(); + $new_theme_engines = array(); foreach ($form_values['status'] as $key => $choice) { // Always enable the default theme, despite its status checkbox being checked: if ($choice || $form_values['theme_default'] == $key) { system_initialize_theme_blocks($key); $new_theme_list[] = $key; db_query("UPDATE {system} SET status = 1 WHERE type = 'theme' and name = '%s'", $key); + if (drupal_get_installed_schema_version('theme', $key) == SCHEMA_UNINSTALLED) { + $new_themes[] = $key; + } } } + if (!empty($new_themes)) { + drupal_install_system_items('theme', $new_themes); + } } if (($admin_theme = variable_get('admin_theme', '0')) != '0' && $admin_theme != $form_values['theme_default']) { drupal_set_message(t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array( @@ -1678,7 +1699,7 @@ function system_modules_submit($form_val $disable_modules = array(); foreach ($form_values['status'] as $key => $choice) { if ($choice) { - if (drupal_get_installed_schema_version($key) == SCHEMA_UNINSTALLED) { + if (drupal_get_installed_schema_version('module', $key) == SCHEMA_UNINSTALLED) { $new_modules[] = $key; } else { @@ -1705,7 +1726,7 @@ function system_modules_submit($form_val unset($new_modules[$key]); } } - drupal_install_modules($new_modules); + drupal_install_system_items('module', $new_modules); $current_module_list = module_list(TRUE, FALSE); if ($old_module_list != $current_module_list) { @@ -1815,7 +1836,7 @@ function system_modules_uninstall($form_ // Load the .install file, and check for an uninstall hook. // If the hook exists, the module can be uninstalled. - module_load_install($module->name); + system_load_install('module', $module->name); if (module_hook($module->name, 'uninstall')) { $form['modules'][$module->name]['name'] = array('#value' => $info['name'] ? $info['name'] : $module->name); $form['modules'][$module->name]['description'] = array('#value' => t($info['description'])); @@ -1953,7 +1974,7 @@ function system_modules_uninstall_submit if (!empty($form['#confirmed'])) { // Call the uninstall routine for each selected module. foreach (array_filter($form_values['uninstall']) as $module => $value) { - drupal_uninstall_module($module); + drupal_uninstall_system_item('module', $module); } drupal_set_message(t('The selected modules have been uninstalled.')); @@ -2076,6 +2097,152 @@ function _system_sort_requirements($a, $ } /** + * Fetch a list of the installed system item types. + */ +function system_get_types() { + $types = array(); + $result = db_query('SELECT DISTINCT(type) FROM {system} ORDER BY type'); + while ($item = db_fetch_array($result)) { + $types[] = $item->type; + } + return $types; +} + +/** + * Load a system item's installation hooks. + */ +function system_load_install($type, $name) { + // Make sure the installation API is available + include_once './includes/install.inc'; + + switch ($type) { + case 'profile': + // Profiles include install-related functions directly in the .profile file. + $install_file = './'. db_result(db_query("SELECT filename FROM {system} WHERE type = 'profile' AND name = '%s'", $name)); + break; + default: + $install_file = './'. drupal_get_path($type, $name) .'/'. $type .'.install'; + break; + } + if (is_file($install_file)) { + include_once $install_file; + } +} + +/** + * Enable a given list of system items. + * + * @param $type + * The type of items to enable. + * @param $items + * An array of item names. + */ +function system_enable($type, $items) { + $invoke_items = array(); + foreach ($items as $name) { + $existing = db_fetch_object(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s'", $type, $name)); + if ($existing->status === '0') { + system_load_install('module', $name); + db_query("UPDATE {system} SET status = 1, throttle = 0 WHERE type = '%s' AND name = '%s'", $type, $name); + drupal_load($type, $name); + $invoke_items[] = $name; + } + } + + if ($type == 'module' && !empty($invoke_items)) { + // Refresh the module list to include the new enabled module. + module_list(TRUE, FALSE); + // Force to regenerate the stored list of hook implementations. + module_implements('', FALSE, TRUE); + } + + foreach ($invoke_items as $name) { + system_item_action($type, $name, 'enable'); + } +} + +/** + * Disable a given set of system items. + * + * @param $type + * The type of items to disable. + * @param $items + * An array of item names. + */ +function system_disable($type, $items) { + $invoke_items = array(); + foreach ($items as $name) { + $existing = db_fetch_object(db_query("SELECT status FROM {system} WHERE type = '%s' AND name = '%s'", $type, $name)); + if ($existing->status == '1') { + system_load_install($type, $name); + system_item_action($type, $name, 'disable'); + db_query("UPDATE {system} SET status = 0, throttle = 0 WHERE type = '%s' AND name = '%s'", $type, $name); + $invoke_items[] = $name; + } + } + + if ($type == 'module' && !empty($invoke_items)) { + // Refresh the module list to exclude the disabled modules. + module_list(TRUE, FALSE); + // Force to regenerate the stored list of hook implementations. + module_implements('', FALSE, TRUE); + } +} + +/** + * Return a list of enabled system items. + */ +function system_list() { + static $items = array(); + if (empty($items)) { + $result = db_query("SELECT type, name FROM {system} WHERE status = 1 ORDER BY type, name"); + while ($item = db_fetch_array($result)) { + $items[] = $item; + } + } + return $items; +} + +/** + * Return the name of the currently installed profile. + */ +function system_get_installed_profile() { + return db_result(db_query("SELECT name FROM {system} WHERE type = 'profile' AND status = 1")); +} + +/** + * Call install, uninstall, enable, and disable functions for system items. + * + * @param type + * The type of items to install. + * @param $name + * The item to uninstall. + * @param $op + * Option, 'install', 'uninstall', 'enable', or 'disable'. + */ +function system_item_action($type, $name, $op) { + switch($type) { + // Module install functions use just the name and install. + case 'module': + $function = $name .'_'. $op; + break; + case 'profile': + // Profile installation tasks are handled separately. + if ($op == 'install') { + $function = FALSE; + break; + } + // Otherwise fall through. + default: + $function = $name .'_'. $type .'_'. $op; + break; + } + if ($function && function_exists($function)) { + $function(); + } +} + +/** * Theme status report */ function theme_status_report(&$requirements) {