Batch processing in Drupal 8 and Drupal 9

lakshmi , Credit to  volkotech-solutions Nov 18

Batch processing involves executing a series of tasks without interruption. It's useful for handling large amounts of data that would otherwise cause PHP timeout.

Batch processes get their name from running multiple programs on different inputs.

In this blog, we learn how to create a batch process to change the language code und (undefined language code) to de (German language code) of all Nodes in Drupal 8/9 using a custom module.

Create a .info.yml file:

Let's name our custom module "batch_und_langcode". Create the folder /modules/custom/batch_und_langcode. In this folder, we'll need to create a batch_und_langcode.info.yml file and add the following code.

name: Batch UND Language Code.
type: module
description: This module change undefine language code (und) to german language code (de).
core: 8.x
package: "Custom"
core_version_requirement: ^8 || ^9

Enable a module:

For all possible ways to enable a module click here.

Using the Manage administrative menu, navigate to the Extend page in the list of modules, search the Batch UND Language Code module and then select its checkbox. Scroll down to the bottom of the webpage, and then click Install, then the Custom module batch_und_langcode has been enabled successfully.

Declaring a route:

The routing information is saved in batch_und_langcode /batch_und_langcode.routing.yml.

batch_und_langcode.replace_with_de_langcode:
  path: '/batch-langcode/replace'
  defaults:
    _form: '\Drupal\batch_und_langcode\Form\ReplaceLanguageCodeForm'
    _title: 'Batch Language Code'
  requirements:
    _permission: 'access content'

Create a form:

Create a new subfolder "modules/custom/batch_und_langcode/src/Form." Create a file called "ReplaceLanguageCodeForm.php" in this folder with the following content and in this, just a submit button is required on the form to process the request.

<?php

namespace Drupal\batch_und_langcode\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Class ReplaceLanguageCodeForm.
 *
 * @package Drupal\batch_und_langcode\Form
 */
class ReplaceLanguageCodeForm extends FormBase {


  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'replace_langcode_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['replace_language'] = [
      '#type' => 'submit',
      '#value' => $this->t('Replace Language code'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
   $query = \Drupal::entityTypeManager()->getStorage('node')->getQuery();
   $query->condition('langcode', 'und', '=');
   $nids = $query->range(0,150)->execute();

   $batch = [
     'title' => t('Replacing Language Code...'),
     'operations' => [],
     'finished' => '\Drupal\batch_und_langcode\ReplaceLanguageCode::replaceLangcodeFinishedCallback',
   ];
   foreach($nids as $nid) {
     $batch['operations'][] = ['\Drupal\batch_und_langcode\ReplaceLanguageCode::replaceLangcode', [$nid]];
   }

   batch_set($batch);
  }

}

In order to avoid processing interruptions, the Drupal batch_set method will carry out a set of operations in batches.

Define methods:

Create a file "modules/custom/batch_und_langcode/src/ReplaceLanguageCode.php" with following content:

<?php

namespace Drupal\batch_und_langcode;

class ReplaceLanguageCode {

  public static function replaceLangcode($nid, &$context){
    $message = 'Replacing langcode(und to de)...';
    $results = array();
    $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
    $node->set('langcode', 'de');
    $results[] = $node->save();
    $context['message'] = $message;
    $context['results'][] = $nid;
  }

  function replaceLangcodeFinishedCallback($success, $results, $operations) {
    // The 'success' parameter means no fatal PHP errors were detected. All
    // other error management should be handled using 'results'.
    if ($success) {
      $message = \Drupal::translation()->formatPlural(
        count($results),
        'One post processed.', '@count posts processed.'
      );
    }
    else {
      $message = t('Finished with an error.');
    }
    \Drupal::messenger()->addMessage($message);
  }
}

After clearing the cache, then navigate to the '/batch-langcode/replace', the output should be,

batch form

Once click "Replace Language code", then start the batch process of changing the language code und (undefined language code) to de (German language code) of all Nodes.

 

Comments