Briefly about Batch API
Batch operations make it possible to process forms during several requests. This prevents from break in processing caused by PHP time-out. The user is also given the information about the course of current operations.
It is affirmed that batch was initially developed for harmonic integration with Forms API, though it is often used in ordinary scripts like update.php.
Let's imagine that we need to process big amount of data. First of all, we'll create a page in hook_menu.
<?php
/**
* Batch form
*/
function module_brand_batch(&$form_state) {
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Start batch'),
'#description' => t("Make some operations"),
'#submit' => array('module_batch_submit'),
);
return $form;
}
?>We've displayed a button to launch batch operations. For usability purpose it's possible to place submits on the form for all applied processes. After the form is submitted module_batch_submit() function is performed.
<?php
/**
* batch submit function
*/
function module_batch_submit($form, &$form_state) {
$batch = array(
'title' => t('Process'),
'init_message' => t('Process'),
//In next parameter it's possible to use such placeholders: @current, @remaining, @total, @percentage, @estimate and @elapsed. По умолчанию - t('Completed @current of @total.')
'progress_message' => t('In progress @current'),
//by default the value is - t('An error has occurred.')
'error_message' => t('Warning! Error!'),
'operations' => array(
array('operations_function', array()),
),
'finished' => 'module_finished_callback',
//path to file where function is situated indicated in 'operations' and 'finished'
'file' => 'module.inc',
);
batch_set($batch);
batch_process();
}
?>Such entry will provide launch of process. We form $batch array, in which we indicate name, function of operation progress and function of operation results. batch_set() - starts a new process. batch_process() - executes the operation.
<?php
/**
* batch
*/
function operations_function(&$context) {
if (empty($context['sandbox'])) {
//we define variables, in variable $context['sandbox']['max'] we indicate number of elements
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_node'] = 0;
$context['sandbox']['max'] = db_result(db_query("SELECT COUNT(`nid`) FROM {node}"));
}
$limit = 10;
// we indicate number of processed elements per step. The less, the slower but more surely
$result = db_query_range("SELECT `nid` FROM {node} WHERE `nid` > %d", $context['sandbox']['current_node'], 0, $limit);
while ($row = db_fetch_object($result)) {
$node = node_load($row->nid, NULL, TRUE);
$context['results'][] = $title . '-' . $nid;
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $nid;
$context['message'] = $node->title
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}
?>Let's describe the function of fining of operation.
<?php
/**
* finishig of batch
*/
function module_finished_callback($success, $results, $operations) {
if ($success) {
$message = 'Process finished success';
}
else {
$error_operation = reset($operations);
$message = t('An error occurred while processing %error_operation with arguments: @arguments', array('%error_operation' => $error_operation[0], '@arguments' => print_r($error_operation[1], TRUE)));
}
drupal_set_message($message);
}
?>Function of finishing checks if processing operations were successfully completed and displays a message.


