webmaster@1
|
1 <?php |
webmaster@11
|
2 // $Id: install.inc,v 1.56.2.3 2008/08/14 09:26:43 dries Exp $ |
webmaster@1
|
3 |
webmaster@1
|
4 define('SCHEMA_UNINSTALLED', -1); |
webmaster@1
|
5 define('SCHEMA_INSTALLED', 0); |
webmaster@1
|
6 |
webmaster@1
|
7 define('REQUIREMENT_INFO', -1); |
webmaster@1
|
8 define('REQUIREMENT_OK', 0); |
webmaster@1
|
9 define('REQUIREMENT_WARNING', 1); |
webmaster@1
|
10 define('REQUIREMENT_ERROR', 2); |
webmaster@1
|
11 |
webmaster@1
|
12 define('FILE_EXIST', 1); |
webmaster@1
|
13 define('FILE_READABLE', 2); |
webmaster@1
|
14 define('FILE_WRITABLE', 4); |
webmaster@1
|
15 define('FILE_EXECUTABLE', 8); |
webmaster@1
|
16 define('FILE_NOT_EXIST', 16); |
webmaster@1
|
17 define('FILE_NOT_READABLE', 32); |
webmaster@1
|
18 define('FILE_NOT_WRITABLE', 64); |
webmaster@1
|
19 define('FILE_NOT_EXECUTABLE', 128); |
webmaster@1
|
20 |
webmaster@1
|
21 /** |
webmaster@1
|
22 * Initialize the update system by loading all installed module's .install files. |
webmaster@1
|
23 */ |
webmaster@1
|
24 function drupal_load_updates() { |
webmaster@1
|
25 foreach (drupal_get_installed_schema_version(NULL, FALSE, TRUE) as $module => $schema_version) { |
webmaster@1
|
26 if ($schema_version > -1) { |
webmaster@1
|
27 module_load_install($module); |
webmaster@1
|
28 } |
webmaster@1
|
29 } |
webmaster@1
|
30 } |
webmaster@1
|
31 |
webmaster@1
|
32 /** |
webmaster@1
|
33 * Returns an array of available schema versions for a module. |
webmaster@1
|
34 * |
webmaster@1
|
35 * @param $module |
webmaster@1
|
36 * A module name. |
webmaster@1
|
37 * @return |
webmaster@11
|
38 * If the module has updates, an array of available updates sorted by version. |
webmaster@11
|
39 * Otherwise, FALSE. |
webmaster@1
|
40 */ |
webmaster@1
|
41 function drupal_get_schema_versions($module) { |
webmaster@1
|
42 $updates = array(); |
webmaster@1
|
43 $functions = get_defined_functions(); |
webmaster@1
|
44 foreach ($functions['user'] as $function) { |
webmaster@1
|
45 if (strpos($function, $module .'_update_') === 0) { |
webmaster@1
|
46 $version = substr($function, strlen($module .'_update_')); |
webmaster@1
|
47 if (is_numeric($version)) { |
webmaster@1
|
48 $updates[] = $version; |
webmaster@1
|
49 } |
webmaster@1
|
50 } |
webmaster@1
|
51 } |
webmaster@1
|
52 if (count($updates) == 0) { |
webmaster@1
|
53 return FALSE; |
webmaster@1
|
54 } |
webmaster@11
|
55 sort($updates, SORT_NUMERIC); |
webmaster@1
|
56 return $updates; |
webmaster@1
|
57 } |
webmaster@1
|
58 |
webmaster@1
|
59 /** |
webmaster@1
|
60 * Returns the currently installed schema version for a module. |
webmaster@1
|
61 * |
webmaster@1
|
62 * @param $module |
webmaster@1
|
63 * A module name. |
webmaster@1
|
64 * @param $reset |
webmaster@1
|
65 * Set to TRUE after modifying the system table. |
webmaster@1
|
66 * @param $array |
webmaster@1
|
67 * Set to TRUE if you want to get information about all modules in the |
webmaster@1
|
68 * system. |
webmaster@1
|
69 * @return |
webmaster@1
|
70 * The currently installed schema version. |
webmaster@1
|
71 */ |
webmaster@1
|
72 function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) { |
webmaster@1
|
73 static $versions = array(); |
webmaster@1
|
74 |
webmaster@1
|
75 if ($reset) { |
webmaster@1
|
76 $versions = array(); |
webmaster@1
|
77 } |
webmaster@1
|
78 |
webmaster@1
|
79 if (!$versions) { |
webmaster@1
|
80 $versions = array(); |
webmaster@1
|
81 $result = db_query("SELECT name, schema_version FROM {system} WHERE type = '%s'", 'module'); |
webmaster@1
|
82 while ($row = db_fetch_object($result)) { |
webmaster@1
|
83 $versions[$row->name] = $row->schema_version; |
webmaster@1
|
84 } |
webmaster@1
|
85 } |
webmaster@1
|
86 |
webmaster@1
|
87 return $array ? $versions : $versions[$module]; |
webmaster@1
|
88 } |
webmaster@1
|
89 |
webmaster@1
|
90 /** |
webmaster@1
|
91 * Update the installed version information for a module. |
webmaster@1
|
92 * |
webmaster@1
|
93 * @param $module |
webmaster@1
|
94 * A module name. |
webmaster@1
|
95 * @param $version |
webmaster@1
|
96 * The new schema version. |
webmaster@1
|
97 */ |
webmaster@1
|
98 function drupal_set_installed_schema_version($module, $version) { |
webmaster@1
|
99 db_query("UPDATE {system} SET schema_version = %d WHERE name = '%s'", $version, $module); |
webmaster@1
|
100 } |
webmaster@1
|
101 |
webmaster@1
|
102 /** |
webmaster@1
|
103 * Loads the profile definition, extracting the profile's defined name. |
webmaster@1
|
104 * |
webmaster@1
|
105 * @return |
webmaster@1
|
106 * The name defined in the profile's _profile_details() hook. |
webmaster@1
|
107 */ |
webmaster@1
|
108 function drupal_install_profile_name() { |
webmaster@1
|
109 global $profile; |
webmaster@1
|
110 static $name = NULL; |
webmaster@1
|
111 |
webmaster@1
|
112 if (!isset($name)) { |
webmaster@1
|
113 // Load profile details. |
webmaster@1
|
114 $function = $profile .'_profile_details'; |
webmaster@1
|
115 if (function_exists($function)) { |
webmaster@1
|
116 $details = $function(); |
webmaster@1
|
117 } |
webmaster@1
|
118 $name = isset($details['name']) ? $details['name'] : 'Drupal'; |
webmaster@1
|
119 } |
webmaster@1
|
120 |
webmaster@1
|
121 return $name; |
webmaster@1
|
122 } |
webmaster@1
|
123 |
webmaster@1
|
124 /** |
webmaster@1
|
125 * Auto detect the base_url with PHP predefined variables. |
webmaster@1
|
126 * |
webmaster@1
|
127 * @param $file |
webmaster@1
|
128 * The name of the file calling this function so we can strip it out of |
webmaster@1
|
129 * the URI when generating the base_url. |
webmaster@1
|
130 * |
webmaster@1
|
131 * @return |
webmaster@1
|
132 * The auto-detected $base_url that should be configured in settings.php |
webmaster@1
|
133 */ |
webmaster@1
|
134 function drupal_detect_baseurl($file = 'install.php') { |
webmaster@1
|
135 global $profile; |
webmaster@1
|
136 $proto = $_SERVER['HTTPS'] ? 'https://' : 'http://'; |
webmaster@1
|
137 $host = $_SERVER['SERVER_NAME']; |
webmaster@1
|
138 $port = ($_SERVER['SERVER_PORT'] == 80 ? '' : ':'. $_SERVER['SERVER_PORT']); |
webmaster@1
|
139 $uri = preg_replace("/\?.*/", '', $_SERVER['REQUEST_URI']); |
webmaster@1
|
140 $dir = str_replace("/$file", '', $uri); |
webmaster@1
|
141 |
webmaster@1
|
142 return "$proto$host$port$dir"; |
webmaster@1
|
143 } |
webmaster@1
|
144 |
webmaster@1
|
145 /** |
webmaster@1
|
146 * Detect all databases supported by Drupal that are compiled into the current |
webmaster@1
|
147 * PHP installation. |
webmaster@1
|
148 * |
webmaster@1
|
149 * @return |
webmaster@1
|
150 * An array of database types compiled into PHP. |
webmaster@1
|
151 */ |
webmaster@1
|
152 function drupal_detect_database_types() { |
webmaster@1
|
153 $databases = array(); |
webmaster@1
|
154 |
webmaster@1
|
155 foreach (array('mysql', 'mysqli', 'pgsql') as $type) { |
webmaster@1
|
156 if (file_exists('./includes/install.'. $type .'.inc')) { |
webmaster@1
|
157 include_once './includes/install.'. $type .'.inc'; |
webmaster@1
|
158 $function = $type .'_is_available'; |
webmaster@1
|
159 if ($function()) { |
webmaster@1
|
160 $databases[$type] = $type; |
webmaster@1
|
161 } |
webmaster@1
|
162 } |
webmaster@1
|
163 } |
webmaster@1
|
164 |
webmaster@1
|
165 return $databases; |
webmaster@1
|
166 } |
webmaster@1
|
167 |
webmaster@1
|
168 /** |
webmaster@1
|
169 * Read settings.php into a buffer line by line, changing values specified in |
webmaster@1
|
170 * $settings array, then over-writing the old settings.php file. |
webmaster@1
|
171 * |
webmaster@1
|
172 * @param $settings |
webmaster@1
|
173 * An array of settings that need to be updated. |
webmaster@1
|
174 */ |
webmaster@1
|
175 function drupal_rewrite_settings($settings = array(), $prefix = '') { |
webmaster@1
|
176 $default_settings = './sites/default/default.settings.php'; |
webmaster@1
|
177 $settings_file = './'. conf_path(FALSE, TRUE) .'/'. $prefix .'settings.php'; |
webmaster@1
|
178 |
webmaster@1
|
179 // Build list of setting names and insert the values into the global namespace. |
webmaster@1
|
180 $keys = array(); |
webmaster@1
|
181 foreach ($settings as $setting => $data) { |
webmaster@1
|
182 $GLOBALS[$setting] = $data['value']; |
webmaster@1
|
183 $keys[] = $setting; |
webmaster@1
|
184 } |
webmaster@1
|
185 |
webmaster@1
|
186 $buffer = NULL; |
webmaster@1
|
187 $first = TRUE; |
webmaster@1
|
188 if ($fp = fopen($default_settings, 'r')) { |
webmaster@1
|
189 // Step line by line through settings.php. |
webmaster@1
|
190 while (!feof($fp)) { |
webmaster@1
|
191 $line = fgets($fp); |
webmaster@1
|
192 if ($first && substr($line, 0, 5) != '<?php') { |
webmaster@1
|
193 $buffer = "<?php\n\n"; |
webmaster@1
|
194 } |
webmaster@1
|
195 $first = FALSE; |
webmaster@1
|
196 // Check for constants. |
webmaster@1
|
197 if (substr($line, 0, 7) == 'define(') { |
webmaster@1
|
198 preg_match('/define\(\s*[\'"]([A-Z_-]+)[\'"]\s*,(.*?)\);/', $line, $variable); |
webmaster@1
|
199 if (in_array($variable[1], $keys)) { |
webmaster@1
|
200 $setting = $settings[$variable[1]]; |
webmaster@1
|
201 $buffer .= str_replace($variable[2], " '". $setting['value'] ."'", $line); |
webmaster@1
|
202 unset($settings[$variable[1]]); |
webmaster@1
|
203 unset($settings[$variable[2]]); |
webmaster@1
|
204 } |
webmaster@1
|
205 else { |
webmaster@1
|
206 $buffer .= $line; |
webmaster@1
|
207 } |
webmaster@1
|
208 } |
webmaster@1
|
209 // Check for variables. |
webmaster@1
|
210 elseif (substr($line, 0, 1) == '$') { |
webmaster@1
|
211 preg_match('/\$([^ ]*) /', $line, $variable); |
webmaster@1
|
212 if (in_array($variable[1], $keys)) { |
webmaster@1
|
213 // Write new value to settings.php in the following format: |
webmaster@1
|
214 // $'setting' = 'value'; // 'comment' |
webmaster@1
|
215 $setting = $settings[$variable[1]]; |
webmaster@1
|
216 $buffer .= '$'. $variable[1] ." = '". $setting['value'] ."';". (!empty($setting['comment']) ? ' // '. $setting['comment'] ."\n" : "\n"); |
webmaster@1
|
217 unset($settings[$variable[1]]); |
webmaster@1
|
218 } |
webmaster@1
|
219 else { |
webmaster@1
|
220 $buffer .= $line; |
webmaster@1
|
221 } |
webmaster@1
|
222 } |
webmaster@1
|
223 else { |
webmaster@1
|
224 $buffer .= $line; |
webmaster@1
|
225 } |
webmaster@1
|
226 } |
webmaster@1
|
227 fclose($fp); |
webmaster@1
|
228 |
webmaster@1
|
229 // Add required settings that were missing from settings.php. |
webmaster@1
|
230 foreach ($settings as $setting => $data) { |
webmaster@1
|
231 if ($data['required']) { |
webmaster@1
|
232 $buffer .= "\$$setting = '". $data['value'] ."';\n"; |
webmaster@1
|
233 } |
webmaster@1
|
234 } |
webmaster@1
|
235 |
webmaster@1
|
236 $fp = fopen($settings_file, 'w'); |
webmaster@1
|
237 if ($fp && fwrite($fp, $buffer) === FALSE) { |
webmaster@1
|
238 drupal_set_message(st('Failed to modify %settings, please verify the file permissions.', array('%settings' => $settings_file)), 'error'); |
webmaster@1
|
239 } |
webmaster@1
|
240 } |
webmaster@1
|
241 else { |
webmaster@1
|
242 drupal_set_message(st('Failed to open %settings, please verify the file permissions.', array('%settings' => $default_settings)), 'error'); |
webmaster@1
|
243 } |
webmaster@1
|
244 } |
webmaster@1
|
245 |
webmaster@1
|
246 /** |
webmaster@1
|
247 * Get list of all .install files. |
webmaster@1
|
248 * |
webmaster@1
|
249 * @param $module_list |
webmaster@1
|
250 * An array of modules to search for their .install files. |
webmaster@1
|
251 */ |
webmaster@1
|
252 function drupal_get_install_files($module_list = array()) { |
webmaster@1
|
253 $installs = array(); |
webmaster@1
|
254 foreach ($module_list as $module) { |
webmaster@1
|
255 $installs = array_merge($installs, drupal_system_listing($module .'.install$', 'modules')); |
webmaster@1
|
256 } |
webmaster@1
|
257 return $installs; |
webmaster@1
|
258 } |
webmaster@1
|
259 |
webmaster@1
|
260 /** |
webmaster@1
|
261 * Verify a profile for installation. |
webmaster@1
|
262 * |
webmaster@1
|
263 * @param profile |
webmaster@1
|
264 * Name of profile to verify. |
webmaster@1
|
265 * @param locale |
webmaster@1
|
266 * Name of locale used (if any). |
webmaster@1
|
267 * @return |
webmaster@1
|
268 * The list of modules to install. |
webmaster@1
|
269 */ |
webmaster@1
|
270 function drupal_verify_profile($profile, $locale) { |
webmaster@1
|
271 include_once './includes/file.inc'; |
webmaster@1
|
272 include_once './includes/common.inc'; |
webmaster@1
|
273 |
webmaster@1
|
274 $profile_file = "./profiles/$profile/$profile.profile"; |
webmaster@1
|
275 |
webmaster@1
|
276 if (!isset($profile) || !file_exists($profile_file)) { |
webmaster@1
|
277 install_no_profile_error(); |
webmaster@1
|
278 } |
webmaster@1
|
279 |
webmaster@1
|
280 require_once($profile_file); |
webmaster@1
|
281 |
webmaster@1
|
282 // Get a list of modules required by this profile. |
webmaster@1
|
283 $function = $profile .'_profile_modules'; |
webmaster@1
|
284 $module_list = array_merge(drupal_required_modules(), $function(), ($locale != 'en' ? array('locale') : array())); |
webmaster@1
|
285 |
webmaster@1
|
286 // Get a list of modules that exist in Drupal's assorted subdirectories. |
webmaster@1
|
287 $present_modules = array(); |
webmaster@1
|
288 foreach (drupal_system_listing('\.module$', 'modules', 'name', 0) as $present_module) { |
webmaster@1
|
289 $present_modules[] = $present_module->name; |
webmaster@1
|
290 } |
webmaster@1
|
291 |
webmaster@1
|
292 // Verify that all of the profile's required modules are present. |
webmaster@1
|
293 $missing_modules = array_diff($module_list, $present_modules); |
webmaster@1
|
294 if (count($missing_modules)) { |
webmaster@1
|
295 foreach ($missing_modules as $module) { |
webmaster@1
|
296 drupal_set_message(st('The %module module is required but was not found. Please move it into the <em>modules</em> subdirectory.', array('%module' => $module)), 'error'); |
webmaster@1
|
297 } |
webmaster@1
|
298 } |
webmaster@1
|
299 else { |
webmaster@1
|
300 return $module_list; |
webmaster@1
|
301 } |
webmaster@1
|
302 } |
webmaster@1
|
303 |
webmaster@1
|
304 /** |
webmaster@1
|
305 * Calls the install function and updates the system table for a given list of |
webmaster@1
|
306 * modules. |
webmaster@1
|
307 * |
webmaster@1
|
308 * @param module_list |
webmaster@1
|
309 * The modules to install. |
webmaster@1
|
310 */ |
webmaster@1
|
311 function drupal_install_modules($module_list = array()) { |
webmaster@1
|
312 $files = module_rebuild_cache(); |
webmaster@1
|
313 $module_list = array_flip(array_values($module_list)); |
webmaster@1
|
314 do { |
webmaster@1
|
315 $moved = FALSE; |
webmaster@1
|
316 foreach ($module_list as $module => $weight) { |
webmaster@1
|
317 $file = $files[$module]; |
webmaster@1
|
318 if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) { |
webmaster@1
|
319 foreach ($file->info['dependencies'] as $dependency) { |
webmaster@1
|
320 if (isset($module_list[$dependency]) && $module_list[$module] < $module_list[$dependency] +1) { |
webmaster@1
|
321 $module_list[$module] = $module_list[$dependency] +1; |
webmaster@1
|
322 $moved = TRUE; |
webmaster@1
|
323 } |
webmaster@1
|
324 } |
webmaster@1
|
325 } |
webmaster@1
|
326 } |
webmaster@1
|
327 } while ($moved); |
webmaster@1
|
328 asort($module_list); |
webmaster@1
|
329 $module_list = array_keys($module_list); |
webmaster@1
|
330 array_filter($module_list, '_drupal_install_module'); |
webmaster@1
|
331 module_enable($module_list); |
webmaster@1
|
332 } |
webmaster@1
|
333 |
webmaster@1
|
334 /** |
webmaster@1
|
335 * Callback to install an individual profile module. |
webmaster@1
|
336 * |
webmaster@1
|
337 * Used during installation to install modules one at a time and then |
webmaster@1
|
338 * enable them, or to install a number of modules at one time |
webmaster@1
|
339 * from admin/build/modules. |
webmaster@1
|
340 */ |
webmaster@1
|
341 function _drupal_install_module($module) { |
webmaster@1
|
342 if (drupal_get_installed_schema_version($module, TRUE) == SCHEMA_UNINSTALLED) { |
webmaster@1
|
343 module_load_install($module); |
webmaster@1
|
344 module_invoke($module, 'install'); |
webmaster@1
|
345 $versions = drupal_get_schema_versions($module); |
webmaster@1
|
346 drupal_set_installed_schema_version($module, $versions ? max($versions) : SCHEMA_INSTALLED); |
webmaster@1
|
347 return TRUE; |
webmaster@1
|
348 } |
webmaster@1
|
349 } |
webmaster@1
|
350 |
webmaster@1
|
351 /** |
webmaster@1
|
352 * Callback to install the system module. |
webmaster@1
|
353 * |
webmaster@1
|
354 * Separated from the installation of other modules so core system |
webmaster@1
|
355 * functions can be made available while other modules are installed. |
webmaster@1
|
356 */ |
webmaster@1
|
357 function drupal_install_system() { |
webmaster@1
|
358 $system_path = dirname(drupal_get_filename('module', 'system', NULL)); |
webmaster@1
|
359 require_once './'. $system_path .'/system.install'; |
webmaster@1
|
360 module_invoke('system', 'install'); |
webmaster@1
|
361 $system_versions = drupal_get_schema_versions('system'); |
webmaster@1
|
362 $system_version = $system_versions ? max($system_versions) : SCHEMA_INSTALLED; |
webmaster@1
|
363 db_query("INSERT INTO {system} (filename, name, type, owner, status, throttle, bootstrap, schema_version) VALUES('%s', '%s', '%s', '%s', %d, %d, %d, %d)", $system_path .'/system.module', 'system', 'module', '', 1, 0, 0, $system_version); |
webmaster@1
|
364 // Now that we've installed things properly, bootstrap the full Drupal environment |
webmaster@1
|
365 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); |
webmaster@1
|
366 module_rebuild_cache(); |
webmaster@1
|
367 } |
webmaster@1
|
368 |
webmaster@1
|
369 |
webmaster@1
|
370 /** |
webmaster@1
|
371 * Calls the uninstall function and updates the system table for a given module. |
webmaster@1
|
372 * |
webmaster@1
|
373 * @param $module |
webmaster@1
|
374 * The module to uninstall. |
webmaster@1
|
375 */ |
webmaster@1
|
376 function drupal_uninstall_module($module) { |
webmaster@1
|
377 // First, retrieve all the module's menu paths from db. |
webmaster@1
|
378 drupal_load('module', $module); |
webmaster@1
|
379 $paths = module_invoke($module, 'menu'); |
webmaster@1
|
380 |
webmaster@1
|
381 // Uninstall the module(s). |
webmaster@1
|
382 module_load_install($module); |
webmaster@1
|
383 module_invoke($module, 'uninstall'); |
webmaster@1
|
384 |
webmaster@1
|
385 // Now remove the menu links for all paths declared by this module. |
webmaster@1
|
386 if (!empty($paths)) { |
webmaster@1
|
387 $paths = array_keys($paths); |
webmaster@1
|
388 // Clean out the names of load functions. |
webmaster@1
|
389 foreach ($paths as $index => $path) { |
webmaster@1
|
390 $parts = explode('/', $path, MENU_MAX_PARTS); |
webmaster@1
|
391 foreach ($parts as $k => $part) { |
webmaster@1
|
392 if (preg_match('/^%[a-z_]*$/', $part)) { |
webmaster@1
|
393 $parts[$k] = '%'; |
webmaster@1
|
394 } |
webmaster@1
|
395 } |
webmaster@1
|
396 $paths[$index] = implode('/', $parts); |
webmaster@1
|
397 } |
webmaster@1
|
398 $placeholders = implode(', ', array_fill(0, count($paths), "'%s'")); |
webmaster@1
|
399 |
webmaster@1
|
400 $result = db_query('SELECT * FROM {menu_links} WHERE router_path IN ('. $placeholders .') AND external = 0 ORDER BY depth DESC', $paths); |
webmaster@1
|
401 // Remove all such items. Starting from those with the greatest depth will |
webmaster@1
|
402 // minimize the amount of re-parenting done by menu_link_delete(). |
webmaster@1
|
403 while ($item = db_fetch_array($result)) { |
webmaster@1
|
404 _menu_delete_item($item, TRUE); |
webmaster@1
|
405 } |
webmaster@1
|
406 } |
webmaster@1
|
407 |
webmaster@1
|
408 drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED); |
webmaster@1
|
409 } |
webmaster@1
|
410 |
webmaster@1
|
411 /** |
webmaster@1
|
412 * Verify the state of the specified file. |
webmaster@1
|
413 * |
webmaster@1
|
414 * @param $file |
webmaster@1
|
415 * The file to check for. |
webmaster@1
|
416 * @param $mask |
webmaster@1
|
417 * An optional bitmask created from various FILE_* constants. |
webmaster@1
|
418 * @param $type |
webmaster@1
|
419 * The type of file. Can be file (default), dir, or link. |
webmaster@1
|
420 * @return |
webmaster@1
|
421 * TRUE on success or FALSE on failure. A message is set for the latter. |
webmaster@1
|
422 */ |
webmaster@1
|
423 function drupal_verify_install_file($file, $mask = NULL, $type = 'file') { |
webmaster@1
|
424 $return = TRUE; |
webmaster@1
|
425 // Check for files that shouldn't be there. |
webmaster@1
|
426 if (isset($mask) && ($mask & FILE_NOT_EXIST) && file_exists($file)) { |
webmaster@1
|
427 return FALSE; |
webmaster@1
|
428 } |
webmaster@1
|
429 // Verify that the file is the type of file it is supposed to be. |
webmaster@1
|
430 if (isset($type) && file_exists($file)) { |
webmaster@1
|
431 $check = 'is_'. $type; |
webmaster@1
|
432 if (!function_exists($check) || !$check($file)) { |
webmaster@1
|
433 $return = FALSE; |
webmaster@1
|
434 } |
webmaster@1
|
435 } |
webmaster@1
|
436 |
webmaster@1
|
437 // Verify file permissions. |
webmaster@1
|
438 if (isset($mask)) { |
webmaster@1
|
439 $masks = array(FILE_EXIST, FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE); |
webmaster@1
|
440 foreach ($masks as $current_mask) { |
webmaster@1
|
441 if ($mask & $current_mask) { |
webmaster@1
|
442 switch ($current_mask) { |
webmaster@1
|
443 case FILE_EXIST: |
webmaster@1
|
444 if (!file_exists($file)) { |
webmaster@1
|
445 if ($type == 'dir') { |
webmaster@1
|
446 drupal_install_mkdir($file, $mask); |
webmaster@1
|
447 } |
webmaster@1
|
448 if (!file_exists($file)) { |
webmaster@1
|
449 $return = FALSE; |
webmaster@1
|
450 } |
webmaster@1
|
451 } |
webmaster@1
|
452 break; |
webmaster@1
|
453 case FILE_READABLE: |
webmaster@1
|
454 if (!is_readable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
455 $return = FALSE; |
webmaster@1
|
456 } |
webmaster@1
|
457 break; |
webmaster@1
|
458 case FILE_WRITABLE: |
webmaster@1
|
459 if (!is_writable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
460 $return = FALSE; |
webmaster@1
|
461 } |
webmaster@1
|
462 break; |
webmaster@1
|
463 case FILE_EXECUTABLE: |
webmaster@1
|
464 if (!is_executable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
465 $return = FALSE; |
webmaster@1
|
466 } |
webmaster@1
|
467 break; |
webmaster@1
|
468 case FILE_NOT_READABLE: |
webmaster@1
|
469 if (is_readable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
470 $return = FALSE; |
webmaster@1
|
471 } |
webmaster@1
|
472 break; |
webmaster@1
|
473 case FILE_NOT_WRITABLE: |
webmaster@1
|
474 if (is_writable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
475 $return = FALSE; |
webmaster@1
|
476 } |
webmaster@1
|
477 break; |
webmaster@1
|
478 case FILE_NOT_EXECUTABLE: |
webmaster@1
|
479 if (is_executable($file) && !drupal_install_fix_file($file, $mask)) { |
webmaster@1
|
480 $return = FALSE; |
webmaster@1
|
481 } |
webmaster@1
|
482 break; |
webmaster@1
|
483 } |
webmaster@1
|
484 } |
webmaster@1
|
485 } |
webmaster@1
|
486 } |
webmaster@1
|
487 return $return; |
webmaster@1
|
488 } |
webmaster@1
|
489 |
webmaster@1
|
490 /** |
webmaster@1
|
491 * Create a directory with specified permissions. |
webmaster@1
|
492 * |
webmaster@1
|
493 * @param file |
webmaster@1
|
494 * The name of the directory to create; |
webmaster@1
|
495 * @param mask |
webmaster@1
|
496 * The permissions of the directory to create. |
webmaster@1
|
497 * @param $message |
webmaster@1
|
498 * (optional) Whether to output messages. Defaults to TRUE. |
webmaster@1
|
499 * |
webmaster@1
|
500 * @return |
webmaster@1
|
501 * TRUE/FALSE whether or not the directory was successfully created. |
webmaster@1
|
502 */ |
webmaster@1
|
503 function drupal_install_mkdir($file, $mask, $message = TRUE) { |
webmaster@1
|
504 $mod = 0; |
webmaster@1
|
505 $masks = array(FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE); |
webmaster@1
|
506 foreach ($masks as $m) { |
webmaster@1
|
507 if ($mask & $m) { |
webmaster@1
|
508 switch ($m) { |
webmaster@1
|
509 case FILE_READABLE: |
webmaster@1
|
510 $mod += 444; |
webmaster@1
|
511 break; |
webmaster@1
|
512 case FILE_WRITABLE: |
webmaster@1
|
513 $mod += 222; |
webmaster@1
|
514 break; |
webmaster@1
|
515 case FILE_EXECUTABLE: |
webmaster@1
|
516 $mod += 111; |
webmaster@1
|
517 break; |
webmaster@1
|
518 } |
webmaster@1
|
519 } |
webmaster@1
|
520 } |
webmaster@1
|
521 |
webmaster@1
|
522 if (@mkdir($file, intval("0$mod", 8))) { |
webmaster@1
|
523 return TRUE; |
webmaster@1
|
524 } |
webmaster@1
|
525 else { |
webmaster@1
|
526 return FALSE; |
webmaster@1
|
527 } |
webmaster@1
|
528 } |
webmaster@1
|
529 |
webmaster@1
|
530 /** |
webmaster@1
|
531 * Attempt to fix file permissions. |
webmaster@1
|
532 * |
webmaster@1
|
533 * The general approach here is that, because we do not know the security |
webmaster@1
|
534 * setup of the webserver, we apply our permission changes to all three |
webmaster@1
|
535 * digits of the file permission (i.e. user, group and all). |
webmaster@1
|
536 * |
webmaster@1
|
537 * To ensure that the values behave as expected (and numbers don't carry |
webmaster@1
|
538 * from one digit to the next) we do the calculation on the octal value |
webmaster@1
|
539 * using bitwise operations. This lets us remove, for example, 0222 from |
webmaster@1
|
540 * 0700 and get the correct value of 0500. |
webmaster@1
|
541 * |
webmaster@1
|
542 * @param $file |
webmaster@1
|
543 * The name of the file with permissions to fix. |
webmaster@1
|
544 * @param $mask |
webmaster@1
|
545 * The desired permissions for the file. |
webmaster@1
|
546 * @param $message |
webmaster@1
|
547 * (optional) Whether to output messages. Defaults to TRUE. |
webmaster@1
|
548 * |
webmaster@1
|
549 * @return |
webmaster@1
|
550 * TRUE/FALSE whether or not we were able to fix the file's permissions. |
webmaster@1
|
551 */ |
webmaster@1
|
552 function drupal_install_fix_file($file, $mask, $message = TRUE) { |
webmaster@1
|
553 $mod = fileperms($file) & 0777; |
webmaster@1
|
554 $masks = array(FILE_READABLE, FILE_WRITABLE, FILE_EXECUTABLE, FILE_NOT_READABLE, FILE_NOT_WRITABLE, FILE_NOT_EXECUTABLE); |
webmaster@1
|
555 |
webmaster@1
|
556 // FILE_READABLE, FILE_WRITABLE, and FILE_EXECUTABLE permission strings |
webmaster@1
|
557 // can theoretically be 0400, 0200, and 0100 respectively, but to be safe |
webmaster@1
|
558 // we set all three access types in case the administrator intends to |
webmaster@1
|
559 // change the owner of settings.php after installation. |
webmaster@1
|
560 foreach ($masks as $m) { |
webmaster@1
|
561 if ($mask & $m) { |
webmaster@1
|
562 switch ($m) { |
webmaster@1
|
563 case FILE_READABLE: |
webmaster@1
|
564 if (!is_readable($file)) { |
webmaster@1
|
565 $mod |= 0444; |
webmaster@1
|
566 } |
webmaster@1
|
567 break; |
webmaster@1
|
568 case FILE_WRITABLE: |
webmaster@1
|
569 if (!is_writable($file)) { |
webmaster@1
|
570 $mod |= 0222; |
webmaster@1
|
571 } |
webmaster@1
|
572 break; |
webmaster@1
|
573 case FILE_EXECUTABLE: |
webmaster@1
|
574 if (!is_executable($file)) { |
webmaster@1
|
575 $mod |= 0111; |
webmaster@1
|
576 } |
webmaster@1
|
577 break; |
webmaster@1
|
578 case FILE_NOT_READABLE: |
webmaster@1
|
579 if (is_readable($file)) { |
webmaster@1
|
580 $mod &= ~0444; |
webmaster@1
|
581 } |
webmaster@1
|
582 break; |
webmaster@1
|
583 case FILE_NOT_WRITABLE: |
webmaster@1
|
584 if (is_writable($file)) { |
webmaster@1
|
585 $mod &= ~0222; |
webmaster@1
|
586 } |
webmaster@1
|
587 break; |
webmaster@1
|
588 case FILE_NOT_EXECUTABLE: |
webmaster@1
|
589 if (is_executable($file)) { |
webmaster@1
|
590 $mod &= ~0111; |
webmaster@1
|
591 } |
webmaster@1
|
592 break; |
webmaster@1
|
593 } |
webmaster@1
|
594 } |
webmaster@1
|
595 } |
webmaster@1
|
596 |
webmaster@1
|
597 // chmod() will work if the web server is running as owner of the file. |
webmaster@1
|
598 // If PHP safe_mode is enabled the currently executing script must also |
webmaster@1
|
599 // have the same owner. |
webmaster@1
|
600 if (@chmod($file, $mod)) { |
webmaster@1
|
601 return TRUE; |
webmaster@1
|
602 } |
webmaster@1
|
603 else { |
webmaster@1
|
604 return FALSE; |
webmaster@1
|
605 } |
webmaster@1
|
606 } |
webmaster@1
|
607 |
webmaster@1
|
608 |
webmaster@1
|
609 /** |
webmaster@1
|
610 * Send the user to a different installer page. This issues an on-site HTTP |
webmaster@1
|
611 * redirect. Messages (and errors) are erased. |
webmaster@1
|
612 * |
webmaster@1
|
613 * @param $path |
webmaster@1
|
614 * An installer path. |
webmaster@1
|
615 */ |
webmaster@1
|
616 function install_goto($path) { |
webmaster@1
|
617 global $base_url; |
webmaster@1
|
618 header('Location: '. $base_url .'/'. $path); |
webmaster@1
|
619 header('Cache-Control: no-cache'); // Not a permanent redirect. |
webmaster@1
|
620 exit(); |
webmaster@1
|
621 } |
webmaster@1
|
622 |
webmaster@1
|
623 /** |
webmaster@1
|
624 * Hardcoded function for doing the equivalent of t() during |
webmaster@1
|
625 * the install process, when database, theme, and localization |
webmaster@1
|
626 * system is possibly not yet available. |
webmaster@1
|
627 */ |
webmaster@1
|
628 function st($string, $args = array()) { |
webmaster@1
|
629 static $locale_strings = NULL; |
webmaster@1
|
630 global $profile, $install_locale; |
webmaster@1
|
631 |
webmaster@1
|
632 if (!isset($locale_strings)) { |
webmaster@1
|
633 $locale_strings = array(); |
webmaster@1
|
634 $filename = './profiles/'. $profile .'/translations/'. $install_locale .'.po'; |
webmaster@1
|
635 if (file_exists($filename)) { |
webmaster@1
|
636 require_once './includes/locale.inc'; |
webmaster@1
|
637 $file = (object) array('filepath' => $filename); |
webmaster@1
|
638 _locale_import_read_po('mem-store', $file); |
webmaster@1
|
639 $locale_strings = _locale_import_one_string('mem-report'); |
webmaster@1
|
640 } |
webmaster@1
|
641 } |
webmaster@1
|
642 |
webmaster@1
|
643 require_once './includes/theme.inc'; |
webmaster@1
|
644 // Transform arguments before inserting them |
webmaster@1
|
645 foreach ($args as $key => $value) { |
webmaster@1
|
646 switch ($key[0]) { |
webmaster@1
|
647 // Escaped only |
webmaster@1
|
648 case '@': |
webmaster@1
|
649 $args[$key] = check_plain($value); |
webmaster@1
|
650 break; |
webmaster@1
|
651 // Escaped and placeholder |
webmaster@1
|
652 case '%': |
webmaster@1
|
653 default: |
webmaster@1
|
654 $args[$key] = '<em>'. check_plain($value) .'</em>'; |
webmaster@1
|
655 break; |
webmaster@1
|
656 // Pass-through |
webmaster@1
|
657 case '!': |
webmaster@1
|
658 } |
webmaster@1
|
659 } |
webmaster@1
|
660 return strtr((!empty($locale_strings[$string]) ? $locale_strings[$string] : $string), $args); |
webmaster@1
|
661 } |
webmaster@1
|
662 |
webmaster@1
|
663 /** |
webmaster@1
|
664 * Check a profile's requirements. |
webmaster@1
|
665 * |
webmaster@1
|
666 * @param profile |
webmaster@1
|
667 * Name of profile to check. |
webmaster@1
|
668 */ |
webmaster@1
|
669 function drupal_check_profile($profile) { |
webmaster@1
|
670 include_once './includes/file.inc'; |
webmaster@1
|
671 |
webmaster@1
|
672 $profile_file = "./profiles/$profile/$profile.profile"; |
webmaster@1
|
673 |
webmaster@1
|
674 if (!isset($profile) || !file_exists($profile_file)) { |
webmaster@1
|
675 install_no_profile_error(); |
webmaster@1
|
676 } |
webmaster@1
|
677 |
webmaster@1
|
678 require_once($profile_file); |
webmaster@1
|
679 |
webmaster@1
|
680 // Get a list of modules required by this profile. |
webmaster@1
|
681 $function = $profile .'_profile_modules'; |
webmaster@1
|
682 $module_list = array_unique(array_merge(drupal_required_modules(), $function())); |
webmaster@1
|
683 |
webmaster@1
|
684 // Get a list of all .install files. |
webmaster@1
|
685 $installs = drupal_get_install_files($module_list); |
webmaster@1
|
686 |
webmaster@1
|
687 // Collect requirement testing results |
webmaster@1
|
688 $requirements = array(); |
webmaster@1
|
689 foreach ($installs as $install) { |
webmaster@1
|
690 require_once $install->filename; |
webmaster@1
|
691 if (module_hook($install->name, 'requirements')) { |
webmaster@1
|
692 $requirements = array_merge($requirements, module_invoke($install->name, 'requirements', 'install')); |
webmaster@1
|
693 } |
webmaster@1
|
694 } |
webmaster@1
|
695 return $requirements; |
webmaster@1
|
696 } |
webmaster@1
|
697 |
webmaster@1
|
698 /** |
webmaster@1
|
699 * Extract highest severity from requirements array. |
webmaster@1
|
700 */ |
webmaster@1
|
701 function drupal_requirements_severity(&$requirements) { |
webmaster@1
|
702 $severity = REQUIREMENT_OK; |
webmaster@1
|
703 foreach ($requirements as $requirement) { |
webmaster@1
|
704 if (isset($requirement['severity'])) { |
webmaster@1
|
705 $severity = max($severity, $requirement['severity']); |
webmaster@1
|
706 } |
webmaster@1
|
707 } |
webmaster@1
|
708 return $severity; |
webmaster@1
|
709 } |
webmaster@1
|
710 |
webmaster@1
|
711 /** |
webmaster@1
|
712 * Check a module's requirements. |
webmaster@1
|
713 */ |
webmaster@1
|
714 function drupal_check_module($module) { |
webmaster@1
|
715 // Include install file |
webmaster@1
|
716 $install = drupal_get_install_files(array($module)); |
webmaster@1
|
717 if (isset($install[$module])) { |
webmaster@1
|
718 require_once $install[$module]->filename; |
webmaster@1
|
719 |
webmaster@1
|
720 // Check requirements |
webmaster@1
|
721 $requirements = module_invoke($module, 'requirements', 'install'); |
webmaster@1
|
722 if (is_array($requirements) && drupal_requirements_severity($requirements) == REQUIREMENT_ERROR) { |
webmaster@1
|
723 // Print any error messages |
webmaster@1
|
724 foreach ($requirements as $requirement) { |
webmaster@1
|
725 if (isset($requirement['severity']) && $requirement['severity'] == REQUIREMENT_ERROR) { |
webmaster@1
|
726 $message = $requirement['description']; |
webmaster@1
|
727 if (isset($requirement['value']) && $requirement['value']) { |
webmaster@1
|
728 $message .= ' ('. t('Currently using !item !version', array('!item' => $requirement['title'], '!version' => $requirement['value'])) .')'; |
webmaster@1
|
729 } |
webmaster@1
|
730 drupal_set_message($message, 'error'); |
webmaster@1
|
731 } |
webmaster@1
|
732 } |
webmaster@1
|
733 return FALSE; |
webmaster@1
|
734 } |
webmaster@1
|
735 } |
webmaster@1
|
736 return TRUE; |
webmaster@1
|
737 } |