Commit 4c81313c authored by Dries's avatar Dries

- Patch #1503224 by catch, sun, bojanz: cleanup module_list().

parent c35ae62e
......@@ -80,7 +80,7 @@ function authorize_access_allowed() {
// 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');
......
......@@ -1085,14 +1085,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);
}
......
......@@ -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.
module_list_reset();
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
}
......
......@@ -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,90 +40,69 @@ 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).
* Acts as a wrapper around system_list(), returning either a list of all
* enabled modules, or just modules needed for bootstrap.
*
* All parameters to this function are optional and should generally not be
* changed from their defaults.
* The returned module list is always based on system_list(). The only exception
* to that is when a fixed list of modules has been passed in previously, in
* which case system_list() is omitted and the fixed list is always returned in
* subsequent calls until manually reverted via module_list_reset().
*
* @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 $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).
* @param string $type
* The type of list to return:
* - module_enabled: All enabled modules.
* - bootstrap: All enabled modules required for bootstrap.
* @param array $fixed_list
* (optional) An array of module names to override the list of modules. This
* list will persist until the next call with a new $fixed_list passed in.
* Primarily intended for internal use (e.g., in install.php and update.php).
* Use module_list_reset() to undo the $fixed_list override.
*
* @return
* @return array
* 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');
function module_list($type = 'module_enabled', array $fixed_list = NULL) {
// This static is only used for $fixed_list.
$module_list = &drupal_static(__FUNCTION__);
// The list that will be be returned. Separate from $module_list in order
// to not duplicate the static cache of system_list().
$list = $module_list;
if (isset($fixed_list)) {
$module_list = array();
foreach ($fixed_list as $name => $module) {
drupal_get_filename('module', $name, $module['filename']);
$module_list[$name] = $name;
}
$list = $module_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;
}
elseif (!isset($module_list)) {
if ($type == 'bootstrap') {
$list = system_list('bootstrap');
}
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());
}
}
}
if ($sort) {
if (!isset($sorted_list)) {
$sorted_list = $list;
ksort($sorted_list);
// 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;
}
/**
* Reverts an enforced fixed list of module_list().
*
* Subsequent calls to module_list() will no longer use a fixed list.
*/
function module_list_reset() {
drupal_static_reset('module_list');
}
/**
* Build a list of bootstrap modules and enabled modules and themes.
*
......@@ -465,7 +445,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 +567,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 +640,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,8 +671,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);
foreach ($list as $module) {
foreach (module_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,
// function_exists() is used directly here.
......
......@@ -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');
}
......
......@@ -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(NULL, $module_list);
drupal_load('module', 'system');
}
......
......@@ -96,13 +96,13 @@ function testDisableEnable() {
$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);
system_list_reset();
$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);
system_list_reset();
$this->assertTrue(module_exists('dashboard'), t('Dashboard enabled.'));
$this->drupalGet('admin/dashboard');
......
......@@ -100,7 +100,7 @@ function testEnableForumField() {
$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);
system_list_reset();
$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
......@@ -109,7 +109,7 @@ function testEnableForumField() {
$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);
system_list_reset();
$this->assertTrue(module_exists('forum'), t('Forum module is enabled.'));
}
......
......@@ -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'];
}
......
......@@ -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',
......
......@@ -49,11 +49,8 @@ protected function setUp() {
$conf = array();
drupal_static_reset();
// Empty out module list.
module_list(TRUE, FALSE, FALSE, array());
// Prevent module_load_all() from attempting to refresh it.
$has_run = &drupal_static('module_load_all');
$has_run = TRUE;
// Enforce an empty module list.
module_list(NULL, array());
// Re-implant theme registry.
// Required for l() and other functions to work correctly and not trigger
......
......@@ -777,7 +777,8 @@ protected function tearDown() {
// 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_list_reset();
module_implements_reset();
// Reset the Field API.
......
......@@ -13,8 +13,6 @@
* Tests class loading.
*/
class ClassLoaderTest extends WebTestBase {
protected $profile = 'testing';
public static function getInfo() {
return array(
'name' => 'Module class loader',
......
......@@ -55,7 +55,7 @@ function testModuleList() {
->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';
......@@ -66,12 +66,12 @@ function testModuleList() {
'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);
module_list_reset();
$this->assertModuleList($module_list, t('After reset'));
}
......@@ -84,8 +84,6 @@ function testModuleList() {
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)));
}
/**
......
......@@ -132,7 +132,7 @@ function assertNoModuleConfig($module) {
* 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.';
......
......@@ -48,7 +48,7 @@ function testMainContentFallback() {
$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.
......@@ -82,7 +82,7 @@ function testMainContentFallback() {
$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.'));
}
}
......@@ -1199,7 +1199,7 @@ 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);
$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.'));
......
......@@ -514,7 +514,8 @@ 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_list_reset();
module_implements_reset();
// Load system theme data appropriately.
......
......@@ -414,7 +414,7 @@ function update_check_requirements($skip_warnings = FALSE) {
// 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment