Импорт контента в 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);
}
{
//путь, где мы запускаем 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'];
}
}
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);
}
$output = '<div>Импортировано строк - '.$results[0].'</div>';
$output .= '<div>Cтрок с ошибками - '.$results[1];
drupal_set_message($output);
}
В качестве примера можете посмотреть модуль импорта данных в Drupal из csv файла.

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