### Eclipse Workspace Patch 1.0 #P Test Drupal 6 Index: update.php =================================================================== RCS file: /cvs/drupal/drupal/update.php,v retrieving revision 1.216 diff -u -r1.216 update.php --- update.php 13 Apr 2007 08:56:57 -0000 1.216 +++ update.php 20 Apr 2007 20:35:53 -0000 @@ -283,37 +283,36 @@ * The module whose update will be run. * @param $number * The update number to run. - * - * @return - * TRUE if the update was finished. Otherwise, FALSE. + * @param $a + * The batch callback working array */ -function update_data($module, $number) { - $ret = module_invoke($module, 'update_'. $number); +function update_data($module, $number, &$a) { + $function = $module .'_update_'. $number; + if (function_exists($function)) { + $ret = $function(&$a['sandbox']); + } + // Assume the update finished unless the update results indicate otherwise. - $finished = 1; + $a['finished'] = 1; if (isset($ret['#finished'])) { - $finished = $ret['#finished']; + $a['finished'] = $ret['#finished']; unset($ret['#finished']); } - // Save the query and results for display by update_finished_page(). - if (!isset($_SESSION['update_results'])) { - $_SESSION['update_results'] = array(); + if (!isset($results[$module])) { + $a['results'][$module] = array(); } - if (!isset($_SESSION['update_results'][$module])) { - $_SESSION['update_results'][$module] = array(); + if (!isset($results[$module][$number])) { + $a['results'][$module][$number] = array(); } - if (!isset($_SESSION['update_results'][$module][$number])) { - $_SESSION['update_results'][$module][$number] = array(); - } - $_SESSION['update_results'][$module][$number] = array_merge($_SESSION['update_results'][$module][$number], $ret); + $a['results'][$module][$number] = array_merge($a['results'][$module][$number], $ret); - if ($finished == 1) { + if ($a['finished'] == 1) { // Update the installed version drupal_set_installed_schema_version($module, $number); } - return $finished; + return t('Updating @module module', array('@module' => $module)); } function update_selection_page() { @@ -322,7 +321,7 @@ drupal_set_title('Drupal database update'); // Prevent browser from using cached drupal.js or update.js - drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE); + //drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE); $output .= drupal_get_form('update_script_selection_form'); update_task_list('select'); @@ -377,7 +376,7 @@ return $form; } -function update_update_page() { +function update_set_batch() { // Set the installed version so updates start at the correct place. foreach ($_POST['start'] as $module => $version) { drupal_set_installed_schema_version($module, $version - 1); @@ -386,146 +385,39 @@ if ($version <= $max_version) { foreach ($updates as $update) { if ($update >= $version) { - $_SESSION['update_remaining'][] = array('module' => $module, 'version' => $update); + $operations[] = array( + 'callback' => 'update_data', + 'arguments' => array($module, $update), + ); } } } } - - // Keep track of total number of updates - if (isset($_SESSION['update_remaining'])) { - $_SESSION['update_total'] = count($_SESSION['update_remaining']); - } - - if ($_POST['has_js']) { - return update_progress_page(); - } - else { - return update_progress_page_nojs(); + if ($operations) { + global $base_url; + $batch = array( + 'title' => 'Updating', + 'init_message' => 'Starting updates', + 'error_message' => 'An unrecoverable error has occured. You can find the error message below. It is advised to copy it to the clipboard for reference.', + 'finished' => 'update_finished', + 'operations' => $operations, + ); + batch_open($batch, $base_url .'/update.php', $base_url .'/update.php?op=results'); } } -function update_progress_page() { - // Prevent browser from using cached drupal.js or update.js - drupal_add_js('misc/progress.js', 'core', 'header', FALSE, TRUE); - drupal_add_js('misc/update.js', 'core', 'header', FALSE, TRUE); - - drupal_set_title('Updating'); - update_task_list('run'); - $output = '
'; - $output .= '

Please wait while your site is being updated.

'; - return $output; -} - -/** - * Perform updates for one second or until finished. - * - * @return - * An array indicating the status after doing updates. The first element is - * the overall percentage finished. The second element is a status message. - */ -function update_do_updates() { - while (isset($_SESSION['update_remaining']) && ($update = reset($_SESSION['update_remaining']))) { - $update_finished = update_data($update['module'], $update['version']); - if ($update_finished == 1) { - // Dequeue the completed update. - unset($_SESSION['update_remaining'][key($_SESSION['update_remaining'])]); - $update_finished = 0; // Make sure this step isn't counted double - } - if (timer_read('page') > 1000) { - break; - } - } - - if ($_SESSION['update_total']) { - $percentage = floor(($_SESSION['update_total'] - count($_SESSION['update_remaining']) + $update_finished) / $_SESSION['update_total'] * 100); - } - else { - $percentage = 100; - } - - // When no updates remain, clear the caches in case the data has been updated. - if (!isset($update['module'])) { - cache_clear_all('*', 'cache', TRUE); - cache_clear_all('*', 'cache_page', TRUE); - cache_clear_all('*', 'cache_menu', TRUE); - cache_clear_all('*', 'cache_filter', TRUE); - drupal_clear_css_cache(); - } - - return array($percentage, isset($update['module']) ? 'Updating '. $update['module'] .' module' : 'Updating complete'); -} - -/** - * Perform updates for the JS version and return progress. - */ -function update_do_update_page() { - global $conf; - - // HTTP Post required - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - drupal_set_message('HTTP Post is required.', 'error'); - drupal_set_title('Error'); - return ''; - } - - // Error handling: if PHP dies, the output will fail to parse as JSON, and - // the Javascript will tell the user to continue to the op=error page. - list($percentage, $message) = update_do_updates(); - print drupal_to_js(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message)); -} - -/** - * Perform updates for the non-JS version and return the status page. - */ -function update_progress_page_nojs() { - drupal_set_title('Updating'); - update_task_list('run'); - - $new_op = 'do_update_nojs'; - if ($_SERVER['REQUEST_METHOD'] == 'POST') { - // This is the first page so return some output immediately. - $percentage = 0; - $message = 'Starting updates'; - } - else { - // This is one of the later requests: do some updates first. - - // Error handling: if PHP dies due to a fatal error (e.g. non-existant - // function), it will output whatever is in the output buffer, - // followed by the error message. So, we put an explanation in the - // buffer to guide the user when an error happens. - ob_start(); - $fallback = '

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 update summary.

