- 7 includes/form.inc batch
- 6 includes/form.inc batch
- 8 core/includes/form.inc batch
Creates and processes batch operations.
Functions allowing forms processing to be spread out over several page requests, thus ensuring that the processing does not get interrupted because of a PHP timeout, while allowing the user to receive feedback on the progress of the ongoing operations.
The API is primarily designed to integrate nicely with the Form API workflow, but can also be used by non-Form API scripts (like update.php) or even simple page callbacks (which should probably be used sparingly).
Example:
$batch = array(
'title' => t('Exporting'),
'operations' => array(
array('my_function_1', array($account->uid, 'story')),
array('my_function_2', array()),
),
'finished' => 'my_finished_callback',
'file' => 'path_to_file_containing_myfunctions',
);
batch_set($batch);
// Only needed if not inside a form _submit handler.
// Setting redirect in batch_process.
batch_process('node/1');
Note: if the batch 'title', 'init_message', 'progress_message', or 'error_message' could contain any user input, it is the responsibility of the code calling batch_set() to sanitize them first with a function like check_plain() or filter_xss(). Furthermore, if the batch operation returns any user input in the 'results' or 'message' keys of $context, it must also sanitize them first.
Sample batch operations:
// Simple and artificial: load a node of a given type for a given user
function my_function_1($uid, $type, &$context) {
// The $context array gathers batch context information about the execution (read),
// as well as 'return values' for the current operation (write)
// The following keys are provided :
// 'results' (read / write): The array of results gathered so far by
// the batch processing, for the current operation to append its own.
// 'message' (write): A text message displayed in the progress page.
// The following keys allow for multi-step operations :
// 'sandbox' (read / write): An array that can be freely used to
// store persistent data between iterations. It is recommended to
// use this instead of $_SESSION, which is unsafe if the user
// continues browsing in a separate window while the batch is processing.
// 'finished' (write): A float number between 0 and 1 informing
// the processing engine of the completion level for the operation.
// 1 (or no value explicitly set) means the operation is finished
// and the batch processing can continue to the next operation.
$node = node_load(array('uid' => $uid, 'type' => $type));
$context['results'][] = $node->nid . ' : ' . check_plain($node->title);
$context['message'] = check_plain($node->title);
}
// More advanced example: multi-step operation - load all nodes, five by five
function my_function_2(&$context) {
if (empty($context['sandbox'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField();
}
$limit = 5;
$result = db_select('node')
->fields('node', array('nid'))
->condition('nid', $context['sandbox']['current_node'], '>')
->orderBy('nid')
->range(0, $limit)
->execute();
foreach ($result as $row) {
$node = node_load($row->nid, NULL, TRUE);
$context['results'][] = $node->nid . ' : ' . check_plain($node->title);
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $node->nid;
$context['message'] = check_plain($node->title);
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
Sample 'finished' callback:
function batch_test_finished($success, $results, $operations) {
// The 'success' parameter means no fatal PHP errors were detected. All
// other error management should be handled using 'results'.
if ($success) {
$message = format_plural(count($results), 'One post processed.', '@count posts processed.');
}
else {
$message = t('Finished with an error.');
}
drupal_set_message($message);
// Providing data for the redirected page is done through $_SESSION.
foreach ($results as $result) {
$items[] = t('Loaded node %title.', array('%title' => $result));
}
$_SESSION['my_batch_results'] = $items;
}
Functions
|
Name |
Location | Description |
|---|---|---|
| batch_get |
includes/ |
Retrieves the current batch. |
| batch_process |
includes/ |
Processes the batch. |
| batch_set |
includes/ |
Adds a new batch. |
| hook_batch_alter |
modules/ |
Alter batch information before a batch is processed. |
| _batch_populate_queue |
includes/ |
Populates a job queue with the operations of a batch set. |
| _batch_queue |
includes/ |
Returns a queue object for a batch set. |
File
- includes/
form.inc, line 4210 - Functions for form and batch generation and processing.
Comments
Batch without form submit
PermalinkIf you are running your batch process without using FAPI submit form, you have to use drupal_goto('path') in your batch_test_finished() function, otherwise your batch will loop endlessly.
drupal_mail in batching
Permalinkmy version is 7.2 and I try to run drupal_mail() in the operation, it run though the query and I receive the mail, but no any title and body somehow, the changes that I made in hook_mail seems doesn't affect the output, could anyone please tell me about this problem? thanks!
throw an error?
PermalinkHow do you throw an error? Bonus points if you can tell me how to halt future pending batch jobs as well.
throw new Exception;
PermalinkWell this
<?phpthrow new Exception(t('My error message.'));
?>
technically works. But it doesn't show pretty output. Ideally there would be a method that has nicer display.
throw an error
PermalinkI was wanting to do something similar, not sure if it's the best method, but after looking at batch.js and progress.js and trial and error, I figured out that you can do something like this (at least in D7)
<?phpfunction some_batch_operation(&$context) {
// do stuff
// if something goes wrong
$result = array('status' => FALSE, 'data' => $message);
die(json_encode($result));
}
?>
What you set as your batch 'error_message' will be displayed first in a p tag with class="error" (see batch.js errorCallback), and whatever you put in $message will be wrapped in a div tag with class="messages error" (see progress.js displayError).
Is function function
PermalinkIs
function batch_test_finished()supposed to befunction my_finished_callback()in the example code? Seems like 'my_finished_callback' is not defined anywhere and 'batch_test_finished' is not referenced anywhere else in the code.You are correct
Permalink$batch['finished'] = 'my_finished_callback'
It looks like this was probably originally copy / pasted from http://drupal.org/node/180528 and then modified.
Example
PermalinkHere's a simple example of passing array values between operations:
http://drupal.org/node/1829700
Hello every one
PermalinkHello every one
Is it possible to pass a parameter to my finished function like operations like this
<?php$batch = array(
'title' => t('Exporting'),
'operations' => array(
array('my_function_1', array($account->uid, 'story')),
array('my_function_2', array()),
),
'finished' => array(
array('my_finished_callback', array($data))),
'file' => 'path_to_file_containing_myfunctions',
);
?>
Thanks in advance