Для того чтобы начать пакетную обработку данных, её необходимо сначала подготовить, а затем запустить должным образом.
¶Подготовка при помощи BatchBuilder
\Drupal\Core\Batch\BatchBuilder
— объект, позволяющий строить очередь для последующего запуска.
Пример:
$data_to_process = [
['foo', 'bar'],
['baz'],
];
$batch = new BatchBuilder();
$batch
->setTitle(new TranslatableMarkup('My batch'))
->setInitMessage(new TranslatableMarkup('Prepare operations for processing.'));
foreach ($data_to_process as $data) {
$batch->addOperation([$this, 'processData'], $data);
}
¶setTitle()
Метод setTitle()
позволяет указать заголовок операции.
Пример:
$batch->setTitle(new TranslatableMarkup('My batch'));
¶setInitMessage()
Метод setInitMessage()
позволяет задать сообщение показываемое при инициализации батча. По умолчанию "Initialazing.".
$batch->setInitMessage(new TranslatableMarkup('Prepare operations for processing.'));
¶setProgressMessage()
Метод setProgressMessage()
позволяет задать сообщение о текущем состоянии выполнения операций.
Вы можете использовать в сообщении следующие подстановки:
-
@current
: Текущая операция находящаяся в обработке. -
@remaining
: Количество операций оставшихся для обработки. -
@total
: Общее количество операций в текущей пакетной обработке. -
@percentage
: Процентное отображение выполнения операций. -
@estimate
: Приблизительное время до завершения выполнения всех операций. -
@elapsed
: Время, затраченное на выполнение операций к текущему моменту.
Сообщение прогресса обновляться в конце каждого вызова обработки операции, будь он в одной операции разделенный на несколько вызовов, или несколько различных операций. Это значит, что сообщение показывается после выполнения, а не в процессе. Например, если операций 10, сейчас выполняется 3-ая по списку, а сообщение имеет вид @current of @total
, то пользователю будет показано 2 of 10
, и только после завершения 3 операции, или её первой итерации, оно заменится на 3 of 10
.
Пример:
$batch->setProgressMessage(new Translatablemarkup('Processing @current of @total. Estimated time to finish is @estimate.'))
¶setErrorMessage()
Метод setErrorMessage()
позволяет задать сообщение, которое будет показана в случае возникновении ошибки. По умолчанию "An error has occurred.".
Пример:
$batch->setErrorMessage(new TranslatableMarkup('Contact site administrator.'));
¶setFile()
Метод setFile()
позволяет указать файл, который необходимо подгрузить в процессе обработки операций. По умолчанию, подгружается файл {module_name}.module
.
Путь должен быть указан относительно корня ядра.
Пример:
$path_to_file = drupal_get_path('module', 'my_module') . '/my_module.batch.inc';
$batch->setFile($path_to_file);
¶setLibraries()
Метод setLibraries()
позволяет задать список библиотек, которые будут загружены на странице обработки.
Данный метод заменяет ранее указанные для подключения библиотеки, но не трогает подключаемые по умолчанию библиотеки. Данный метод предназначен только для подключения собственных библиотек и по умолчанию пустой.
Пример:
$libraries = [
'my_module/library_name',
'my_theme/library_name',
];
$batch->setLibraries($libraries);
¶setUrlOptions()
Метод setUrlOptions()
позволяет задать опции для Url, на который будет переадресован пользователь для выполнения операций.
Путь для всех операций всегда один, но вы можете влиять на передаваемые опции в соответствии с Drupal\Core\Url
. Для более детальной информации, какие опции могут быть переданы, обратитесь к документации Url::fromUri()
.
Пример:
$url_options = [
'query' => [
'key' => 'value',
],
];
$batch->seetUrlOptions($url_options);
¶setProgressive()
Метод setProgressive()
позволяет включать или отключать прогрессивный режим обработки. По умолчанию данный режим включен.
Прогрессивный режим обработки означает, что операции будут выполняться при помощи вызова множества новых запросов. Отключение прогрессивного режима означает, что будет предпринята попытка выполнить все операции в пределах одного HTTP-запроса. Если по каким-то причинам, обработка операций не успеет завершиться, например, из-за тайм-аута, то вся обработки закончится с ошибкой. Поэтому, отключать прогрессивный режим не рекомендуется без острой необходимости. Это один из плюсов использования пакетной обработки.
Пример:
// Disable progressive mode.
$batch->setProgressive(FALSE);
¶setQueue()
Метод setQueue()
позволяет задать свой собственный идентификатор очереди и класс обработчик.
Принимает два аргумента:
-
$name
: Собственное название очереди, которое будет использовано для операций заданных в текущей пакетной обработке. -
$class
: Полное имя класса, ответственного за работу с очередью. Класс должен реализовыватьDrupal\Core\Queue\QueueInterface
. По умолчанию используется\Drupal\Core\Queue\Batch
для прогрессивных обработок и\Drupal\Core\Queue\BatchMemory
для операций за один запрос.
Может пригодиться в каких-то специфичных кейсах, когда, например, данные на обработку нужно вынести за пределы БД (memcache, redis или вовсе на иной сервер). Для более подробной информации, рекомендуется изучить материал очередей.
¶addOperation()
Метод addOperation()
позволяет добавлять операции для пакетной обработки.
Метод принимает два аргумента:
-
$callback
: Элемент типаcallable
— обработчик что будет вызван для обработки данной операции. Например:-
['\Drupal\MyModule\Batch', 'methodName']
-
[$this, 'methodName']
или[get_class($this), 'methodName']
или[self::class, 'methodName']
-
['function_name']
-
-
$arguments
: Массив данных, который будет передан обработчику.
На каждую операцию нужно делать собственный вызов. Операций может быть сколько угодно, а также, каждая операция может иметь свой собственный обработчик.
Пример:
$data_to_process = [
['foo', 'bar'],
['baz'],
];
foreach ($data_to_process as $data) {
$batch->addOperation([$this, 'processData'], $data);
}
¶setFinishCallback()
Метод setFinishCallback()
позволяет указать функцию обратного вызова, которая будет вызвана после успешного завершения всех операций.
Пример:
$batch->setFinishCallback([$this, 'finished']);
¶toArray()
Метод toArray()
преобразовывает все настройки, заданные при помощи методов BatchBuilder
в массив.
Пример:
batch_set($batch->toArray());
¶Запуск пакетной обработки
После того как сформированы данные и настройки для пакетной обработки, её необходимо запустить.
Запуск производится при помощи двух функций:
-
batch_set()
: Принимает структурированный массив пакетной обработки созданный при помощиBatchBuilder
или руками, и сохраняет его до запуска. -
batch_process()
: Перенаправляет пользователя на страницу пакетной обработки и запускает её.
В общем случае выглядит это следующим образом:
$data_to_process = [
['foo', 'bar'],
['baz'],
];
$batch = new BatchBuilder();
$batch
->setTitle(new TranslatableMarkup('My batch'))
->setInitMessage(new TranslatableMarkup('Prepare operations for processing.'));
foreach ($data_to_process as $data) {
$batch->addOperation([$this, 'processData'], $data);
}
batch_set($batch->toArray());
batch_process();
В ситуации, когда вы хотите запустить пакетную обработки из формы, вам не нужно вызывать batch_process()
, так как это сделает сам Form API, после того как обработка формы корректно завершится.
¶Ссылки
- Drupal 8: Batch API, Niklan, 2018