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
上一篇:基于ROS和python,通过TCP通信协议,完成键盘无线控制移动机器人运动


下一篇:Debian出现in the drive ‘/media/cdrom/’ and press enter解决办法