Builds a list of bootstrap modules and enabled modules and themes.
@todo There are too many layers/levels of caching involved for system_list() data. Consider to add a config($name, $cache = TRUE) argument to allow callers like system_list() to force-disable a possible configuration storage controller cache or some other way to circumvent it/take it over.
$type: The type of list to return:
An associative array of modules or themes, keyed by name. For $type 'bootstrap' and 'module_enabled', the array values equal the keys. For $type 'theme', the array values are objects representing the respective database row, with the 'info' property already unserialized.
function system_list($type) {
$lists =& drupal_static(__FUNCTION__);
if ($cached = cache('bootstrap')
->get('system_list')) {
$lists = $cached->data;
}
else {
$lists = array(
'theme' => array(),
'filepaths' => array(),
);
// Build a list of themes.
$enabled_themes = (array) config('system.theme')
->get('enabled');
// @todo Themes include all themes, including disabled/uninstalled. This
// system.theme.data state will go away entirely as soon as themes have
// a proper installation status.
// @see http://drupal.org/node/1067408
$theme_data = Drupal::state()
->get('system.theme.data');
if (empty($theme_data)) {
// @todo: system_list() may be called from _drupal_bootstrap_code(), in
// which case system.module is not loaded yet.
// Prevent a filesystem scan in drupal_load() and include it directly.
// @see http://drupal.org/node/1067408
require_once DRUPAL_ROOT . '/core/modules/system/system.module';
$theme_data = system_rebuild_theme_data();
}
foreach ($theme_data as $name => $theme) {
$theme->status = (int) isset($enabled_themes[$name]);
$lists['theme'][$name] = $theme;
// Build a list of filenames so drupal_get_filename can use it.
if (isset($enabled_themes[$name])) {
$lists['filepaths'][] = array(
'type' => 'theme',
'name' => $name,
'filepath' => $theme->filename,
);
}
}
// @todo Move into list_themes(). Read info for a particular requested
// theme from state instead.
foreach ($lists['theme'] as $key => $theme) {
if (!empty($theme->info['base theme'])) {
// Make a list of the theme's base themes.
require_once __DIR__ . '/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'];
}
cache('bootstrap')
->set('system_list', $lists);
}
// 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_register($item['type'], $item['name'], $item['filepath']);
}
return $lists[$type];
}