diff -u b/core/includes/module.inc b/core/includes/module.inc --- b/core/includes/module.inc +++ b/core/includes/module.inc @@ -126,33 +126,20 @@ return $lists['bootstrap']; } if ($cached = cache('bootstrap')->get('bootstrap_modules')) { - $bootstrap_list = $cached->data; + $lists['bootstrap'] = $cached->data; // To avoid a separate database lookup for the filepath, prime the // drupal_get_filename() static cache for bootstrap modules only. // The rest is stored separately to keep the bootstrap module cache small. - foreach ($bootstrap_list as $module => $filename) { + foreach ($lists['bootstrap'] as $module => $filename) { _system_list_warm('module', $module, $filename); } } else { - $enabled_modules = config('system.module')->get(); - _system_list_warm('module', 'system', 'core/modules/system.module', TRUE); - $module_data = system_rebuild_module_data(); - $bootstrap_list = array(); - foreach ($enabled_modules as $module => $weight) { - $filename = $module_data[$module]->filename; - _system_list_warm('module', $module, $filename, TRUE); - foreach (bootstrap_hooks() as $hook) { - if (function_exists($module .'_' . $hook)) { - $bootstrap_list[$module] = $filename; - } - } - } - cache('bootstrap')->set('bootstrap_modules', $bootstrap_list); + $lists = _system_list_rebuild(); } // We only return the module names here since module_list() doesn't need // the filename itself. - $lists['bootstrap'] = array_keys($bootstrap_list); + $lists['bootstrap'] = array_keys($lists['bootstrap']); } // Otherwise build the list for enabled modules and themes. elseif (!isset($lists['module_enabled'])) { @@ -160,79 +147,8 @@ $lists = $cached->data; } else { - // The module name (rather than the filename) is used as the fallback - // weighting in order to guarantee consistent behavior across different - // Drupal installations, which might have modules installed in different - // locations in the file system. The ordering here must also be - // consistent with the one used in module_implements(). - $enabled_themes = config('system.theme')->get(); - $enabled_modules = config('system.module')->get(); - // It's important to retrieve these first because the rebuild calls - // reset the system_list static. - $bootstrap_list = $lists['bootstrap']; - _system_list_warm('module', 'system', 'core/modules/system.module', TRUE); - $module_data = system_rebuild_module_data(); - $theme_data = system_rebuild_theme_data(); - $lists = array( - 'bootstrap' => $bootstrap_list, - 'module_enabled' => array(), - 'theme' => array(), - 'filepaths' => array(), - ); - foreach ($theme_data as $key => $theme) { - $lists['theme'][$key] = $theme; - $status = isset($enabled_themes[$key]); - $lists['theme'][$key]->status = $status; - $lists['theme'][$key]->name = $key; - // Build a list of filenames so drupal_get_filename can use it. - if ($status) { - $lists['filepaths'][] = array( - 'type' => 'theme', - 'name' => $key, - 'filepath' => $theme->filename - ); - } - } - foreach ($lists['theme'] as $key => $theme) { - if (!empty($theme->info['base theme'])) { - // Make a list of the theme's base themes. - require_once DRUPAL_ROOT . '/core/includes/theme.inc'; - $lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key); - // Don't proceed if there was a problem with the root base theme. - if (!current($lists['theme'][$key]->base_themes)) { - continue; - } - // Determine the root base theme. - $base_key = key($lists['theme'][$key]->base_themes); - // Add to the list of sub-themes for each of the theme's base themes. - foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) { - $lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name']; - } - // Add the base theme's theme engine info. - $lists['theme'][$key]->info['engine'] = $lists['theme'][$base_key]->info['engine']; - } - else { - // A plain theme is its own base theme. - $base_key = $key; - } - // Set the theme engine prefix. - $lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine']; - } - - foreach ($enabled_modules as $name => $weight) { - // Build a list of all enabled modules. - $lists['module_enabled'][$name] = $name; - // Build a list of filenames so drupal_get_filename can use it. - $lists['filepaths'][] = array( - 'type' => 'module', - 'name' => $name, - 'filepath' => $module_data[$name]->filename, - ); - } - cache('bootstrap')->set('system_list', $lists); + $lists = _system_list_rebuild(); } - // To avoid a separate database lookup for the filepath, prime the - // drupal_get_filename() static cache with all enabled modules and themes. foreach ($lists['filepaths'] as $item) { _system_list_warm($item['type'], $item['name'], $item['filepath']); } @@ -242,6 +158,88 @@ } /** + * Rebuild the system list data structure. + */ +function _system_list_rebuild() { + // The module name (rather than the filename) is used as the fallback + // weighting in order to guarantee consistent behavior across different + // Drupal installations, which might have modules installed in different + // locations in the file system. The ordering here must also be + // consistent with the one used in module_implements(). + $enabled_themes = config('system.theme')->get(); + $enabled_modules = config('system.module')->get(); + _system_list_warm('module', 'system', 'core/modules/system.module', TRUE); + $module_data = system_rebuild_module_data(FALSE); + $theme_data = system_rebuild_theme_data(FALSE); + $lists = array( + 'bootstrap' => array(), + 'module_enabled' => array(), + 'theme' => array(), + 'filepaths' => array(), + ); + foreach ($theme_data as $key => $theme) { + $lists['theme'][$key] = $theme; + $status = isset($enabled_themes[$key]); + $lists['theme'][$key]->status = $status; + $lists['theme'][$key]->name = $key; + // Build a list of filenames so drupal_get_filename can use it. + if ($status) { + $lists['filepaths'][] = array( + 'type' => 'theme', + 'name' => $key, + 'filepath' => $theme->filename + ); + } + } + foreach ($lists['theme'] as $key => $theme) { + if (!empty($theme->info['base theme'])) { + // Make a list of the theme's base themes. + require_once DRUPAL_ROOT . '/core/includes/theme.inc'; + $lists['theme'][$key]->base_themes = drupal_find_base_themes($lists['theme'], $key); + // Don't proceed if there was a problem with the root base theme. + if (!current($lists['theme'][$key]->base_themes)) { + continue; + } + // Determine the root base theme. + $base_key = key($lists['theme'][$key]->base_themes); + // Add to the list of sub-themes for each of the theme's base themes. + foreach (array_keys($lists['theme'][$key]->base_themes) as $base_theme) { + $lists['theme'][$base_theme]->sub_themes[$key] = $lists['theme'][$key]->info['name']; + } + // Add the base theme's theme engine info. + $lists['theme'][$key]->info['engine'] = $lists['theme'][$base_key]->info['engine']; + } + else { + // A plain theme is its own base theme. + $base_key = $key; + } + // Set the theme engine prefix. + $lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine']; + } + + foreach ($enabled_modules as $name => $weight) { + // Build a list of all enabled modules. + $lists['module_enabled'][$name] = $name; + $filename = $module_data[$name]->filename; + // Build a list of filenames so drupal_get_filename can use it. + $lists['filepaths'][] = array( + 'type' => 'module', + 'name' => $name, + 'filepath' => $filename, + ); + _system_list_warm('module', $name, $filename, TRUE); + foreach (bootstrap_hooks() as $hook) { + if (function_exists($name .'_' . $hook)) { + $lists['bootstrap'][] = $filename; + } + } + } + cache('bootstrap')->set('system_list', $lists); + cache('bootstrap')->set('bootstrap_modules', $lists['bootstrap']); + return $lists; +} + +/** * Prepares a module for loading and optionally calls drupal_load(). * * @param string $type diff -u b/core/modules/system/system.module b/core/modules/system/system.module --- b/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2780,7 +2780,7 @@ * @return * Array of all available modules and their data. */ -function system_rebuild_module_data() { +function system_rebuild_module_data($reset = TRUE) { $modules_cache = &drupal_static(__FUNCTION__, array()); // Only rebuild once per request. $modules and $modules_cache cannot be // combined into one variable, because the $modules_cache variable is reset by @@ -2803,7 +2803,9 @@ } // As noted above, system_list_reset() deletes $modules_cache so the order // here is important. - system_list_reset(); + if ($reset) { + system_list_reset(); + } $modules_cache['data'] = $modules; } // Running the info alter function is not possible before full bootstrap. @@ -2970,14 +2972,16 @@ * @return * Array of all available themes and their data. */ -function system_rebuild_theme_data() { +function system_rebuild_theme_data($reset = TRUE) { $themes = _system_rebuild_theme_data(); ksort($themes); $themes_status = config('system.theme')->get(); foreach ($themes as $theme => $data) { $data->status = isset($themes_status[$theme]); } - system_list_reset(); + if ($reset) { + system_list_reset(); + } return $themes; }