Использование Batch процессов в hook_update_N

Иногда в hook_pdate_N() требуется запустить batch процесс для обработки большого объема данных, но процесс обновления и так уже является batch процессом. Для решения этой проблемы можно использовать переменную $sandbox которая передается по ссылке и позволяет выполнить одну функцию обновления несколько раз.

Рассмотрим пример обработки всех нод за несколько проходов, в одном проходе обрабатывается по 10 нод.

/**
 * Update all node titles.
 */
function MODULENAME_update_7001(&$sandbox) {
  // Это будет выполнено во время первого прохода
  if (!isset($sandbox['total'])) {
    $result = db_select('node', 'n')
      ->fields('n', array('nid'))
      ->execute();
    $sandbox['total'] = $result->rowCount();
    $sandbox['current'] = 0;
  }
 
  // Колличество обрабатываемых нодов за один проход
  $nodes_per_pass = 10;
 
  // Получение идентификаторов нодов обрабатываемых в текущем проходе
  $result = db_select('node', 'n')
      ->fields('n', array('nid'))
      ->orderBy('n.nid')
      ->range($sandbox['current'], $nodes_per_pass)
      ->execute();
  foreach ($result as $row){
    // Загружаем нод
    $node = node_load($row->nid);
    // Проводим манипуляции
    $node->title = $node->title . '(processed)';
    // Сохраняем нод
    node_save($node);
 
    // Увеличиваем current на 1.
    $sandbox['current']++;
  }
 
  // Устанавливаем ключ #finished (если ключ #finished будет равен 1 процесс завершится)
  $sandbox['#finished'] = ($sandbox['current'] / $sandbox['total']);
 
  if ($sandbox['#finished'] === 1) {
    drupal_set_message(t('We processed @nodes nodes. DONE!!!', array('@nodes' => $sandbox['total'])));
  }
}

Оригинальная статья: http://bleen.net/blog/running-batch-processes-update-hook-bed

Автор адаптации: Денис Захаров.

Поделись с друзьями:

Комментарии

Спасибо, за классную статью, но тут есть маленькая ошибка $sandbox['#finished'] должно быть $sandbox['finished'] без решетки, про это написано в оригинальной статье в комментах. Спасибо.

Там они своими комментариями автора запутали )) Я написал сразу по правильному.

Хотя нет все правильно, сорри. Просто у меня апдейт зацикливается на половине, причину понять не могу.