diff --git a/core/authorize.php b/core/authorize.php index fd0774d..a9245da 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(NULL, $module_list); drupal_load('module', 'system'); drupal_load('module', 'user'); diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index b358269..2b2495a 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1057,14 +1057,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 eb9dff9..5c83a96 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -277,10 +277,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(NULL, $module_list); drupal_load('module', 'system'); drupal_load('module', 'entity'); drupal_load('module', 'user'); @@ -1445,6 +1446,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 928abc9..29f7eab 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -30,7 +30,8 @@ function module_load_all($bootstrap = FALSE) { $has_run = &$drupal_static_fast['has_run']; 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. @@ -39,86 +40,54 @@ function module_load_all($bootstrap = FALSE) { return $has_run; } - /** * 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). - * - * All parameters to this function are optional and should generally not be - * changed from their defaults. + * 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(). * - * @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) { - // system_list() may be reset within a request, so the module list needs to be - // reset, too. - // Use the advanced drupal_static() pattern, since this is called very often. - static $drupal_static_fast; - if (!isset($drupal_static_fast)) { - $drupal_static_fast['list'] = &drupal_static(__FUNCTION__ . ':list'); - $drupal_static_fast['sorted_list'] = &drupal_static(__FUNCTION__ . ':sorted_list'); - } - $list = &$drupal_static_fast['list']; - $sorted_list = &$drupal_static_fast['sorted_list']; - - if (!isset($list) || $refresh || isset($fixed_list)) { - $list = array(); - $sorted_list = NULL; - // The fixed list may be a completely empty array, thus check for isset(). - // Calling code may use this to empty out the module list entirely. For - // example, unit tests need to ensure that no modules are invoked. - if (isset($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 (!isset($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; } @@ -465,7 +434,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. @@ -588,7 +556,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. @@ -662,16 +629,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)) { @@ -696,7 +660,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 c11068f..6e267a6 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 a2d6870..751fab0 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/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 dbc836c..92575d6 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/lib/Drupal/simpletest/UnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php index b5314ce..9374a05 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php @@ -50,7 +50,7 @@ abstract class UnitTestBase extends TestBase { drupal_static_reset(); // Empty out module list. - module_list(TRUE, FALSE, FALSE, array()); + module_list(NULL, array()); // Prevent module_load_all() from attempting to refresh it. $has_run = &drupal_static('module_load_all'); $has_run = TRUE; diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 3384e2c..d006cae 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -776,7 +776,7 @@ abstract class WebTestBase extends TestBase { // Reload module list and implementations to ensure that test module hooks // aren't called after tests. - module_list(TRUE); + drupal_static_reset('module_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 9c682f0..9c14dfd 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -1198,7 +1198,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 168f2fc..549d3cd 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -513,7 +513,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 e4df904..684692a 100644 --- a/core/modules/system/system.test +++ b/core/modules/system/system.test @@ -147,7 +147,7 @@ class ModuleTestCase extends WebTestBase { * 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.'; @@ -1673,7 +1673,7 @@ class SystemMainContentFallback extends WebTestBase { $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. @@ -1707,7 +1707,7 @@ class SystemMainContentFallback extends WebTestBase { $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/modules/system/tests/module.test b/core/modules/system/tests/module.test index 761992d..1d3067e 100644 --- a/core/modules/system/tests/module.test +++ b/core/modules/system/tests/module.test @@ -53,7 +53,7 @@ class ModuleUnitTest extends WebTestBase { ->condition('type', 'module') ->execute(); // Reset the module list. - module_list(TRUE); + system_list_reset(); // Move contact to the end of the array. unset($module_list[array_search('contact', $module_list)]); $module_list[] = 'contact'; @@ -64,12 +64,12 @@ class ModuleUnitTest extends WebTestBase { '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(NULL, $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); + system_list_reset(); $this->assertModuleList($module_list, t('After reset')); } @@ -82,8 +82,6 @@ class ModuleUnitTest extends WebTestBase { 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/update.php b/core/update.php index b47702e..fcff60b 100644 --- a/core/update.php +++ b/core/update.php @@ -418,7 +418,7 @@ if (is_null($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(NULL, $module_list); drupal_load('module', 'system'); // Reset the module_implements() cache so that any new hook implementations