/[drupal]/contributions/modules/versioncontrol_project/cvs_to_versioncontrol_project_update.php
ViewVC logotype

Contents of /contributions/modules/versioncontrol_project/cvs_to_versioncontrol_project_update.php

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


Revision 1.8 - (show annotations) (download) (as text)
Sun Jan 4 14:18:38 2009 UTC (10 months, 3 weeks ago) by jpetso
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-RC1, DRUPAL-6--1-0-RC2, DRUPAL-6--1-0-BETA2, DRUPAL-6--1-0-BETA1, HEAD
Changes since 1.7: +4 -4 lines
File MIME type: text/x-php
A few minor tweaks to please Coder. Also, rename the watchdog menu path
to the new one in D6.
1 <?php
2 // $Id: cvs_to_versioncontrol_project_update.php,v 1.7 2008/01/11 13:42:25 thehunmonkgroup Exp $
3
4 /**
5 * @file
6 * Administrative page for handling updates from cvs module to
7 * versioncontrol_project module.
8 *
9 * Place this file in the root of your Drupal installation (ie, the same
10 * directory as index.php), point your browser to
11 * "http://yoursite/cvs_to_versioncontrol_project_update.php" and follow the
12 * instructions.
13 *
14 * If you are not logged in as administrator, you will need to modify the access
15 * check statement below. Change the TRUE to a FALSE to disable the access
16 * check. After finishing the upgrade, be sure to open this file and change the
17 * FALSE back to a TRUE!
18 */
19
20 // Enforce access checking?
21 $access_check = TRUE;
22
23 /**
24 * Convert project commit access data.
25 */
26 function cvs_to_versioncontrol_project_update_1() {
27
28 // This determines how many users will be processed in each batch run. A reasonable
29 // default has been chosen, but you may want to tweak depending on your setup.
30 $limit = 100;
31
32 // Multi-part update
33 if (!isset($_SESSION['cvs_to_versioncontrol_project_update_1'])) {
34 $_SESSION['cvs_to_versioncontrol_project_update_1'] = 0;
35 $_SESSION['cvs_to_versioncontrol_project_update_1_max'] = db_result(db_query("SELECT COUNT(*) FROM {cvs_project_maintainers}"));
36 }
37
38 // Pull the next batch of users.
39 $comaintainers = db_query_range("SELECT nid, uid FROM {cvs_project_maintainers} ORDER BY nid, uid", $_SESSION['cvs_to_versioncontrol_project_update_1'], $limit);
40
41 // Loop through each co-maintainer.
42 while ($comaintainer = db_fetch_object($comaintainers)) {
43 db_query("INSERT INTO {versioncontrol_project_comaintainers} (nid, uid) VALUES (%d, %d)", $comaintainer->nid, $comaintainer->uid);
44 $_SESSION['cvs_to_versioncontrol_project_update_1']++;
45 }
46
47 if ($_SESSION['cvs_to_versioncontrol_project_update_1'] >= $_SESSION['cvs_to_versioncontrol_project_update_1_max']) {
48 $count = $_SESSION['cvs_to_versioncontrol_project_update_1_max'];
49 unset($_SESSION['cvs_to_versioncontrol_project_update_1']);
50 unset($_SESSION['cvs_to_versioncontrol_project_update_1_max']);
51 return array(array('success' => TRUE, 'query' => t('Converted @count project co-maintainer entries.', array('@count' => $count))));
52 }
53 return array('#finished' => $_SESSION['cvs_to_versioncontrol_project_update_1'] / $_SESSION['cvs_to_versioncontrol_project_update_1_max']);
54 }
55
56 /**
57 * Convert project repository data.
58 */
59 function cvs_to_versioncontrol_project_update_2() {
60
61 // This determines how many projects will be processed in each batch run. A reasonable
62 // default has been chosen, but you may want to tweak depending on your setup.
63 $limit = 100;
64
65 // Multi-part update
66 if (!isset($_SESSION['cvs_to_versioncontrol_project_update_2'])) {
67 $_SESSION['cvs_to_versioncontrol_project_update_2'] = 0;
68 $_SESSION['cvs_to_versioncontrol_project_update_2_max'] = db_result(db_query("SELECT COUNT(*) FROM {cvs_projects}"));
69 }
70
71 // Pull the next batch of users.
72 $projects = db_query_range("SELECT p.nid, p.rid, p.directory, r.modules FROM {cvs_projects} p INNER JOIN {cvs_repositories} r ON p.rid = r.rid ORDER BY p.nid", $_SESSION['cvs_to_versioncontrol_project_update_2'], $limit);
73
74 // Loop through each project.
75 while ($project = db_fetch_object($projects)) {
76 // Add the repo module, and chop off the trailing slash.
77 $directory = '/'. trim($project->modules) . drupal_substr($project->directory, 0, drupal_strlen($project->directory) - 1);
78 db_query("INSERT INTO {versioncontrol_project_projects} (nid, repo_id, directory) VALUES (%d, %d, '%s')", $project->nid, $project->rid, $directory);
79 $_SESSION['cvs_to_versioncontrol_project_update_2']++;
80 }
81
82 if ($_SESSION['cvs_to_versioncontrol_project_update_2'] >= $_SESSION['cvs_to_versioncontrol_project_update_2_max']) {
83 $count = $_SESSION['cvs_to_versioncontrol_project_update_2_max'];
84 unset($_SESSION['cvs_to_versioncontrol_project_update_2']);
85 unset($_SESSION['cvs_to_versioncontrol_project_update_2_max']);
86 return array(array('success' => TRUE, 'query' => t('Converted @count project repository entries.', array('@count' => $count))));
87 }
88 return array('#finished' => $_SESSION['cvs_to_versioncontrol_project_update_2'] / $_SESSION['cvs_to_versioncontrol_project_update_2_max']);
89 }
90
91 /**
92 * Perform one update and store the results which will later be displayed on
93 * the finished page.
94 *
95 * @param $module
96 * The module whose update will be run.
97 * @param $number
98 * The update number to run.
99 *
100 * @return
101 * TRUE if the update was finished. Otherwise, FALSE.
102 */
103 function update_data($module, $number) {
104
105 $function = "cvs_to_versioncontrol_project_update_$number";
106 $ret = $function();
107
108 // Assume the update finished unless the update results indicate otherwise.
109 $finished = 1;
110 if (isset($ret['#finished'])) {
111 $finished = $ret['#finished'];
112 unset($ret['#finished']);
113 }
114
115 // Save the query and results for display by update_finished_page().
116 if (!isset($_SESSION['update_results'])) {
117 $_SESSION['update_results'] = array();
118 }
119 if (!isset($_SESSION['update_results'][$module])) {
120 $_SESSION['update_results'][$module] = array();
121 }
122 if (!isset($_SESSION['update_results'][$module][$number])) {
123 $_SESSION['update_results'][$module][$number] = array();
124 }
125 $_SESSION['update_results'][$module][$number] = array_merge($_SESSION['update_results'][$module][$number], $ret);
126
127 return $finished;
128 }
129
130 function update_selection_page() {
131 $output = '';
132 $output .= '<p>Click Update to start the update process.</p>';
133
134 drupal_set_title('CVS module to Version Control/Project Node integration module update');
135 // Use custom update.js.
136 drupal_add_js(update_js(), 'inline');
137 $output .= drupal_get_form('update_script_selection_form');
138
139 return $output;
140 }
141
142 function update_script_selection_form() {
143 $form = array();
144
145 $form['has_js'] = array(
146 '#type' => 'hidden',
147 '#default_value' => FALSE,
148 '#attributes' => array('id' => 'edit-has_js'),
149 );
150 $form['submit'] = array(
151 '#type' => 'submit',
152 '#value' => 'Update',
153 );
154 return $form;
155 }
156
157 function update_update_page() {
158 // Set the installed version so updates start at the correct place.
159 $_SESSION['update_remaining'][] = array('module' => 'versioncontrol_project', 'version' => 1);
160 $_SESSION['update_remaining'][] = array('module' => 'versioncontrol_project', 'version' => 2);
161
162 // Keep track of total number of updates
163 if (isset($_SESSION['update_remaining'])) {
164 $_SESSION['update_total'] = count($_SESSION['update_remaining']);
165 }
166
167 if ($_POST['has_js']) {
168 return update_progress_page();
169 }
170 else {
171 return update_progress_page_nojs();
172 }
173 }
174
175 function update_progress_page() {
176 // Prevent browser from using cached drupal.js or update.js
177 drupal_add_js('misc/progress.js', 'core', 'header', FALSE, TRUE);
178 drupal_add_js(update_js(), 'inline');
179
180 drupal_set_title('Updating');
181 $output = '<div id="progress"></div>';
182 $output .= '<p id="wait">Please wait while your site is being updated.</p>';
183 return $output;
184 }
185
186 /**
187 * Can't include misc/update.js, because it makes a direct call to update.php.
188 *
189 * @return unknown
190 */
191 function update_js() {
192 return "
193 if (Drupal.jsEnabled) {
194 $(document).ready(function() {
195 $('#edit-has-js').each(function() { this.value = 1; });
196 $('#progress').each(function () {
197 var holder = this;
198
199 // Success: redirect to the summary.
200 var updateCallback = function (progress, status, pb) {
201 if (progress == 100) {
202 pb.stopMonitoring();
203 window.location = window.location.href.split('op=')[0] +'op=finished';
204 }
205 }
206
207 // Failure: point out error message and provide link to the summary.
208 var errorCallback = function (pb) {
209 var div = document.createElement('p');
210 div.className = 'error';
211 $(div).html('An unrecoverable error has occured. You can find the error message below. It is advised to copy it to the clipboard for reference. Please continue to the <a href=\"cvs_to_versioncontrol_project_update.php?op=error\">update summary</a>');
212 $(holder).prepend(div);
213 $('#wait').hide();
214 }
215
216 var progress = new Drupal.progressBar('updateprogress', updateCallback, \"POST\", errorCallback);
217 progress.setProgress(-1, 'Starting updates');
218 $(holder).append(progress.element);
219 progress.startMonitoring('cvs_to_versioncontrol_project_update.php?op=do_update', 0);
220 });
221 });
222 }
223 ";
224 }
225
226 /**
227 * Perform updates for one second or until finished.
228 *
229 * @return
230 * An array indicating the status after doing updates. The first element is
231 * the overall percentage finished. The second element is a status message.
232 */
233 function update_do_updates() {
234 while (isset($_SESSION['update_remaining']) && ($update = reset($_SESSION['update_remaining']))) {
235 $update_finished = update_data($update['module'], $update['version']);
236 if ($update_finished == 1) {
237 // Dequeue the completed update.
238 unset($_SESSION['update_remaining'][key($_SESSION['update_remaining'])]);
239 $update_finished = 0; // Make sure this step isn't counted double
240 }
241 if (timer_read('page') > 1000) {
242 break;
243 }
244 }
245
246 if ($_SESSION['update_total']) {
247 $percentage = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining']) + $update_finished) / $_SESSION['update_total'] * 100);
248 }
249 else {
250 $percentage = 100;
251 }
252
253 // When no updates remain, clear the caches in case the data has been updated.
254 if (!isset($update['module'])) {
255 cache_clear_all('*', 'cache', TRUE);
256 cache_clear_all('*', 'cache_page', TRUE);
257 cache_clear_all('*', 'cache_menu', TRUE);
258 cache_clear_all('*', 'cache_filter', TRUE);
259 drupal_clear_css_cache();
260 }
261
262 return array($percentage, isset($update['module']) ? 'Updating '. $update['module'] .' module' : 'Updating complete');
263 }
264
265 /**
266 * Perform updates for the JS version and return progress.
267 */
268 function update_do_update_page() {
269 global $conf;
270
271 // HTTP Post required
272 if ($_SERVER['REQUEST_METHOD'] != 'POST') {
273 drupal_set_message('HTTP Post is required.', 'error');
274 drupal_set_title('Error');
275 return '';
276 }
277
278 // Error handling: if PHP dies, the output will fail to parse as JSON, and
279 // the Javascript will tell the user to continue to the op=error page.
280 list($percentage, $message) = update_do_updates();
281 print drupal_to_js(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
282 }
283
284 /**
285 * Perform updates for the non-JS version and return the status page.
286 */
287 function update_progress_page_nojs() {
288 drupal_set_title('Updating');
289
290 $new_op = 'do_update';
291 if ($_SERVER['REQUEST_METHOD'] == 'GET') {
292 // Error handling: if PHP dies, it will output whatever is in the output
293 // buffer, followed by the error message.
294 ob_start();
295 $fallback = '<p class="error">An unrecoverable error has occurred. You can find the error message below. It is advised to copy it to the clipboard for reference. Please continue to the <a href="cvs_to_versioncontrol_project_update.php?op=error">update summary</a>.</p>';
296 print theme('maintenance_page', $fallback, FALSE, TRUE);
297
298 list($percentage, $message) = update_do_updates();
299 if ($percentage == 100) {
300 $new_op = 'finished';
301 }
302
303 // Updates successful; remove fallback
304 ob_end_clean();
305 }
306 else {
307 // Abort the update if the necessary modules aren't installed.
308 if (!module_exists('versioncontrol') || !module_exists('versioncontrol_project') || !module_exists('cvs')) {
309 print update_finished_page(FALSE);
310 return NULL;
311 }
312
313 // This is the first page so return some output immediately.
314 $percentage = 0;
315 $message = 'Starting updates';
316 }
317
318 drupal_set_html_head('<meta http-equiv="Refresh" content="0; URL=cvs_to_versioncontrol_project_update.php?op='. $new_op .'">');
319 $output = theme('progress_bar', $percentage, $message);
320 $output .= '<p>Updating your site will take a few seconds.</p>';
321
322 // Note: do not output drupal_set_message()s until the summary page.
323 print theme('maintenance_page', $output, FALSE);
324 return NULL;
325 }
326
327 function update_finished_page($success) {
328 drupal_set_title('CVS module to Version Control/Project Node integration module update.');
329 // NOTE: we can't use l() here because the URL would point to 'update.php?q=admin'.
330 $links[] = '<a href="'. base_path() .'">Main page</a>';
331 $links[] = '<a href="'. base_path() .'?q=admin">Administration pages</a>';
332
333 // Report end result
334 if ($success) {
335 $output = '<p>Updates were attempted. If you see no failures below, you should remove cvs_to_versioncontrol_project_update.php from your Drupal root directory. Otherwise, you may need to update your database manually. All errors have been <a href="index.php?q=admin/reports/dblog">logged</a>.</p>';
336 }
337 else {
338 $output = '<p class="error">The update process was aborted prematurely. All other errors have been <a href="index.php?q=admin/reports/dblog">logged</a>. You may need to check the <code>watchdog</code> database table manually.</p>';
339 $output .= '<p class="error">This has most likely occurred because the Version Control/Project Node integration module or the CVS module is not <a href=\"index.php?q=admin/build/modules\">properly installed</a>.</p>';
340 }
341
342 $output .= theme('item_list', $links);
343
344 if ($success) {
345 $output .= "<h4>Some things to take care of now:</h4>\n";
346 $output .= "<ul>\n";
347 $output .= "<li>Visit the <a href=\"index.php?q=admin/project/versioncontrol-settings/project\">Version control settings page for project integration</a>, and make any necessary adjustments.</li>\n";
348 $output .= "<li>If you're all done with the old CVS module, <a href=\"index.php?q=admin/build/modules\">disable/uninstall it</a>.</li>\n";
349 $output .= "</ul>\n";
350 }
351
352 // Output a list of queries executed
353 if (!empty($_SESSION['update_results'])) {
354 $output .= '<div id="update-results">';
355 $output .= '<h2>The following queries were executed</h2>';
356 foreach ($_SESSION['update_results'] as $module => $updates) {
357 $output .= '<h3>'. $module .' module</h3>';
358 foreach ($updates as $number => $queries) {
359 $output .= '<h4>Update #'. $number .'</h4>';
360 $output .= '<ul>';
361 foreach ($queries as $query) {
362 if ($query['success']) {
363 $output .= '<li class="success">'. $query['query'] .'</li>';
364 }
365 else {
366 $output .= '<li class="failure"><strong>Failed:</strong> '. $query['query'] .'</li>';
367 }
368 }
369 if (!count($queries)) {
370 $output .= '<li class="none">No queries</li>';
371 }
372 $output .= '</ul>';
373 }
374 }
375 $output .= '</div>';
376 unset($_SESSION['update_results']);
377 }
378
379 return $output;
380 }
381
382 function update_info_page() {
383 drupal_set_title('CVS module to Version Control/Project Node integration module update.');
384 $output = "<ol>\n";
385 $output .= "<li>Use this script to <strong>upgrade an existing CVS module installation to the Version Control/Project Node integration module</strong>. You don't need this script when installing Version Control/Project Node integration from scratch.</li>";
386 $output .= "<li>Before doing anything, backup your database. This process will change your database and its values.</li>\n";
387 $output .= "<li>Make sure the Version Control/Project Node integration module and the old CVS module are <a href=\"index.php?q=admin/build/modules\">properly installed</a>.</li>\n";
388 $output .= "<li>Make sure this file is placed in the root of your Drupal installation (the same directory that index.php is in) and <a href=\"cvs_to_versioncontrol_project_update.php?op=selection\">run the database upgrade script</a>. <strong>Don't upgrade your database twice as it will cause problems!</strong></li>\n";
389 $output .= "</ol>";
390 $output .= "<h2>Caveats</h2>\n";
391 $output .= "<ul>\n";
392 $output .= "<li>If a repository entry in the old CVS module lists more than one module in the 'Modules' field (at admin/project/cvs-repositories/edit/[repo_id]), the script will not correctly generate the new project paths to the repository directories (listed on project nodes, edit page, 'Version control integration' fieldset, 'Project directory').</li>\n";
393 $output .= "</ul>\n";
394 return $output;
395 }
396
397 function update_access_denied_page() {
398 drupal_set_title('Access denied');
399 return '<p>Access denied. You are not authorized to access this page. Please log in as the admin user (the first user you created). If you cannot log in, you will have to edit <code>cvs_to_versioncontrol_project_update.php</code> to bypass this access check. To do this:</p>
400 <ol>
401 <li>With a text editor find the cvs_to_versioncontrol_project_update.php file on your system. It should be in the main Drupal directory that you installed all the files into.</li>
402 <li>There is a line near top of cvs_to_versioncontrol_project_update.php that says <code>$access_check = TRUE;</code>. Change it to <code>$access_check = FALSE;</code>.</li>
403 <li>As soon as the update is done, you should remove cvs_to_versioncontrol_project_update.php from your main installation directory.</li>
404 </ol>';
405 }
406
407 include_once './includes/bootstrap.inc';
408
409 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
410 drupal_maintenance_theme();
411
412 // Access check:
413 if (($access_check == FALSE) || ($user->uid == 1)) {
414
415 $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
416 switch ($op) {
417 case 'Update':
418 $output = update_update_page();
419 break;
420
421 case 'finished':
422 $output = update_finished_page(TRUE);
423 break;
424
425 case 'error':
426 $output = update_finished_page(FALSE);
427 break;
428
429 case 'do_update':
430 $output = update_do_update_page();
431 break;
432
433 case 'do_update_nojs':
434 $output = update_progress_page_nojs();
435 break;
436
437 case 'selection':
438 $output = update_selection_page();
439 break;
440
441 default:
442 $output = update_info_page();
443 break;
444 }
445 }
446 else {
447 $output = update_access_denied_page();
448 }
449
450 if (isset($output)) {
451 print theme('maintenance_page', $output);
452 }

  ViewVC Help
Powered by ViewVC 1.1.2