Planes in a production assembly line.
Began

This module provides interfaces & services to help modernize the Drupal Batch API. The batch API provided by Drupal relies on several legacy procedural functions & carefully-crafted arrays. The interfaces provided by this module rely on that older functionality.

This project was created while I was working at Unleashed Technologies & was publicly released in 2021 with their express permission. I continue to maintain it to this day.

<?php
namespace Drupal\example_module\Form\Batch;

use Drupal\Core\TypedData\TranslatableInterface;
use Drupal\batch_services\BatchWorkerService;

class FooBatchWorkerService extends BatchWorkerService {

  private ExampleHelperServiceInterface $exampleHelper;

  public function __construct(MessengerInterface $messenger, ExampleHelperServiceInterface $exampleHelper)
  {
    parent::__construct($messenger);
    $this->exampleHelper = $exampleHelper;
  }

  /**
   * Gets the batch title.
   */
  public function getTitle(): TranslatableInterface
  {
    return $this->t('Processing Foo items...');
  }

  /**
   * Gets remote items.
   *
   * @param int $page
   *   The human-readable page number (e.g. starting with "1").
   * @param int $limit
   *   How many items to get with each page.
   *
   * @return array
   *   A list of assets & metadata about the query.
   */
  public function getRemoteItems(int $page = 1, int $limit = 100): array
  {
    return [
      'media' => ['foo', 'bar', 'baz'],
      'total' => 3,
    ];
  }

  /**
   * Processes a batch item.
   */
  public function processBatchItem(): void
  {
    $result = $this->getRemoteItems($this->getPageNumber(), static::ITEMS_PER_PAGE);
    $this->setTotal($result['total']['count']);
    foreach ($result['media'] as $asset) {
      if ('baz' === $asset) {
        $this->incrementSkipped();
      }
      else {
        $this->exampleHelper->createMediaEntityFromAsset($asset)->save();
        $this->incrementCreated();
      }
      $this->incrementProgress();
      $this->incrementCurrentId();
    }
  }

}