<?php
function _registry_update() {
$connection_info = Database::getConnectionInfo();
$driver = $connection_info['default']['driver'];
require_once DRUPAL_ROOT . '/includes/database/query.inc';
require_once DRUPAL_ROOT . '/includes/database/select.inc';
require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
$modules = db_query("SELECT * FROM {system} WHERE type = 'module'")
->fetchAll();
$files = array();
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,
);
}
$transaction = db_transaction();
try {
drupal_alter('registry_files', $files, $modules);
foreach (registry_get_parsed_files() as $filename => $file) {
if (isset($files[$filename])) {
$files[$filename]['hash'] = $file['hash'];
}
else {
db_delete('registry')
->condition('filename', $filename)
->execute();
db_delete('registry_file')
->condition('filename', $filename)
->execute();
}
}
$parsed_files = _registry_parse_files($files);
$unchanged_resources = array();
$lookup_cache = array();
if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
$lookup_cache = $cache->data;
}
foreach ($lookup_cache as $key => $file) {
if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) {
$unchanged_resources[$key] = $file;
}
}
module_implements('', FALSE, TRUE);
_registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
} catch (Exception $e) {
$transaction
->rollback();
watchdog_exception('registry', $e);
throw $e;
}
if (count($unchanged_resources) > 0) {
cache_set('lookup_cache', $unchanged_resources, 'cache_bootstrap');
}
}
function registry_get_parsed_files() {
$files = array();
$files = db_query("SELECT * FROM {registry_file}")
->fetchAllAssoc('filename', PDO::FETCH_ASSOC);
return $files;
}
function _registry_parse_files($files) {
$parsed_files = array();
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) {
_registry_parse_file($filename, file_get_contents($filename), $file['module'], $file['weight']);
db_merge('registry_file')
->key(array(
'filename' => $filename,
))
->fields(array(
'hash' => $file['hash'],
))
->execute();
}
return array_keys($parsed_files);
}
function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
if (preg_match_all('/^\\s*(?:abstract|final)?\\s*(class|interface|trait)\\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
foreach ($matches[2] as $key => $name) {
db_merge('registry')
->key(array(
'name' => $name,
'type' => $matches[1][$key],
))
->fields(array(
'filename' => $filename,
'module' => $module,
'weight' => $weight,
))
->execute();
}
db_delete('registry')
->condition('filename', $filename)
->condition('name', $matches[2], 'NOT IN')
->execute();
}
}