back

Knowlegde

Knowledge Centre

Drupal 8 Batch Process: Why and When You Should Use It

by editor | 09.03.2018

Drupal 8 Batch Process: Why and When You Should Use It

In one of our Drupal 8 projects, we needed to implement a batch process. Let's explore what batch processes are in Drupal 8, and understand how and when to use them effectively.

A batch process executes a series of operations without requiring user interaction. It processes data in discrete "batches" or sets of inputs, hence the name. This approach allows for handling large-scale operations that might otherwise be impractical or impossible to complete in a single request.

Why Use a Batch Process?

Batch processes are particularly valuable when handling large amounts of data that would typically cause a PHP timeout under normal execution. They break down extensive operations into manageable chunks, ensuring reliable processing while providing progress feedback to users.

Let's explore a practical scenario: Imagine you have a view that filters article content types where `field_boring` is set to TRUE, and you want to delete all of them. With 500+ matching articles, manual deletion would be time-consuming and inefficient. Let's implement a batch process to handle this task automatically.

Required Components

To implement our batch process, we need three files:

  1. A controller (Delete.php)
  2. Module information file (module.info.yml)
  3. Routing configuration (module.routing.yml)

Let's create each component:

First, create the module information file:

# module.info.yml
name: Delete
description: 'Delete articles'
core: 8.x
type: module
package: Custom

Next, set up the routing configuration to handle requests to '/delete-boring-articles':

# module.routing.yml
module.delete:
 path: '/delete-boring-articles'
 defaults:
   _controller: '\Drupal\module\Controller\Delete::delete'
   _title: 'Delete boring articles'
 requirements:
   _permission: 'administer node'

Finally, let's create our controller that handles the deletion process:

<?php
namespace Drupal\module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\node\Entity\Node;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Provides batch operations for deleting articles.
*/
class Delete extends ControllerBase {
 /**
  * Initiates the batch process for deleting articles.
  *
  * @return array
  *   Returns a batch array.
  */
 public function delete() {
   // Get results from our view.
   $view_results = views_get_view_result('boring_articles', 'page_1');
   $operations = [];
   // Build the operations array from view results.
   foreach ($view_results as $result) {
     $operations[] = [
       [$this, 'batchFunction'],
       [$result->_entity->id()],
     ];
   }
   $batch = [
     'title' => $this->t('Deleting articles'),
     'operations' => $operations,
     'finished' => [$this, 'finishedCallback'],
     'progressive' => TRUE,
   ];
   batch_set($batch);
   return batch_process();
 }
 /**
  * Processes a single node deletion.
  *
  * @param int $id
  *   The node ID to delete.
  * @param array $context
  *   The batch context array.
  */
 public function batchFunction($id, &$context) {
   try {
     $node = Node::load($id);
     if ($node) {
       $node->delete();
       $context['results'][] = $id;
       $context['message'] = $this->t('Deleted article with ID: @id', ['@id' => $id]);
     }
   }
   catch (\Exception $e) {
     $context['error_messages'][] = $this->t('Error deleting article @id: @message', [
       '@id' => $id,
       '@message' => $e->getMessage(),
     ]);
   }
 }
 /**
  * Handles batch completion.
  *
  * @param bool $success
  *   Indicates whether the batch process completed successfully.
  * @param array $results
  *   An array of processed node IDs.
  * @param array $operations
  *   An array of unprocessed operations.
  */
 public function finishedCallback($success, $results, $operations) {
   if ($success) {
     $message = $this->t('Successfully deleted @count articles.', [
       '@count' => count($results),
     ]);
     $this->messenger()->addMessage($message);
   }
   else {
     $message = $this->t('An error occurred while deleting articles.');
     $this->messenger()->addError($message);
   }
   return new RedirectResponse('/admin/content');
 }
}

Key Improvements in the Code

  1. Proper Error Handling: Added try-catch blocks to handle potential errors during node deletion.
  2. Context Usage: Implemented proper use of the batch context to track progress and results.
  3. Dependency Injection: Used Drupal's built-in translation and messenger services properly.
  4. Type Safety: Added proper type hinting and documentation blocks.
  5. Progress Tracking: Added meaningful progress messages during batch execution.
  6. Clean Completion: Improved the finished callback to provide useful feedback.

Important Notes

  1. Always test batch processes thoroughly in a development environment first.
  2. Consider adding a confirmation step before initiating the batch process.
  3. Remember to back up your database before running destructive operations.
  4. Monitor memory usage when dealing with very large datasets.

Conclusion

Batch processes in Drupal 8 provide a robust solution for handling time-consuming operations that would otherwise timeout or strain server resources. By breaking down large operations into manageable chunks, we can process significant amounts of data reliably while keeping users informed of progress.

If you encounter any issues with implementation or have questions, feel free to leave a comment below.

drupal 8 batch process
Top
default
  • Knowlegde
    Knowledge Centre
    Fine-tuning LLaMA to Recreate Eminescu's Literary Style
    editor
  • Knowlegde
    Knowledge Centre
    A New Era Begins: Drupal CMS 1.0 Launches
    editor
  • Knowlegde
    Knowledge Centre
    Bringing AI to B2B
    editor

Post a Comment.