Drupal 7 Batch Process Example

Drupal 7 Batch Process Example that utilizes the Batch API

In this example we write users data on CSV file with batch process and download it.

/**
 * Implements hook_menu().
 */
function module_name_menu() {
  $items = array();
  $items['batch-process-user-report'] = array(
    'title' => 'Batch process user report example',
    'page callback' => 'batch_process_user_report',
    'access arguments' => array('access content'),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * batch-process-user-report callback.
 */
function batch_process_user_report() {
  // Code for CSV file download starts
  if (isset($_SESSION['user_report_data_csv_file'])) {
    // Add HTTP headers for CSV file download.
    drupal_add_http_header('Content-Type', 'text/csv; utf-8');
    drupal_add_http_header('Content-Disposition', 'attachment; filename=' . $_SESSION['user_report_data_csv_file'], TRUE);
    // Allow caching, otherwise IE users can't dl over SSL (see issue #294).
    drupal_add_http_header('Cache-Control', 'max-age=300; must-revalidate');

    // Read the file to the output buffer and exit.
    readfile($_SESSION['user_report_data_csv_file']);
    unlink($_SESSION['user_report_data_csv_file']);
    unset($_SESSION['user_report_data_csv_file']);
    exit;
  }
  // Code for CSV file download ends
  if (!isset($_SESSION['user_report_data_csv_file'])) {
    $destination = url('user');
    $batch = array(
      'operations' => array(
        array('_write_data_on_csv_and_download_user_report', array()),
      ),
      'finished' => 'user_report_download_finished',
      'title' => t('User Data Download') . " <div id='back-to-report'&gt<a href='" . $destination . "'&gtBack to report</a&gt</div&gt",
      'init_message' => t('User Data Download is starting.'),
      'progress_message' => t('Processed @current out of @total.'),
      'error_message' => t('User Data Download Batch has encountered an error.'),
    );
    // Adds a new batch.
    batch_set($batch);
    // The path to redirect to when done.
    batch_process('batch-process-user-report');
  }
}

/**
 * Batch process code
 */
function _write_data_on_csv_and_download_user_report() {
  $limit = 100;
  $context['finished'] = 0;
  if (!isset($context['sandbox']['file'])) {
    $field_labels = array(
      'USER NAME',
      'USER EMAIL',
      'Last Login',
      'STATUS',
    );
    $filename = "user_report_backend_data" . time() . ".csv";
    $fp = fopen("sites/default/files/" . $filename, 'w');
    fputcsv($fp, $field_labels, ",");
    fclose($fp);
    $total_users_count = db_query("SELECT COUNT(uid) FROM {users}")->fetchField();
    $context['sandbox']['file'] = "sites/default/files/" . $filename;
    $context['sandbox']['total_users_count'] = $total_users_count;
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['from_limit'] = 0;
    $_SESSION['user_report_data_csv_file'] = $context['results']['file'] = $context['sandbox']['file']; //For download function
  }
  $fp = fopen($context['sandbox']['file'], 'a');
  $query = db_select('users', 'u')
      ->fields('u', array('uid'));
  // Excluse anonymous user
  $query->condition('u.uid', 0, '<>');
  $query->range($context['sandbox']['from_limit'], $limit);
  $results = $query->execute();
  $coll_array = array();
  while ($data = $results->fetchObject()) {
    $user_obj = user_load($data->uid);
    $coll_array['u_name'] = $user_obj->name;
    $coll_array['u_mail'] = $user_obj->mail;
    $coll_array['u_login'] = ($user_obj->login != 0) ? format_date($user_obj->login, 'custom', 'd-M-Y', 'Asia/Kolkata') : "Not Logged in Yet";
    $coll_array['u_status'] = $user_obj->status;
    fputcsv($fp, $coll_array, ",");

    $context['results'][] = $user_obj->name . " Write on CSV.";
    $context['sandbox']['progress'] ++;
    $context['sandbox']['from_limit'] ++;
    $context['message'] = t('Now Writing %name ON CSV', array('%name' => $user_obj->name));
  }
  // Close the file.
  fclose($fp);
  if ($context['sandbox']['progress'] == $context['sandbox']['total_users_count']) {
    // Sotp the batch process
    $context['finished'] = 1;
  }
}

/**
 * Batch Process download finish
 */
function user_report_download_finished($success, $results, $operations) {
  if ($success) {
    // Here we do something meaningful with the results.
    $message = 'Total ' . (count($results) - 1) . ' Records write on xls.';
    $message .= theme('item_list', $results); // D6 syntax
    drupal_set_message($message);
  }
  else {
    // An error occurred.
    // $operations contains the operations that remained unprocessed.
    $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, 'error');
  }
}