In the web development process the use of batch operations enables forms processing to be performed in the course of several requests. This prevents interrupts in form processing that might occur due to PHP time-out. The user, also, keeps being informed about the current operations running. The batch is considered to have been initially developed to secure harmonic integration with Forms API, it has often been used, though, in writing ordinary scripts like update.php.
Say, we need to process big data. First, we will create a page in hook_menu.
/** * 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; }
Our form displays a button that launches batch operations. For the purpose of usability we can have submits for all applied processes been displayed there in the form. Once the form has been submitted, module_batch_submit() function starts.
/** * batch submit function */ function module_batch_submit($form, &$form_state) { $batch = array( 'title' => t('Process'), 'init_message' => t('Process'), //В следующем парметре возможно использования таких placeholders: @current, @remaining, @total, @percentage, @estimate and @elapsed. По умолчанию - t('Completed @current of @total.') 'progress_message' => t('In progress @current'), //По умолчанию значение - t('An error has occurred.') 'error_message' => t('Warning! Error!'), 'operations' => array( array('operations_function', array()), ), 'finished' => 'module_finished_callback', //Путь к файлу где находится функция указанная в 'operations' и 'finished' 'file' => 'module.inc', ); batch_set($batch); batch_process(); }
Such entry will prompt launching of the processing. We form $batch array, wherein the name, the processing function and the function of operation results are indicated. While batch_set() gets a new process initiated, batch_process() has the operation completed.
/** * batch */ function operations_function(&$context) { if (empty($context['sandbox'])) { //задаем стартовые переменные, в переменной $context['sandbox']['max'] указываем //количество элементов $context['sandbox']['progress'] = 0; $context['sandbox']['current_node'] = 0; $context['sandbox']['max'] = db_result(db_query("SELECT COUNT(`nid`) FROM {node}")); } $limit = 10; // указываем количество обратавыемых элементов за шаг. Чем меньше тем медленее но //надежнее $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']; } }
At this point, we will describe the function for finalizing the operation.
/** * 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); }
The finishing function checks if processing operations have been successfully completed and gets the relevant message displayed.