Импорт контента в Drupal через batch

В Drupal есть хорошая штука - batch, позволяет обрабатывать большие массивы данных не особо беспокоясь о превышение лимита выполнения скрипта или памяти. Часто это нужно при импорте контента.

Назовем модуль "import_products". Импортируется csv файл.

function import_products_import_form_submit($form, &$form_state)
{
//путь, где мы запускаем batch
$redirect_path = 'admin/content/import_products';

$csv_file_path = file_directory_path() . '/importfile.csv';
$csv_file = file($csv_file_path);

//определяем batch           
$batch = array(
  'title' => 'Импортирование продукции',
  'operations' => array()
);

//В batch может быть несколько функций - обработчиков. Запускаются они последовательно.
//определили функцию, которая будет выполняться в начале.
$batch['operations'][] = array('import_products_function1', array($val));

//определили функцию, которая будет выполняться после.
$batch['operations'][] = array('import_products_function2',array($csv_file));

//определили функцию, которая выполняется после того, как batch выполнит работу.
$batch['finished'] = 'import_products_report';
               
//устанавливаем batch
batch_set($batch);

//запускаем batch
batch_process($redirect_path);
}

Собственно обработчики:

//в $context хранится состояние выполнения batch
function import_products_function2($csv_file, &$context){
$batch_limit = 150; //лимит количества итераций, обрабатываемых за одно выполнение batch.

//настройки batch
if (!isset($context['sandbox']['progress'])) {
 $context['sandbox']['progress'] = 0;
 //устанавливаем максимальное количество итераций.
 $context['sandbox']['max'] = count($csv_file);
}

if(!isset($context['sandbox']['items'])) {
 //сохраняем наш массив со строками.
 $context['sandbox']['items'] = $csv_file;
}

//удаляем обработанные строки из массива
if ($context['sandbox']['progress'] != 0){
   array_splice($context['sandbox']['items'], 0, $batch_limit);
}      
$counter = 0;

foreach ($context['sandbox']['items'] as $line) {
 if ($counter != $batch_limit){
  $counter++;
  //обрабатываем $line;
  //если  line обработали успешно сохраняем статистику успешных обработок
  //$context['results'][0]++;

  //если  line обработали неуспешно сохраняем статистику неуспешных  обработок
  //$context['results'][1]++;
  $context['sandbox']['progress']++;
 }else {
   break;
 }                     
}
//Выводим сообщение о работе batch
$context['message'] = 'Обработано '.$context['sandbox']['progress'].' строк из '.$context['sandbox']['max'];

//batch будет выполняться до тех пор пока $context['finished'] не станет 1
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
  $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}      

}

Функция вызывается после работы batch - выводим результаты работы.

function import_products_report($success, $results, $operations){
$output = '<div>Импортировано строк - '.$results[0].'</div>';
$output .= '<div>Cтрок с ошибками - '.$results[1];
drupal_set_message($output);
}

В качестве примера можете посмотреть модуль импорта данных в Drupal из csv файла.

Комментарии

Шикарно)
Exactly what I need!))
Спасибо большое!
Замечательный у вас блог, добавил в rss

Оставить сообщение

Картинка