You are here

public static function IndexBatchHelper::process in Search API 8

Processes an index batch operation.

Parameters

\Drupal\search_api\IndexInterface $index: The index on which items should be indexed.

int $batch_size: The maximum number of items to index per batch pass.

int $limit: The maximum number of items to index in total, or -1 to index all items.

array|\ArrayAccess $context: The context of the current batch, as defined in the Batch operations documentation.

File

src/IndexBatchHelper.php, line 113

Class

IndexBatchHelper
Provides helper methods for indexing items using Drupal's Batch API.

Namespace

Drupal\search_api

Code

public static function process(IndexInterface $index, $batch_size, $limit, &$context) {

  // Check if the sandbox should be initialized.
  if (!isset($context['sandbox']['limit'])) {

    // Initialize the sandbox with data which is shared among the batch runs.
    $context['sandbox']['limit'] = $limit;
    $context['sandbox']['batch_size'] = $batch_size;
  }

  // Check if the results should be initialized.
  if (!isset($context['results']['indexed'])) {

    // Initialize the results with data which is shared among the batch runs.
    $context['results']['indexed'] = 0;
    $context['results']['not indexed'] = 0;
  }

  // Get the remaining item count. When no valid tracker is available then
  // the value will be set to zero which will cause the batch process to
  // stop.
  $remaining_item_count = $index
    ->hasValidTracker() ? $index
    ->getTrackerInstance()
    ->getRemainingItemsCount() : 0;

  // Check if an explicit limit needs to be used.
  if ($context['sandbox']['limit'] > -1) {

    // Calculate the remaining amount of items that can be indexed. Note that
    // a minimum is taking between the allowed number of items and the
    // remaining item count to prevent incorrect reporting of not indexed
    // items.
    $actual_limit = min($context['sandbox']['limit'] - $context['results']['indexed'], $remaining_item_count);
  }
  else {

    // Use the remaining item count as actual limit.
    $actual_limit = $remaining_item_count;
  }

  // Store original count of items to be indexed to show progress properly.
  if (empty($context['sandbox']['original_item_count'])) {
    $context['sandbox']['original_item_count'] = $actual_limit;
  }

  // Determine the number of items to index for this run.
  $to_index = min($actual_limit, $context['sandbox']['batch_size']);

  // Catch any exception that may occur during indexing.
  try {

    // Index items limited by the given count.
    $indexed = $index
      ->indexItems($to_index);

    // Increment the indexed result and progress.
    $context['results']['indexed'] += $indexed;

    // Display progress message.
    if ($indexed > 0) {
      $context['message'] = static::formatPlural($context['results']['indexed'], 'Successfully indexed 1 item.', 'Successfully indexed @count items.');
    }

    // Everything has been indexed?
    if ($indexed === 0 || $context['results']['indexed'] >= $context['sandbox']['original_item_count']) {
      $context['finished'] = 1;
      $context['results']['not indexed'] = $context['sandbox']['original_item_count'] - $context['results']['indexed'];
    }
    else {
      $context['finished'] = $context['results']['indexed'] / $context['sandbox']['original_item_count'];
    }
  } catch (\Exception $e) {

    // Log exception to watchdog and abort the batch job.
    watchdog_exception('search_api', $e);
    $context['message'] = static::t('An error occurred during indexing: @message', [
      '@message' => $e
        ->getMessage(),
    ]);
    $context['finished'] = 1;
    $context['results']['not indexed'] = $context['sandbox']['original_item_count'] - $context['results']['indexed'];
  }
}