Блог

Пакетные операции дают возможность обрабатывать формы в ходе нескольких запросов. Таким образом предупреждается обрыв обработки из-за тайм-аута РНР. Кроме этого, пользователю предоставляется информация о ходе осуществления текущих операций.

Считается также, что batch, в первую очередь, был разработан для гармоничной интеграции с Forms API, хотя часто его используют и в обычных скриптах - таких как update.php.

Представим, что нам необходимо осуществить обработку большого количества данных. Для начала веб разработчику нужно создать страницу в 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;
}

На форме мы  отобразили кнопку для запуска пакетных операций. Для удобства на форме можно размещать submit'ы для всех применяемых обработок. После submit'а формы исполняется функция module_batch_submit().

/**
* 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();
}

Такая запись обеспечит вызов обработки. Формируем массив $batch, в котором указываем название, функцию выполняющую обработку и функцию завершения обработки. batch_set() — открывает новую обработку. batch_process() — совершает обработку.

/**
* 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'];
  }
}

Также, описываем функцию завершения операций.

/**
* 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);
}

Функция завершения проверяет, успешно ли прошли операции обработки и выдает соответствующее сообщение.

Join the conversation
0 Comments