Jul 02, 2019 in Drupal 8, Snippets

Batch processes give you a hard time when using them for the first time. This module example will handle every aspect of it!

What we're building

This module will import 3 dogs from a json file as nodes. A batch process has some advantages:

  • Provide interaction about which part is being imported
  • The script cannot timeout and it is recommended to use batch operations when doing large amounts of data

The code

Download the code from my GitHub page. 

  • 1. Enable the module
  • 2. Clear caches
  • 3. Go to admin/batch-import-example and submit the form
  • 4. A batch process will start and give interaction about which dog he is importing.
<?php

namespace Drupal\batch_import_example\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Serialization\Json;
use Drupal\node\Entity\Node;

/**
 * Provides a form for deleting a batch_import_example entity.
 *
 * @ingroup batch_import_example
 */
class ImportForm extends FormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormId() : string {
    return 'batch_import_example_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {

    $form['#prefix'] = '<p>This example form will import 3 pages from the docs/animals.json example</p>';

    $form['actions'] = array(
      '#type' => 'actions',
      'submit' => array(
        '#type' => 'submit',
        '#value' => 'Proceed',
      ),
    );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {

    $host = \Drupal::request()->getHost();
    $url = $host . '/' . drupal_get_path('module', 'batch_import_example') . '/docs/animals.json';
    $request = \Drupal::httpClient()->get($url);
    $body = $request->getBody();
    $data = Json::decode($body);
    $total = count($data);

    $batch = [
    'title' => t('Importing animals'),
    'operations' => [],
    'init_message' => t('Import process is starting.'),
    'progress_message' => t('Processed @current out of @total. Estimated time: @estimate.'),
    'error_message' => t('The process has encountered an error.'),
    ];

    foreach($data as $item) {
      $batch['operations'][] = [['\Drupal\batch_import_example\Form\ImportForm', 'importAnimal'], [$item]];
    }

    batch_set($batch);
    \Drupal::messenger()->addMessage('Imported ' . $total . ' animals!');

    $form_state->setRebuild(TRUE);
  }

  /**
   * @param $entity
   * Deletes an entity
   */
  public function importAnimal($item, &$context) {
    $entity = Node::create([
        'type' => 'page',
        'langcode' => 'und',
        'title' => $item['name'],
      ]
    );
    $entity->save();
    $context['results'][] = $item['name'];
    $context['message'] = t('Created @title', array('@title' => $item['name']));
  }

}