Пример создания batch операции на Drupal

Для того чтобы какую-то большую операцию выполнить в несколько приёмов, нужно использовать специальное Batch API Друпала. Хорошая статья по его использованию есть здесь:
http://drupalace.ru/lesson/obrabotka-bolshogo-kolichestva-dannyh-s-pomos...

Но там есть пара нюансов, которые я хотел бы прояснить:
$context['finished'] надо заполнять при каждом шаге, это значение от 0 до 1, как раз его значение будет отображаться в прогрессбаре. В примере в той статье этого нет, хотя текстом написано. Здесь у себя я просто оставлю свою заготовку для использования batch api, в следующий раз если надо будет обработать одномерный массив с какими-то данными буду пользоваться ею:

function mymodule_bulk_update_for_loi_records_form() {
  $form = array();
 
  $form['description'] = array(
    '#type' => 'markup',
    '#markup' => t('This form allows you ......<br/><br/>'),
  );
 
  $form['step_limit'] = array(
    '#type' => 'textfield',
    '#title' => t('How much lois you want to process per each step?'),
    '#default_value' => 10,
    '#size' => 3,
  );
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );
 
  return $form;
}
 
function mymodule_bulk_update_for_loi_records_form_submit($form, $form_state) {
  // Get all lois where is no 'ltc' variable (or any other of the added 14 variables by our script)
  $lois = db_query("SELECT...'")->fetchCol();
 
  $batch = array(
    'title' => t('Updating lois...'),
    'operations' => array(
      array('mymodule_bulk_update_step', array($lois, $form_state['values']['step_limit']))
    ),
    'finished' => 'mymodule_bulk_update_finished',
  );
  batch_set($batch);
}
 
function mymodule_bulk_update_step($lois, $step_limit, &$context) {
 
  if (empty($context['sandbox']['progress'])) {
    $context['sandbox']['progress'] = 0;
    $context['sandbox']['max'] = count($lois);
    $context['sandbox']['items'] = $lois;
  }
 
  $counter = 0;
  if(!empty($context['sandbox']['items'])) {
 
    // Get rid of the processed lois
    if ($context['sandbox']['progress'] != 0) {
      array_splice($context['sandbox']['items'], 0, $step_limit);
    }
 
    foreach ($context['sandbox']['items'] as $item) {
      if ($counter != $step_limit) {
 
        //Что-то делаем с lois
        sleep(1);
 
        // Увеличиваем счётчики
        $counter++;
        $context['sandbox']['progress']++;
 
        $context['message'] = t('Processed %progress LOIs of %count', array('%progress' => $context['sandbox']['progress'], '%count' => $context['sandbox']['max']));
        if ($context['sandbox']['progress'] < $context['sandbox']['max']) {
          $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
        }
      }
      else break;
    }
  }
  else {
    $context['finished'] = 1;
  }
}
 
function mymodule_bulk_update_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 item processed.', '@count items processed.');
  }
  else {
    $message = t('Finished with an error.');
  }
  drupal_set_message($message);
}
Drupal 7

Комментарии

Добавить комментарий