• Drupal的system_list()函数解析


    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' => '...'),
    )
  • 相关阅读:
    leetcode刷题-26-删除有序数组重复项
    leetcode刷题-27-移除元素
    leetcode刷题-54-螺旋矩阵
    leetcode刷题-70-爬楼梯
    leetcode刷题-442-数组中重复的数据
    leetcode刷题-945-使数组唯一的最小增量
    leetcode刷题-11-盛最多水的容器
    random.choice函数
    Rating prediction and Ranking prediction
    Dev-c++在windows环境下无法debug(调试)的解决方案
  • 原文地址:https://www.cnblogs.com/eastson/p/3371787.html
Copyright © 2020-2023  润新知