system_list()函数的目的是根据传入的资源类型,返回一个数组列表:
function system_list($type) { ... ... }
参数$type支持下面三种类型:
- bootstrap:返回启动模块列表
- module_enabled :返回模块列表
- theme:返回主题列表
三种类型里面bootstrap处理方式有点不同,module_enabled和theme是相同的。
先看看bootstrap是如此处理的。这里的bootstrap指的是系统表system里面标识为bootstrap的模块,是系统的启动模块,在Drupal启动过程中需要先被载入。首先检查是否有缓存:
if ($cached = cache_get('bootstrap_modules', 'cache_bootstrap')) { $bootstrap_list = $cached->data; }
若没有缓存,则直接从系统表system中查询:
$bootstrap_list = db_query("SELECT name, filename FROM {system} WHERE status = 1 AND bootstrap = 1 AND type = 'module' ORDER BY weight ASC, name ASC")->fetchAllAssoc('name'); cache_set('bootstrap_modules', $bootstrap_list, 'cache_bootstrap');
然后透过drupal_get_filename()更新模块主文件路径,目的是用system表的filename字段更新drupal_get_filename()函数中的静态变量:
foreach ($bootstrap_list as $module) { drupal_get_filename('module', $module->name, $module->filename); }
最后,更新system_list()的静态变量$lists,返回列表:
$lists['bootstrap'] = array_keys($bootstrap_list); ... ... return $list[$type];
注意这里boostrap类型返回的只是启动模块的名称数组,没有其它额外的信息。
下面看看module_enabled和theme是如何处理的。首先还是查看缓存:
if ($cached = cache_get('system_list', 'cache_bootstrap')) { $lists = $cached->data; }
若缓存不存在,则直接读取系统表system:
$lists = array( 'module_enabled' => array(), 'theme' => array(), 'filepaths' => array(), ); $result = db_query("SELECT * FROM {system} WHERE type = 'theme' OR (type = 'module' AND status = 1) ORDER BY weight ASC, name ASC"); foreach ($result as $record) { $record->info = unserialize($record->info); // info字段就是资源的info文件 // Build a list of all enabled modules. if ($record->type == 'module') { $lists['module_enabled'][$record->name] = $record; } // Build a list of themes. if ($record->type == 'theme') { $lists['theme'][$record->name] = $record; } // Build a list of filenames so drupal_get_filename can use it. if ($record->status) { $lists['filepaths'][] = array('type' => $record->type, 'name' => $record->name, 'filepath' => $record->filename); } }
接下来处理主题的继承关系。关于主题的继承关系可以参看《Drupal如何解析主题继承关系?》。
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 . '/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'] = isset($lists['theme'][$base_key]->info['engine']) ? $lists['theme'][$base_key]->info['engine'] : 'theme'; } else { // A plain theme is its own engine. $base_key = $key; if (!isset($lists['theme'][$key]->info['engine'])) { $lists['theme'][$key]->info['engine'] = 'theme'; } } // Set the theme engine prefix. $lists['theme'][$key]->prefix = ($lists['theme'][$key]->info['engine'] == 'theme') ? $base_key : $lists['theme'][$key]->info['engine']; }
最后更新drupal_get_filename()的资源主文件路径,返回列表:
foreach ($lists['filepaths'] as $item) { drupal_get_filename($item['type'], $item['name'], $item['filepath']); } return $lists[$type];
从代码来看,system_list()也是可以调用filepaths类型的,结果也是数组:
array( array('type' => '...', 'name' => '...', 'filepath' => '...'), array('type' => '...', 'name' => '...', 'filepath' => '...'), )