diff --git a/core/authorize.php b/core/authorize.php index c6ba51d..904b038 100644 --- a/core/authorize.php +++ b/core/authorize.php @@ -80,7 +80,7 @@ global $conf; // display errors via the maintenance theme. $module_list['system']['filename'] = 'core/modules/system/system.module'; $module_list['user']['filename'] = 'core/modules/user/user.module'; -module_list(TRUE, FALSE, FALSE, $module_list); +module_list('module_enabled', $module_list); drupal_load('module', 'system'); drupal_load('module', 'user'); diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index c26ec86..c094ab2 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -961,14 +961,7 @@ function drupal_page_is_cacheable($allow_caching = NULL) { * @see bootstrap_hooks() */ function bootstrap_invoke_all($hook) { - // Bootstrap modules should have been loaded when this function is called, so - // we don't need to tell module_list() to reset its internal list (and we - // therefore leave the first parameter at its default value of FALSE). We - // still pass in TRUE for the second parameter, though; in case this is the - // first time during the bootstrap that module_list() is called, we want to - // make sure that its internal cache is primed with the bootstrap modules - // only. - foreach (module_list(FALSE, TRUE) as $module) { + foreach (module_list('bootstrap') as $module) { drupal_load('module', $module); module_invoke($module, $hook); } diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 07e25a0..52f7ff0 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -279,10 +279,11 @@ function install_begin_request(&$install_state) { drupal_language_initialize(); require_once DRUPAL_ROOT . '/core/includes/ajax.inc'; + // Override the module list with a minimal set of modules. $module_list['system']['filename'] = 'core/modules/system/system.module'; $module_list['entity']['filename'] = 'core/modules/entity/entity.module'; $module_list['user']['filename'] = 'core/modules/user/user.module'; - module_list(TRUE, FALSE, FALSE, $module_list); + module_list('module_enabled', $module_list); drupal_load('module', 'system'); drupal_load('module', 'entity'); drupal_load('module', 'user'); @@ -1401,6 +1402,9 @@ function install_load_profile(&$install_state) { * An array of information about the current installation state. */ function install_bootstrap_full(&$install_state) { + // Clear the module list that was overriden earlier in the process. + // This will allow all freshly installed modules to be loaded. + drupal_static_reset('module_list'); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); } diff --git a/core/includes/module.inc b/core/includes/module.inc index df9c138..49a38db 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -20,7 +20,8 @@ function module_load_all($bootstrap = FALSE) { static $has_run = FALSE; if (isset($bootstrap)) { - foreach (module_list(TRUE, $bootstrap) as $module) { + $type = $bootstrap ? 'bootstrap' : 'module_enabled'; + foreach (module_list($type) as $module) { drupal_load('module', $module); } // $has_run will be TRUE if $bootstrap is FALSE. @@ -33,70 +34,51 @@ function module_load_all($bootstrap = FALSE) { /** * Returns a list of currently active modules. * - * Usually, this returns a list of all enabled modules. When called early on in - * the bootstrap, it will return a list of vital modules only (those needed to - * generate cached pages). + * Acts as a wrapper around system_list(), returning either a list of all + * enabled modules, or just modules needed for bootstrap. + * An optional parameter allows an alternative module list to be provided, + * which is then stored and used in subsequent calls instead of the one + * provided by system_list(). * - * All parameters to this function are optional and should generally not be - * changed from their defaults. - * - * @param $refresh - * (optional) Whether to force the module list to be regenerated (such as - * after the administrator has changed the system settings). Defaults to - * FALSE. - * @param $bootstrap_refresh - * (optional) When $refresh is TRUE, setting $bootstrap_refresh to TRUE forces - * the module list to be regenerated using the reduced set of modules loaded - * in "bootstrap mode" for cached pages. Otherwise, setting $refresh to TRUE - * generates the complete list of enabled modules. - * @param $sort - * (optional) By default, modules are ordered by weight and module name. Set - * this option to TRUE to return a module list ordered only by module name. + * @param $type + * The type of list to return: + * - module_enabled: All enabled modules. + * - bootstrap: All enabled modules required for bootstrap. * @param $fixed_list * (optional) If an array of module names is provided, this will override the * module list with the given set of modules. This will persist until the next - * call with $refresh set to TRUE or with a new $fixed_list passed in. This - * parameter is primarily intended for internal use (e.g., in install.php and - * update.php). + * call with a new $fixed_list passed in. This parameter is primarily + * intended for internal use (e.g., in install.php and update.php). * * @return * An associative array whose keys and values are the names of the modules in * the list. */ -function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE, $fixed_list = NULL) { - static $list = array(), $sorted_list; - - if (empty($list) || $refresh || $fixed_list) { - $list = array(); - $sorted_list = NULL; - if ($fixed_list) { - foreach ($fixed_list as $name => $module) { - drupal_get_filename('module', $name, $module['filename']); - $list[$name] = $name; - } - } - else { - if ($refresh) { - // For the $refresh case, make sure that system_list() returns fresh - // data. - drupal_static_reset('system_list'); - } - if ($bootstrap_refresh) { - $list = system_list('bootstrap'); - } - else { - // Not using drupal_map_assoc() here as that requires common.inc. - $list = array_keys(system_list('module_enabled')); - $list = (!empty($list) ? array_combine($list, $list) : array()); - } +function module_list($type = 'module_enabled', $fixed_list = NULL) { + // Tracks data acquired from $fixed_list. + $module_list = &drupal_static(__FUNCTION__, array()); + + // The list that will be be returned. Separate from $module_list in order + // to avoid statically caching data acquired from system_list(), since + // that function already has its own static cache. + $list = $module_list; + + if (isset($fixed_list)) { + foreach ($fixed_list as $name => $module) { + drupal_get_filename('module', $name, $module['filename']); + $module_list[$name] = $name; } + $list = $module_list; } - if ($sort) { - if (!isset($sorted_list)) { - $sorted_list = $list; - ksort($sorted_list); + elseif (empty($module_list)) { + if ($type == 'bootstrap') { + $list = system_list('bootstrap'); + } + else { + // Not using drupal_map_assoc() here as that requires common.inc. + $list = array_keys(system_list($type)); + $list = (!empty($list) ? array_combine($list, $list) : array()); } - return $sorted_list; } return $list; } @@ -443,7 +425,6 @@ function module_enable($module_list, $enable_dependencies = TRUE) { ->execute(); // Refresh the module list to include it. system_list_reset(); - module_list(TRUE); module_implements_reset(); _system_update_bootstrap_status(); // Update the registry to include it. @@ -564,7 +545,6 @@ function module_disable($module_list, $disable_dependents = TRUE) { if (!empty($invoke_modules)) { // Refresh the module list to exclude the disabled modules. system_list_reset(); - module_list(TRUE); module_implements_reset(); // Invoke hook_modules_disabled before disabling modules, // so we can still call module hooks to get information. @@ -636,16 +616,13 @@ function module_hook($module, $hook) { * * @param $hook * The name of the hook (e.g. "help" or "menu"). - * @param $sort - * By default, modules are ordered by weight and filename, settings this option - * to TRUE, module list will be ordered by module name. * * @return * An array with the names of the modules which are implementing this hook. * * @see module_implements_write_cache() */ -function module_implements($hook, $sort = FALSE) { +function module_implements($hook) { // Use the advanced drupal_static() pattern, since this is called very often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { @@ -670,7 +647,7 @@ function module_implements($hook, $sort = FALSE) { $implementations['#write_cache'] = TRUE; $hook_info = module_hook_info(); $implementations[$hook] = array(); - $list = module_list(FALSE, FALSE, $sort); + $list = module_list(); foreach ($list as $module) { $include_file = isset($hook_info[$hook]['group']) && module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']); // Since module_hook() may needlessly try to load the include file again, diff --git a/core/includes/schema.inc b/core/includes/schema.inc index 18fab75..77ceb47 100644 --- a/core/includes/schema.inc +++ b/core/includes/schema.inc @@ -70,10 +70,10 @@ function drupal_get_complete_schema($rebuild = FALSE) { // been completed, so we force the functions we need to load just in case. if (function_exists('module_load_all_includes')) { // This function can be called very early in the bootstrap process, so - // we force the module_list() cache to be refreshed to ensure that it - // contains the complete list of modules before we go on to call + // we force the system_list() static cache to be refreshed to ensure + // that it contains the complete list of modules before we go on to call // module_load_all_includes(). - module_list(TRUE); + drupal_static_reset('system_list'); module_load_all_includes('install'); } diff --git a/core/includes/theme.maintenance.inc b/core/includes/theme.maintenance.inc index 3fd60c9..e769a11 100644 --- a/core/includes/theme.maintenance.inc +++ b/core/includes/theme.maintenance.inc @@ -56,7 +56,7 @@ function _drupal_maintenance_theme() { // Ensure that system.module is loaded. if (!function_exists('_system_rebuild_theme_data')) { $module_list['system']['filename'] = 'core/modules/system/system.module'; - module_list(TRUE, FALSE, FALSE, $module_list); + module_list('module_enabled', $module_list); drupal_load('module', 'system'); } diff --git a/core/modules/dashboard/dashboard.test b/core/modules/dashboard/dashboard.test index ff37d57..8707788 100644 --- a/core/modules/dashboard/dashboard.test +++ b/core/modules/dashboard/dashboard.test @@ -92,13 +92,13 @@ class DashboardBlocksTestCase extends DrupalWebTestCase { $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); $this->assertNoRaw('assigned to the invalid region', t('Dashboard blocks gracefully disabled.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertFalse(module_exists('dashboard'), t('Dashboard disabled.')); $edit['modules[Core][dashboard][enable]'] = 'dashboard'; $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertTrue(module_exists('dashboard'), t('Dashboard enabled.')); $this->drupalGet('admin/dashboard'); diff --git a/core/modules/forum/forum.test b/core/modules/forum/forum.test index b5b8ae4..7165c36 100644 --- a/core/modules/forum/forum.test +++ b/core/modules/forum/forum.test @@ -63,7 +63,7 @@ class ForumTestCase extends DrupalWebTestCase { $edit['modules[Core][forum][enable]'] = FALSE; $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertFalse(module_exists('forum'), t('Forum module is not enabled.')); // Attempt to re-enable the forum module and ensure it does not try to @@ -72,7 +72,7 @@ class ForumTestCase extends DrupalWebTestCase { $edit['modules[Core][forum][enable]'] = 'forum'; $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertTrue(module_exists('forum'), t('Forum module is enabled.')); } diff --git a/core/modules/help/help.admin.inc b/core/modules/help/help.admin.inc index 81cd224..0a8e147 100644 --- a/core/modules/help/help.admin.inc +++ b/core/modules/help/help.admin.inc @@ -64,7 +64,7 @@ function help_links_as_list() { $module_info = system_rebuild_module_data(); $modules = array(); - foreach (module_implements('help', TRUE) as $module) { + foreach (module_implements('help') as $module) { if (module_invoke($module, 'help', "admin/help#$module", $empty_arg)) { $modules[$module] = $module_info[$module]->info['name']; } diff --git a/core/modules/help/help.module b/core/modules/help/help.module index 9e74751..c57e62f 100644 --- a/core/modules/help/help.module +++ b/core/modules/help/help.module @@ -18,7 +18,9 @@ function help_menu() { 'file' => 'help.admin.inc', ); - foreach (module_implements('help', TRUE) as $module) { + $modules = module_implements('help'); + ksort($modules); + foreach ($modules as $module) { $items['admin/help/' . $module] = array( 'title' => $module, 'page callback' => 'help_page', diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php index a5a27ec..4b0d59e 100644 --- a/core/modules/simpletest/drupal_web_test_case.php +++ b/core/modules/simpletest/drupal_web_test_case.php @@ -739,7 +739,7 @@ class DrupalUnitTestCase extends DrupalTestCase { if (isset($module_list['locale'])) { $this->originalModuleList = $module_list; unset($module_list['locale']); - module_list(TRUE, FALSE, FALSE, $module_list); + module_list('module_enabled', $module_list); } $this->setup = TRUE; } @@ -754,7 +754,7 @@ class DrupalUnitTestCase extends DrupalTestCase { $conf['file_public_path'] = $this->originalFileDirectory; // Restore modules if necessary. if (isset($this->originalModuleList)) { - module_list(TRUE, FALSE, FALSE, $this->originalModuleList); + module_list('module_enabled', $this->originalModuleList); } } } @@ -1494,7 +1494,7 @@ class DrupalWebTestCase extends DrupalTestCase { // Reset all static variables. drupal_static_reset(); // Reset the list of enabled modules. - module_list(TRUE); + drupal_static_reset('system_list'); // Reset cached schema for new database prefix. This must be done before // drupal_flush_all_caches() so rebuilds can make use of the schema of @@ -1572,7 +1572,7 @@ class DrupalWebTestCase extends DrupalTestCase { // Reload module list and implementations to ensure that test module hooks // aren't called after tests. - module_list(TRUE); + drupal_static_reset('system_list'); module_implements_reset(); // Reset the Field API. diff --git a/core/modules/simpletest/tests/module.test b/core/modules/simpletest/tests/module.test index 19acf60..0e3cba8 100644 --- a/core/modules/simpletest/tests/module.test +++ b/core/modules/simpletest/tests/module.test @@ -51,7 +51,7 @@ class ModuleUnitTest extends DrupalWebTestCase { ->condition('type', 'module') ->execute(); // Reset the module list. - module_list(TRUE); + drupal_static_reset('system_list'); // Move contact to the end of the array. unset($module_list[array_search('contact', $module_list)]); $module_list[] = 'contact'; @@ -62,12 +62,12 @@ class ModuleUnitTest extends DrupalWebTestCase { 'system' => array('filename' => drupal_get_path('module', 'system')), 'menu' => array('filename' => drupal_get_path('module', 'menu')), ); - module_list(FALSE, FALSE, FALSE, $fixed_list); + module_list('module_enabled', $fixed_list); $new_module_list = array_combine(array_keys($fixed_list), array_keys($fixed_list)); $this->assertModuleList($new_module_list, t('When using a fixed list')); // Reset the module list. - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertModuleList($module_list, t('After reset')); } @@ -80,8 +80,6 @@ class ModuleUnitTest extends DrupalWebTestCase { protected function assertModuleList(Array $expected_values, $condition) { $expected_values = array_combine($expected_values, $expected_values); $this->assertEqual($expected_values, module_list(), t('@condition: module_list() returns correct results', array('@condition' => $condition))); - ksort($expected_values); - $this->assertIdentical($expected_values, module_list(FALSE, FALSE, TRUE), t('@condition: module_list() returns correctly sorted results', array('@condition' => $condition))); } /** diff --git a/core/modules/simpletest/tests/upgrade/upgrade.test b/core/modules/simpletest/tests/upgrade/upgrade.test index aafb642..b1ad1ae 100644 --- a/core/modules/simpletest/tests/upgrade/upgrade.test +++ b/core/modules/simpletest/tests/upgrade/upgrade.test @@ -178,7 +178,7 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { // Reload module list and implementations to ensure that test module hooks // aren't called after tests. - module_list(TRUE); + drupal_static_reset('system_list'); module_implements_reset(); // Reset the Field API. diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 978b0f4..a6594da 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -1194,7 +1194,8 @@ function system_modules_submit($form, &$form_state) { // Gets module list after install process, flushes caches and displays a // message if there are changes. - $post_install_list = module_list(TRUE); + drupal_static_reset('system_list'); + $post_install_list = module_list(); if ($pre_install_list != $post_install_list) { drupal_flush_all_caches(); drupal_set_message(t('The configuration options have been saved.')); diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 905d11d..ad5c403 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -499,7 +499,7 @@ function system_install() { // Clear out module list and hook implementation statics before calling // system_rebuild_theme_data(). - module_list(TRUE); + drupal_static_reset('system_list'); module_implements_reset(); // Load system theme data appropriately. diff --git a/core/modules/system/system.test b/core/modules/system/system.test index 9287d16..e6069a5 100644 --- a/core/modules/system/system.test +++ b/core/modules/system/system.test @@ -81,7 +81,7 @@ class ModuleTestCase extends DrupalWebTestCase { * Expected module state. */ function assertModules(array $modules, $enabled) { - module_list(TRUE); + drupal_static_reset('system_list'); foreach ($modules as $module) { if ($enabled) { $message = 'Module "@module" is enabled.'; @@ -1563,7 +1563,7 @@ class SystemMainContentFallback extends DrupalWebTestCase { $edit['modules[Core][block][enable]'] = FALSE; $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertFalse(module_exists('block'), t('Block module disabled.')); // At this point, no region is filled and fallback should be triggered. @@ -1597,7 +1597,7 @@ class SystemMainContentFallback extends DrupalWebTestCase { $edit['modules[Core][block][enable]'] = 'block'; $this->drupalPost('admin/modules', $edit, t('Save configuration')); $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.')); - module_list(TRUE); + drupal_static_reset('system_list'); $this->assertTrue(module_exists('block'), t('Block module re-enabled.')); } } diff --git a/core/update.php b/core/update.php index 3d858a2..444ca4f 100644 --- a/core/update.php +++ b/core/update.php @@ -395,7 +395,7 @@ if (empty($op) && update_access_allowed()) { // Load module basics. include_once DRUPAL_ROOT . '/core/includes/module.inc'; $module_list['system']['filename'] = 'core/modules/system/system.module'; - module_list(TRUE, FALSE, FALSE, $module_list); + module_list('module_enabled', $module_list); drupal_load('module', 'system'); // Reset the module_implements() cache so that any new hook implementations