/[drupal]/drupal/includes/registry.inc
ViewVC logotype

Contents of /drupal/includes/registry.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.25 - (show annotations) (download) (as text)
Tue Oct 13 05:26:57 2009 UTC (6 weeks, 4 days ago) by webchick
Branch: MAIN
CVS Tags: DRUPAL-7-0-UNSTABLE-10
Changes since 1.24: +2 -2 lines
File MIME type: text/x-php
#561452 by pwolanin and David_Rothstein: Add API function to get module/theme info without rebuilding it.
1 <?php
2 // $Id: registry.inc,v 1.24 2009/08/24 00:14:18 webchick Exp $
3
4 /**
5 * @file
6 * This file contains the code registry parser engine.
7 */
8
9 /**
10 * @defgroup registry Code registry
11 * @{
12 * The code registry engine.
13 *
14 * Drupal maintains an internal registry of all functions or classes in the
15 * system, allowing it to lazy-load code files as needed (reducing the amount
16 * of code that must be parsed on each request).
17 */
18
19 /**
20 * @see registry_rebuild.
21 */
22 function _registry_rebuild() {
23
24 // The registry serves as a central autoloader for all classes, including
25 // the database query builders. However, the registry rebuild process
26 // requires write ability to the database, which means having access to the
27 // query builders that require the registry in order to be loaded. That
28 // causes a fatal race condition. Therefore we manually include the
29 // appropriate query builders for the currently active database before the
30 // registry rebuild process runs.
31 $connection_info = Database::getConnectionInfo();
32 $driver = $connection_info['default']['driver'];
33 require_once DRUPAL_ROOT . '/includes/database/query.inc';
34 require_once DRUPAL_ROOT . '/includes/database/select.inc';
35 require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/query.inc';
36
37 // Get current list of modules and their files.
38 $modules = system_rebuild_module_data();
39 // Get the list of files we are going to parse.
40 $files = array();
41 foreach ($modules as &$module) {
42 $dir = dirname($module->uri);
43
44 // Store the module directory for use in hook_registry_files_alter().
45 $module->dir = $dir;
46
47 if ($module->status) {
48 // Add files for enabled modules to the registry.
49 foreach ($module->info['files'] as $file) {
50 $files["$dir/$file"] = array('module' => $module->name, 'weight' => $module->weight);
51 }
52 }
53 }
54 foreach (file_scan_directory('includes', '/\.inc$/') as $filename => $file) {
55 $files["$filename"] = array('module' => '', 'weight' => 0);
56 }
57
58 // Allow modules to manually modify the list of files before the registry
59 // parses them. The $modules array provides the .info file information, which
60 // includes the list of files registered to each module. Any files in the
61 // list can then be added to the list of files that the registry will parse,
62 // or modify attributes of a file.
63 drupal_alter('registry_files', $files, $modules);
64 foreach (registry_get_parsed_files() as $filename => $file) {
65 // Add the file creation and modification dates to those files we have
66 // already parsed.
67 if (isset($files[$filename])) {
68 $files[$filename]['filectime'] = $file['filectime'];
69 $files[$filename]['filemtime'] = $file['filemtime'];
70 }
71 else {
72 // Flush the registry of resources in files that are no longer on disc
73 // or are in files that no installed modules require to be parsed.
74 db_delete('registry')
75 ->condition('filename', $filename)
76 ->execute();
77 db_delete('registry_file')
78 ->condition('filename', $filename)
79 ->execute();
80 }
81 }
82 $parsed_files = _registry_parse_files($files);
83
84 $unchanged_resources = array();
85 $lookup_cache = array();
86 if ($cache = cache_get('lookup_cache', 'cache_registry')) {
87 $lookup_cache = $cache->data;
88 }
89 foreach ($lookup_cache as $key => $file) {
90 // If the file for this cached resource is carried over unchanged from
91 // the last registry build, then we can safely re-cache it.
92 if ($file && in_array($file, array_keys($files)) && !in_array($file, $parsed_files)) {
93 $unchanged_resources[$key] = $file;
94 }
95 }
96 module_implements('', FALSE, TRUE);
97 _registry_check_code(REGISTRY_RESET_LOOKUP_CACHE);
98
99 cache_clear_all('*', 'cache_registry', TRUE);
100
101 // We have some unchanged resources, warm up the cache - no need to pay
102 // for looking them up again.
103 if (count($unchanged_resources) > 0) {
104 cache_set('lookup_cache', $unchanged_resources, 'cache_registry');
105 }
106 }
107
108 /**
109 * Return the list of files in registry_file
110 */
111 function registry_get_parsed_files() {
112 $files = array();
113 // We want the result as a keyed array.
114 $files = db_query("SELECT * FROM {registry_file}")->fetchAllAssoc('filename', PDO::FETCH_ASSOC);
115 return $files;
116 }
117
118 /**
119 * Parse all files that have changed since the registry was last built, and save their function and class listings.
120 *
121 * @param $files
122 * The list of files to check and parse.
123 */
124 function _registry_parse_files($files) {
125 $parsed_files = array();
126 foreach ($files as $filename => $file) {
127 $filectime = filectime($filename);
128 $filemtime = filemtime($filename);
129 $modified_file = !isset($file['filectime']) || !isset($file['filemtime'])
130 || $filectime != $file['filectime'] || $filemtime != $file['filemtime'];
131 if ($modified_file) {
132 $contents = file_get_contents($filename);
133 $parsed_files[] = $filename;
134 // We update the filectime/filemtime after we've saved the files resources
135 // rather than here, so if we don't make it through this rebuild, the next
136 // run will reparse the file.
137 _registry_parse_file($filename, $contents, $file['module'], $file['weight']);
138 db_merge('registry_file')
139 ->key(array('filename' => $filename))
140 ->fields(array(
141 'filectime' => $filectime,
142 'filemtime' => $filemtime,
143 ))
144 ->execute();
145 }
146 }
147 return $parsed_files;
148 }
149
150 /**
151 * Parse a file and save its function and class listings.
152 *
153 * @param $filename
154 * Name of the file we are going to parse.
155 * @param $contents
156 * Contents of the file we are going to parse as a string.
157 * @param $module
158 * (optional) Name of the module this file belongs to.
159 * @param $weight
160 * (optional) Weight of the module.
161 */
162 function _registry_parse_file($filename, $contents, $module = '', $weight = 0) {
163 static $map = array(T_CLASS => 'class', T_INTERFACE => 'interface');
164 // Delete registry entries for this file, so we can insert the new resources.
165 db_delete('registry')
166 ->condition('filename', $filename)
167 ->execute();
168 if (preg_match_all('/^\s*(?:abstract)?\s*(class|interface)\s+([a-zA-Z0-9_]+)/m', $contents, $matches)) {
169 $query = db_insert('registry')->fields(array('name', 'type', 'filename', 'module', 'weight'));
170 foreach ($matches[2] as $key => $name) {
171 $query->values(array(
172 'name' => $name,
173 'type' => $matches[1][$key],
174 'filename' => $filename,
175 'module' => $module,
176 'weight' => $weight,
177 ));
178 }
179 $query->execute();
180 }
181 }
182
183 /**
184 * @} End of "defgroup registry".
185 */
186

  ViewVC Help
Powered by ViewVC 1.1.2