'; - $fallback = theme('maintenance_page', $fallback, FALSE); - - // We strip the end of the page using a marker in the template, so any - // additional HTML output by PHP shows up inside the page rather than - // below it. While this causes invalid HTML, the same would be true if - // we didn't, as content is not allowed to appear after anyway. - list($fallback) = explode('', $fallback); - print $fallback; - - // Do updates - list($percentage, $message) = update_do_updates(); - if ($percentage == 100) { - $new_op = 'finished'; - } - - // Updates were successful; wipe the output buffer as it's unneeded. - ob_end_clean(); - } - - drupal_set_html_head(''); - $output = theme('progress_bar', $percentage, $message); - $output .= '

Updating your site will take a few seconds.

'; +function update_finished($success, $results) { + // clear the caches in case the data has been updated. + cache_clear_all('*', 'cache', TRUE); + cache_clear_all('*', 'cache_page', TRUE); + cache_clear_all('*', 'cache_filter', TRUE); + drupal_clear_css_cache(); - // Note: do not output drupal_set_message()s until the summary page. - print theme('maintenance_page', $output, FALSE); - return NULL; + $_SESSION['update_results'] = $results; + $_SESSION['update_success'] = $success; } -function update_finished_page($success) { +function update_finished_page() { drupal_set_title('Drupal database update'); // NOTE: we can't use l() here because the URL would point to 'update.php?q=admin'. $links[] = 'Main page'; @@ -533,11 +425,12 @@ update_task_list(); // Report end result - if ($success) { + if ($_SESSION['update_success']) { $output = '

Updates were attempted. If you see no failures below, you may proceed happily to the administration pages. Otherwise, you may need to update your database manually. All errors have been logged.

'; } else { - $update = reset($_SESSION['update_remaining']); + // TODO + $update = reset($results['update_remaining']); $output = '

The update process was aborted prematurely while running update #'. $update['version'] .' in '. $update['module'] .'.module. All other errors have been logged. You may need to check the watchdog database table manually.

'; } @@ -571,8 +464,9 @@ } } $output .= ''; - unset($_SESSION['update_results']); } + unset($_SESSION['update_results']); + unset($_SESSION['update_success']); return $output; } @@ -780,6 +674,41 @@ } /** + * Create the batch table. + * + * This is part of the Drupal 5.x to 6.x migration. + */ +function update_create_batch_table() { + + // If cache_filter exists, update is not necessary + if (db_table_exists('batch')) { + return; + } + + $ret = array(); + switch ($GLOBALS['db_type']) { + case 'mysql': + case 'mysqli': + $ret[] = update_sql("CREATE TABLE {batch} ( + bid int(11) NOT NULL, + timestamp int(11) NOT NULL, + batch longtext, + PRIMARY KEY (bid) + ) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); + break; + case 'pgsql': + $ret[] = update_sql("CREATE TABLE {batch} ( + bid int NOT NULL default '0', + timestamp int NOT NULL default '0', + batch text, + PRIMARY KEY (bid) + )"); + break; + } + return $ret; +} + +/** * Add the update task list to the current page. */ function update_task_list($active = NULL) { @@ -808,6 +737,7 @@ // variable_(get|set), which only works after a full bootstrap. update_fix_access_table(); update_create_cache_tables(); +update_create_batch_table(); // Turn error reporting back on. From now on, only fatal errors (which are // not passed through the error handler) will cause a message to be printed. @@ -826,39 +756,39 @@ $op = isset($_REQUEST['op']) ? $_REQUEST['op'] : ''; switch ($op) { - case 'Update': - $output = update_update_page(); - break; - - case 'finished': - $output = update_finished_page(TRUE); - break; - - case 'error': - $output = update_finished_page(FALSE); + // update.php ops + case '': + $output = update_info_page(); break; - case 'do_update': - $output = update_do_update_page(); + case 'selection': + $output = update_selection_page(); break; - case 'do_update_nojs': - $output = update_progress_page_nojs(); + case 'Update': + update_set_batch(); + batch_execute(); break; - case 'selection': - $output = update_selection_page(); + case 'results': + $output = update_finished_page(); break; + // Regular batch ops : defer to batch.inc default: - $output = update_info_page(); + update_task_list('run'); + $output = _batch_page(); break; } } else { $output = update_access_denied_page(); } - if (isset($output)) { - print theme('maintenance_page', $output); + if ($output === FALSE) { + // TODO : ?? + } + else { + print theme('maintenance_page', $output); + } }