- Patch #149593 by yched: batch API fixes.

6.x
Dries Buytaert 2007-07-20 05:44:13 +00:00
parent a47643cb09
commit eb65040c5e
3 changed files with 60 additions and 25 deletions

View File

@ -22,13 +22,14 @@ function _batch_page() {
register_shutdown_function('_batch_shutdown');
$op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
$output = NULL;
switch ($op) {
case 'start':
$output = _batch_start();
break;
case 'do':
$output = _batch_do();
_batch_do();
break;
case 'do_nojs':
@ -97,9 +98,7 @@ function _batch_do() {
list($percentage, $message) = _batch_process();
drupal_set_header('Content-Type: text/plain; charset=utf-8');
print drupal_to_js(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
exit();
drupal_json(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
}
/**
@ -159,6 +158,10 @@ function _batch_process() {
$batch =& batch_get();
$current_set =& _batch_current_set();
if ($batch['progressive']) {
timer_start('batch_processing');
}
while (!$current_set['success']) {
$finished = 1;
$task_message = '';
@ -169,33 +172,51 @@ function _batch_process() {
}
if ($finished == 1) {
// Make sure this step isn't counted double.
// Make sure this step isn't counted double when computing $current.
$finished = 0;
// Remove the operation, and clear the sandbox to reduce the stored data.
// Remove the operation and clear the sandbox.
array_shift($current_set['operations']);
$current_set['sandbox'] = array();
}
// Make sure we display progress information about a batch set that
// actually has operations, and not about a 'control' set (form submit
// handler).
$remaining = count($current_set['operations']);
$progress_message = $current_set['progress_message'];
$total = $current_set['total'];
// If the batch set is completed, browse through the remaining sets
// until we find one that actually has operations.
// If the batch set is completed, browse through the remaining sets,
// executing 'control sets' (stored submit handlers) along the way - this
// might in turn insert new batch sets. Stop when we find a set that
// actually has operations.
$set_changed = FALSE;
$old_set = $current_set;
while (empty($current_set['operations']) && ($current_set['success'] = TRUE) && _batch_next_set()) {
$current_set =& _batch_current_set();
$set_changed = TRUE;
}
// At this point, either $current_set is a 'real' batch set (has operations),
// or all sets have been completed.
// Progressive mode : stop after 1 second
if ($batch['progressive'] && timer_read('page') > 1000) {
// Progressive mode : stop after 1 second.
if ($batch['progressive'] && timer_read('batch_processing') > 1000) {
break;
}
}
if ($batch['progressive']) {
// Gather progress information.
// Reporting 100% progress will cause the whole batch to be considered
// processed. If processing was paused right after moving to a new set,
// we have to use the info from the new one.
if ($set_changed && isset($current_set['operations'])) {
// Processing will continue with a fresh batch set.
$remaining = count($current_set['operations']);
$total = $current_set['total'];
$progress_message = $current_set['init_message'];
$task_message = '';
}
else {
$remaining = count($old_set['operations']);
$total = $old_set['total'];
$progress_message = $old_set['progress_message'];
}
$current = $total - $remaining + $finished;
$percentage = $total ? floor($current / $total * 100) : 100;
$values = array(
@ -258,7 +279,9 @@ function _batch_finished() {
}
// Cleanup the batch table and unset the global $batch variable.
if ($batch['progressive']) {
db_query("DELETE FROM {batch} WHERE bid = %d", $batch['id']);
}
$_batch = $batch;
$batch = NULL;

View File

@ -1398,6 +1398,8 @@ function expand_date($element) {
$options = drupal_map_assoc(range(1900, 2050));
break;
}
$parents = $element['#parents'];
$parents[] = $type;
$element[$type] = array(
'#type' => 'select',
'#value' => $element['#value'][$type],
@ -2027,7 +2029,7 @@ function batch_set($batch_definition) {
* isses a drupal_goto and thus ends page execution.
*
* This function is not needed in form submit handlers; Form API takes care
* of batches issued during form submission.
* of batches that were set during form submission.
*
* @param $redirect
* (optional) Path to redirect to when the batch has finished processing.
@ -2040,7 +2042,6 @@ function batch_process($redirect = NULL, $url = NULL) {
if (isset($batch)) {
// Add process information
$t = get_t();
$url = isset($url) ? $url : 'batch';
$process_info = array(
'current_set' => 0,
@ -2048,13 +2049,13 @@ function batch_process($redirect = NULL, $url = NULL) {
'url' => isset($url) ? $url : 'batch',
'source_page' => $_GET['q'],
'redirect' => $redirect,
'error_message' => $t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => url($url, array('query' => array('id' => $batch['id'], 'op' => 'error'))))),
);
$batch += $process_info;
if ($batch['progressive']) {
// Save and unset the destination if any. drupal_goto looks for redirection
// in $_REQUEST['destination'] and $_REQUEST['edit']['destination'].
// Clear the way for the drupal_goto redirection to the batch processing
// page, by saving and unsetting the 'destination' if any, on both places
// drupal_goto looks for it.
if (isset($_REQUEST['destination'])) {
$batch['destination'] = $_REQUEST['destination'];
unset($_REQUEST['destination']);
@ -2063,9 +2064,20 @@ function batch_process($redirect = NULL, $url = NULL) {
$batch['destination'] = $_REQUEST['edit']['destination'];
unset($_REQUEST['edit']['destination']);
}
db_query('INSERT INTO {batch} (timestamp) VALUES (%d)', time());
// Initiate db storage in order to get a batch id. We have to provide
// at least an empty string for the (not null) 'token' column.
db_query("INSERT INTO {batch} (token, timestamp) VALUES ('', %d)", time());
$batch['id'] = db_last_insert_id('batch', 'bid');
// Now that we have a batch id, we can generate the redirection link in
// the generic error message.
$t = get_t();
$batch['error_message'] = $t('Please continue to <a href="@error_url">the error page</a>', array('@error_url' => url($url, array('query' => array('id' => $batch['id'], 'op' => 'finished')))));
// Actually store the batch data and the token generated form the batch id.
db_query("UPDATE {batch} SET token = '%s', batch = '%s' WHERE bid = %d", drupal_get_token($batch['id']), serialize($batch), $batch['id']);
drupal_goto($batch['url'], 'op=start&id='. $batch['id']);
}
else {

View File

@ -2808,7 +2808,7 @@ function system_batch_page() {
if ($output === FALSE) {
drupal_access_denied();
}
else {
elseif (isset($output)) {
// Force a page without blocks or messages to
// display a list of collected messages later.
print theme('page', $output, FALSE, FALSE);