/[drupal]/contributions/modules/uts/uts.environment.inc
ViewVC logotype

Contents of /contributions/modules/uts/uts.environment.inc

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


Revision 1.15 - (show annotations) (download) (as text)
Sun Aug 17 00:59:10 2008 UTC (15 months, 1 week ago) by boombatower
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC1, DRUPAL-6--1-0, DRUPAL-6--1-0-BETA2, HEAD
Changes since 1.14: +5 -5 lines
File MIME type: text/x-php
Change $headers to $header.
1 <?php
2 // $Id: uts.environment.inc,v 1.14 2008/07/24 02:56:55 boombatower Exp $
3 /**
4 * @file
5 * Provide Usability Testing Suite testing environment functions.
6 *
7 * Copyright 2008 by Jimmy Berry ("boombatower", http://drupal.org/user/214218)
8 */
9
10 /**
11 * Invoke the callback function in another process using a http request. This
12 * ensures that static variables that are messed up during environment create
13 * and destroy do no effect the user experience.
14 *
15 * @param string $op Operation to perform (create, destroy).
16 * @param string $prefix Environment prefix to perform opperation on.
17 * @param string $second If performing create opperation an environment
18 * be used as a base to copy from. If performing enabling or disabling
19 * modules then a comman separate list of modules can be specified.
20 * @return boolean Success.
21 */
22 function uts_environment_invoke_callback($op, $prefix, $second = NULL) {
23 // Set internal request data for checking in other thread.
24 variable_set('uts_environment', "$op:$prefix:$second");
25
26 $header = array('User-Agent' => 'UTS-Environment-Callback');
27 $url = url("uts/environment/$op/$prefix/$second", array('absolute' => TRUE));
28 $result = drupal_http_request($url, $header);
29
30 // Fix any issues after creating environment.
31 uts_environment_rebuild_caches();
32
33 if ($result->data != 'success') {
34 return FALSE;
35 }
36
37 return TRUE;
38 }
39
40 /**
41 * Menu callback that allows environment opperation to be called
42 * in a seperate process via a http request.
43 *
44 * @param string $op Operation to perform (create, destroy).
45 * @param string $prefix Environment prefix to perform opperation on.
46 * @param string $second If performing create opperation an environment
47 * be used as a base to copy from. If performing enabling or disabling
48 * modules then a comman separate list of modules can be specified.
49 * @return Output status code.
50 */
51 function uts_environment_callback($op, $prefix, $second = NULL) {
52 if (variable_get('uts_environment', '') != "$op:$prefix:$second" ||
53 $_SERVER['HTTP_USER_AGENT'] != 'UTS-Environment-Callback') {
54 // Invalid request.
55 exit('error');
56 }
57 variable_del('uts_environment');
58
59 if ($op == 'create') {
60 uts_environment_create($prefix, $second);
61 }
62 else if ($op == 'destroy') {
63 uts_environment_destroy($prefix);
64 }
65 else if ($op == 'enable_modules') {
66 uts_environment_modules($prefix, $second, TRUE);
67 }
68 else if ($op == 'disable_modules') {
69 uts_environment_modules($prefix, $second, FALSE);
70 }
71 else {
72 exit('error');
73 }
74 exit('success');
75 }
76
77 /**
78 * Create prefixed environment, including database and files directory.
79 *
80 * @param string $prefix Prefix to use for new environment.
81 * @param string $copy_prefix Prefix of environment to copy.
82 */
83 function uts_environment_create($prefix, $copy_prefix = NULL) {
84 global $db_prefix;
85
86 // Retreive variables before database is changed.
87 $admin_name = variable_get('uts_environment_admin_name', 'admin');
88 $admin_pass = variable_get('uts_environment_admin_pass', 'utsadmin');
89
90 // Get max nid, and vid for use below.
91 $result = db_fetch_object(db_query('SELECT MAX(nid) AS max_nid, MAX(vid) AS max_vid FROM {node}'));
92 $max_nid = $result->max_nid;
93 $max_vid = $result->max_vid;
94
95 // Store necessary current values before switching to prefixed database.
96 $db_prefix_original = $db_prefix;
97 $clean_url_original = variable_get('clean_url', 0);
98
99 // Generate temporary prefixed database to ensure that test sessions have a clean starting point.
100 $db_prefix = $prefix;
101 include_once './includes/install.inc';
102 drupal_install_system();
103
104 $modules = drupal_verify_profile('default', 'en');
105
106 // Remove dblog to avoid extraneous errors while logging.
107 foreach ($modules as $key => $module) {
108 if ($module == 'dblog') {
109 unset($modules[$key]);
110 }
111 }
112
113 if ($copy_prefix && $copy_prefix != 'base') {
114 // Set prefix to base environment database.
115 $db_prefix = $copy_prefix;
116
117 // Load modules from study base environment, and override default list.
118 $modules = array();
119 $result = db_query("SELECT name
120 FROM {system}
121 WHERE status = %d
122 AND type = '%s'", 1, 'module');
123 while ($module = db_result($result)) {
124 $modules[] = $module;
125 }
126
127 // Return to installation database.
128 $db_prefix = $prefix;
129 }
130 else if ($copy_prefix == 'base') {
131 // Add proctor to base installations only. The menu hooks for proctor
132 // will not work for some reason.
133 $modules[] = 'uts_proctor';
134 }
135
136 drupal_install_modules($modules);
137
138 // Run default profile tasks.
139 $task = 'profile';
140 default_profile_tasks($task, '');
141
142 // Rebuild caches.
143 uts_environment_rebuild_caches();
144
145 // Restore necessary variables.
146 variable_set('install_profile', 'default');
147 variable_set('install_task', 'profile-finished');
148 variable_set('clean_url', $clean_url_original);
149
150 // Use temporary files directory with the same prefix as database.
151 variable_set('file_directory_path', file_directory_path() . '/' . $prefix);
152 file_check_directory(file_directory_path(), TRUE); // Create the files directory.
153
154 if ($copy_prefix && $copy_prefix != 'base') {
155 // Override database.
156 uts_environment_copy_database($copy_prefix, $prefix);
157
158 // Copy files.
159 uts_environment_copy_directory(file_directory_path() . "/../$copy_prefix", file_directory_path());
160 file_put_contents('output.txt', file_directory_path() . "/../$copy_prefix\n", FILE_APPEND);
161 file_put_contents('output.txt', file_directory_path() . "\n", FILE_APPEND);
162 }
163 else {
164 // Create admin user if base or no prefixed environment to copy from.
165 $pass_hash = md5($admin_pass);
166 db_query("UPDATE {users}
167 SET name = '%s',
168 pass = '%s',
169 created = %d,
170 access = %d,
171 login = %d,
172 status = %d
173 WHERE uid = %d", $admin_name, $pass_hash, time(), 0, 0, 1, 1);
174 }
175
176 // Rebuild caches.
177 uts_environment_rebuild_caches();
178
179 // Add required UTS variables.
180 variable_set('uts_db_prefix', $db_prefix_original);
181
182 // Restore original environment.
183 $db_prefix = $db_prefix_original;
184 uts_environment_rebuild_caches();
185 }
186
187 /**
188 * Copy one database to another, using the prefixes as different databases.
189 *
190 * @param string $original Original database prefix.
191 * @param string $new New database prefix.
192 */
193 function uts_environment_copy_database($original, $new) {
194 file_put_contents('output.txt', '$copy_prefix => ' . $original . "\n");
195 $tables = uts_environment_get_like_tables(''); // Already in database prefix
196 foreach ($tables as $table) {
197 // Empty table and then copy data.
198 // Table variable has the prefix already in it. Format: $prefix$table.
199 db_query('TRUNCATE TABLE ' . $table . '');
200 if (!preg_match('/cache.*/', $table)) {
201 // Let cache tables be re-generated.
202 $table_original = $original . str_replace($new, '', $table);
203 if (!preg_match('/uts\d+user/', $table)) {
204 db_query('INSERT INTO ' . $table . '
205 SELECT *
206 FROM ' . $table_original);
207 }
208 else {
209 // Make special exception for user table. Don't import user ID 0 due to issues.
210 db_query('INSERT INTO ' . $table . '
211 SELECT *
212 FROM ' . $table_original . '
213 WHERE ' . $table_original . '.uid != 0');
214 }
215 }
216 file_put_contents('output.txt', "" . $table_original . "\n", FILE_APPEND);
217 }
218
219 // Make proctor as disabled so that it when enabled it will install menu items.
220 db_query("UPDATE {system}
221 SET status = %d
222 WHERE name = '%s'", 0, 'uts_proctor');
223 }
224
225 /**
226 * Destroy prefixed environment.
227 *
228 * @param string $prefix Prefix of environment to destroy.
229 */
230 function uts_environment_destroy($prefix) {
231 global $db_prefix;
232
233 // Delete temporary files directory and reset files directory path.
234 uts_environment_destroy_directory(file_directory_path() . "/$prefix");
235
236 // Remove all prefixed tables (all the tables in the schema).
237 $tables = uts_environment_get_like_tables($prefix);
238 $ret = array();
239 foreach ($tables as $table) {
240 if (!preg_match('/^uts_.*$/', $table)) {
241 // UTS tables won't exist since they never have their hook_install() called.
242 db_drop_table($ret, $table);
243 }
244 }
245 }
246
247 /**
248 * Perform operations on modules, either enable or disable. Executes
249 * system_modules form to ensure that all caches are cleared properly.
250 *
251 * @param string $prefix Prefix of environment to enable modules in.
252 * @param string $modules Comma separated list of modules.
253 * @param boolean $enable Enable/Disable list of modules.
254 */
255 function uts_environment_modules($prefix, $modules, $enable) {
256 global $db_prefix;
257
258 // Switch database.
259 $db_prefix_original = $db_prefix;
260 $db_prefix = $prefix;
261 uts_environment_rebuild_caches();
262
263 // Prepare form_state array.
264 $modules = explode(',', $modules);
265 $form_state = array();
266 foreach ($modules as $module) {
267 $form_state['values']["status[$module]"] = $enable;
268 }
269
270 $reserved_modules = module_list(TRUE, FALSE);
271 foreach ($reserved_modules as $module) {
272 $form_state['values']["status[$module]"] = TRUE;
273 }
274
275 // Execute system_modules form to ensure that all caches are cleared properly.
276 require_once drupal_get_path('module', 'system') . '/system.admin.inc';
277 drupal_execute('system_modules', $form_state);
278
279 // Changes don't get saved so force them.
280 if ($enable) {
281 module_enable($modules);
282 }
283 else {
284 module_disable($modules);
285 }
286 uts_environment_rebuild_caches();
287
288 // Restore original environment.
289 $db_prefix = $db_prefix_original;
290 uts_environment_rebuild_caches();
291 }
292
293 /**
294 * Refresh all caches to ensure that static variables reflect current environment.
295 */
296 function uts_environment_rebuild_caches() {
297 global $conf;
298 cache_clear_all();
299 $conf = variable_init();
300
301 module_list(TRUE, FALSE);
302 module_rebuild_cache();
303 drupal_flush_all_caches();
304 menu_rebuild();
305
306 actions_synchronize();
307 }
308
309 /**
310 * Remove all files from specified directory and then remove directory.
311 *
312 * @param string $path Directory path.
313 */
314 function uts_environment_destroy_directory($path) {
315 if (is_dir($path)) {
316 $files = scandir($path);
317 foreach ($files as $file) {
318 if ($file != '.' && $file != '..') {
319 $file_path = "$path/$file";
320 if (is_dir($file_path)) {
321 uts_environment_destroy_directory($file_path);
322 }
323 else {
324 file_delete($file_path);
325 }
326 }
327 }
328 rmdir($path);
329 }
330 }
331
332 /**
333 * Copy a directory recursively to another location.
334 *
335 * @param string $source Source directory location.
336 * @param string $destination Destination directory location.
337 */
338 function uts_environment_copy_directory($source, $destination) {
339 if (is_dir($source)) {
340 if (!file_exists($destination)) {
341 mkdir($destination);
342 }
343 $files = scandir($source);
344 foreach ($files as $file) {
345 if ($file != '.' && $file != '..') {
346 $file_path = "$source/$file";
347 $new_path = str_replace($source . '/', $destination . '/', $file_path);
348 if (is_dir($file_path)) {
349 uts_environment_copy_directory($file_path, $new_path);
350 }
351 else {
352 copy($file_path, $new_path);
353 }
354 }
355 }
356 }
357 }
358
359 /**
360 * Find all tables that are like the specified base table name.
361 *
362 * @param string $base_table Base table name.
363 * @param boolean $count Return the table count instead of list of tables.
364 * @return mixed Array of matching tables or count of tables.
365 */
366 function uts_environment_get_like_tables($base_table = 'uts', $count = FALSE) {
367 global $db_url, $db_prefix;
368 $url = parse_url($db_url);
369 $database = substr($url['path'], 1);
370 $select = $count ? 'COUNT(table_name)' : 'table_name';
371 $result = db_query("SELECT $select
372 FROM information_schema.tables
373 WHERE table_schema = '%s'
374 AND table_name LIKE '%s%'", $database, $db_prefix . $base_table);
375
376 if ($count) {
377 return db_result($result);
378 }
379 $tables = array();
380 while ($table = db_result($result)) {
381 $tables[] = $table;
382 }
383 return $tables;
384 }
385
386 /**
387 * Create table to list all the environments.
388 *
389 * @return string HTML output.
390 */
391 function uts_environments() {
392 $environments = uts_environments_load();
393 $header = array(t('Prefix'), t('Name'), t('Description'), t('Operations'));
394 $rows = array();
395 foreach ($environments as $environment) {
396 $row = array();
397 $row[] = $environment->prefix;
398 $row[] = $environment->title;
399 $row[] = $environment->body;
400 $row[] = uts_render_operations(uts_environment_operations($environment));
401
402 $rows[] = $row;
403 }
404
405 if (empty($rows)) {
406 return t('No environments to display.');
407 }
408 return theme('table', $header, $rows);
409 }
410
411 /**
412 * Get an array containing the environment operation links.
413 *
414 * @param $environment Environment object.
415 * @return Array of links.
416 */
417 function uts_environment_operations($environment) {
418 $links = array();
419 $links['environment_edit'] = array(
420 'title' => t('edit'),
421 'href' => "admin/uts/environments/$environment->nid/edit"
422 );
423 $links['environment_open'] = array(
424 'title' => t('open'),
425 'href' => "admin/uts/environments/$environment->nid/open"
426 );
427 $links['environment_delete'] = array(
428 'title' => t('delete'),
429 'href' => "admin/uts/environments/$environment->nid/delete"
430 );
431
432 return $links;
433 }
434
435 /**
436 * Load all environments.
437 *
438 * @return array List of environment objects.
439 */
440 function uts_environments_load() {
441 $result = db_query('SELECT nid
442 FROM {uts_environment}');
443
444 $environments = array();
445 while ($environment = db_result($result)) {
446 $environments[] = node_load($environment);
447 }
448 return $environments;
449 }
450
451 /**
452 * Open the specified environment. Only to be used with base environments.
453 *
454 * @param object $environment Environment node object.
455 */
456 function uts_environment_open($environment) {
457 uts_session_restore($environment->prefix);
458 drupal_goto();
459 }

  ViewVC Help
Powered by ViewVC 1.1.2