summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2007-07-20 05:44:13 +0000
committerDries Buytaert <dries@buytaert.net>2007-07-20 05:44:13 +0000
commiteb65040c5e66dd50c0a5d496b686ae72e77143c6 (patch)
tree10760a4f85d2f688b4d9a4e8d4ed9e88804cca16 /includes
parenta47643cb091a363514f8589f548338ec40eadbc4 (diff)
downloadbrdo-eb65040c5e66dd50c0a5d496b686ae72e77143c6.tar.gz
brdo-eb65040c5e66dd50c0a5d496b686ae72e77143c6.tar.bz2
- Patch #149593 by yched: batch API fixes.
Diffstat (limited to 'includes')
-rw-r--r--includes/batch.inc59
-rw-r--r--includes/form.inc24
2 files changed, 59 insertions, 24 deletions
diff --git a/includes/batch.inc b/includes/batch.inc
index 16a5326ca..3f93bcbbc 100644
--- a/includes/batch.inc
+++ b/includes/batch.inc
@@ -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.
- db_query("DELETE FROM {batch} WHERE bid = %d", $batch['id']);
+ if ($batch['progressive']) {
+ db_query("DELETE FROM {batch} WHERE bid = %d", $batch['id']);
+ }
$_batch = $batch;
$batch = NULL;
diff --git a/includes/form.inc b/includes/form.inc
index 92d4fe401..865c1fecd 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -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 {