zoukankan      html  css  js  c++  java
  • Drupal如何更新注册表?

    Drupal的注册表是指registry和registry_file两个数据表。前一个表保存所有可用的类和接口以及它们所对应的文件,后一个表保存每个文件的hash码。

    1. 将所有需要更新的文件都汇总的$files数组:

    // 需要更新的文件有两部分:一是系统includes目录下所有的.inc文件,二是模块描述文件中通过files属性声明的文件。
    
    $files = array();
    
    $modules = db_query("SELECT * FROM {system} WHERE type = 'module'")->fetchAll();
    foreach ($modules as &$module) {
      $module->info = unserialize($module->info);
      $dir = dirname($module->filename);
      $module->dir = $dir;
    
      if ($module->status) {
        foreach ($module->info['files'] as $file) {
          $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
        }
      }
    }
    
    foreach (file_scan_directory('includes', '/.inc$/') as $filename => $file) {
      $files["$filename"] = array('module' => '', 'weight' => 0);
    }


    2. 更新$files数组的hash属性:

    foreach (db_query("SELECT * FROM {registry_file}")->fetchAllAssoc('filename', PDO::FETCH_ASSOC) 
                                                    as $filename => $file) {
      // Add the hash for those files we have already parsed.
      if (isset($files[$filename])) {
        $files[$filename]['hash'] = $file['hash'];
      }
      else {
        // Flush the registry of resources in files that are no longer on disc
        // or are in files that no installed modules require to be parsed.
        db_delete('registry')
          ->condition('filename', $filename)
          ->execute();
        db_delete('registry_file')
          ->condition('filename', $filename)
          ->execute();
      }
    }


    3. 更新registry和registry_file表:

    $parsed_files = array();
    
    // 重新计算每个文件的Hash码
    foreach ($files as $filename => $file) {
      if (file_exists($filename)) {
        $hash = hash_file('sha256', $filename);
        if (empty($file['hash']) || $file['hash'] != $hash) {
          $file['hash'] = $hash;
          $parsed_files[$filename] = $file;
        }
      }
    }
    
    foreach ($parsed_files as $filename => $file) {
      // 搜索文件中的类和接口
      if (preg_match_all('/^s*(?:abstract|final)?s*(class|interface)s+([a-zA-Z0-9_]+)/m', 
                                        file_get_contents($filename), $matches)) {
        foreach ($matches[2] as $key => $name) {
            // 将类和接口名称更新到registry表
          db_merge('registry')
            ->key(array(
              'name' => $name,
              'type' => $matches[1][$key],
            ))
            ->fields(array(
              'filename' => $filename,
              'module' => $module,
              'weight' => $weight,
            ))
            ->execute();
        }
        // Delete any resources for this file where the name is not in the list
        // we just merged in.
        db_delete('registry')
          ->condition('filename', $filename)
          ->condition('name', $matches[2], 'NOT IN')
          ->execute();
      }
      
      // 更新registry_file表
      db_merge('registry_file')
        ->key(array('filename' => $filename))
        ->fields(array(
          'hash' => $file['hash'],
        ))
        ->execute();
    }


    所以,模块安装时,让Drupal自动更新注册表的关键是要在.info文件中注明files属性。例如,comment模块的.info文件就是这样写的:

    name = Comment
    description = Allows users to comment on and discuss published content.
    package = Core
    version = VERSION
    core = 7.x
    dependencies[] = text
    files[] = comment.module
    files[] = comment.test
    configure = admin/content/comment
    stylesheets[all][] = comment.css
  • 相关阅读:
    redis 使用 get 命令读取 bitmap 类型的数据
    如何用vue-router为每个路由配置各自的title
    vue定义全局变量和全局方法
    后端分布式系列:分布式存储-HDFS 与 GFS 的设计差异
    Android Studio(十二):打包多个发布渠道的apk文件
    Android中使用lambda表达式
    Android教程-03 常见布局的总结
    程序员的业余项目
    Android Studio(十一):代码混淆及打包apk
    win10提示 磁盘包含不是“PARTITION_BASIC_DATA_GUID"类型的分区
  • 原文地址:https://www.cnblogs.com/eastson/p/3352202.html
Copyright © 2011-2022 走看看