SU-SWS/stanford_migrate

View on GitHub
src/StanfordMigrateBatchExecutable.php

Summary

Maintainability
A
0 mins
Test Coverage
B
87%
<?php

namespace Drupal\stanford_migrate;

use Drupal\migrate\MigrateMessage;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_tools\MigrateBatchExecutable;

/**
 * Class StanfordMigrateBatchExecutable that changes the batch methods.
 *
 * The primary object of this class is entirely to change the batch_limit in an
 * effort to import 15 items on each batch execution.
 *
 * @package Drupal\stanford_migrate
 */
class StanfordMigrateBatchExecutable extends MigrateBatchExecutable {

  /**
   * {@inheritdoc}
   */
  public function batchImport(): void {
    // Create the batch operations for each migration that needs to be executed.
    // This includes the migration for this executable, but also the dependent
    // migrations.
    $operations = $this->batchOperations([$this->migration], 'import', [
      'limit' => $this->itemLimit,
      'update' => $this->updateExistingRows,
      'force' => $this->checkDependencies,
      'sync' => $this->syncSource,
      'configuration' => $this->configuration,
    ]);

    if (count($operations) > 0) {
      $batch = [
        'operations' => $operations,
        'title' => t('Migrating %migrate', ['%migrate' => $this->migration->label()]),
        'init_message' => t('Start migrating %migrate', ['%migrate' => $this->migration->label()]),
        'progress_message' => t('Migrating %migrate', ['%migrate' => $this->migration->label()]),
        'error_message' => t('An error occurred while migrating %migrate.', ['%migrate' => $this->migration->label()]),
        'finished' => '\Drupal\stanford_migrate\StanfordMigrateBatchExecutable::batchFinishedImport',
      ];

      batch_set($batch);
    }
  }

  /**
   * {@inheritdoc}
   */
  protected function batchOperations(array $migrations, $operation, array $options = []): array {
    array_walk($migrations, [$this, 'prepareMigrations']);
    $operations = parent::batchOperations($migrations, $operation, $options);
    foreach ($operations as &$operation) {
      // Change the operation to use this class instead of the parent.
      $operation[0] = [self::class, 'batchProcessImport'];
    }
    return $operations;
  }

  /**
   * Reset status of the migration and its dependency migration.
   *
   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
   *   Migration object to reset.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   */
  protected function prepareMigrations(MigrationInterface $migration) {
    $migration->interruptMigration(MigrationInterface::RESULT_STOPPED);
    $migration->setStatus(MigrationInterface::STATUS_IDLE);
    foreach ($migration->getMigrationDependencies()['required'] as $dependency_id) {
      /** @var \Drupal\migrate\Plugin\MigrationInterface $dependent_migration */
      $dependent_migration = $this->migrationPluginManager->createInstance($dependency_id);
      $this->prepareMigrations($dependent_migration);
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function batchProcessImport($migration_id, array $options, &$context): void {
    if (empty($context['sandbox'])) {
      $context['finished'] = 0;
      $context['sandbox'] = [];
      $context['sandbox']['total'] = 0;
      $context['sandbox']['counter'] = 0;
      $context['sandbox']['batch_limit'] = 0;
      $context['sandbox']['operation'] = StanfordMigrateBatchExecutable::BATCH_IMPORT;
    }

    // Prepare the migration executable.
    $message = new MigrateMessage();
    /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
    $migration = \Drupal::getContainer()
      ->get('plugin.manager.migration')
      ->createInstance($migration_id, $options);

    // Make sure the migration plugin has the passed configuration settings.
    foreach ($options['configuration'] as $key => $value) {
      $migration->set($key, $value);
    }

    $executable = new StanfordMigrateBatchExecutable($migration, $message, $options);

    if (empty($context['sandbox']['total'])) {
      $context['sandbox']['total'] = $executable->getSource()->count();

      // THIS is the only change from the parent class. Allow 15 items to be
      // imported on each batch execution. The parent split the total items
      // into 100 executions which doesn't really do anything helpful.
      $context['sandbox']['batch_limit'] = \Drupal::config('stanford_migrate.settings')
        ->get('batch_limit') ?: 15;
      $context['results'][$migration->id()] = [
        '@numitems' => 0,
        '@created' => 0,
        '@updated' => 0,
        '@failures' => 0,
        '@ignored' => 0,
        '@name' => $migration->label(),
      ];
    }

    // Every iteration, we reset out batch counter.
    $context['sandbox']['batch_counter'] = 0;

    // Make sure we know our batch context.
    $executable->setBatchContext($context);

    // Do the import.
    $result = $executable->import();

    // Store the result; will need to combine the results of all our iterations.
    $context['results'][$migration->id()] = [
      '@numitems' => $context['results'][$migration->id()]['@numitems'] + $executable->getProcessedCount(),
      '@created' => $context['results'][$migration->id()]['@created'] + $executable->getCreatedCount(),
      '@updated' => $context['results'][$migration->id()]['@updated'] + $executable->getUpdatedCount(),
      '@failures' => $context['results'][$migration->id()]['@failures'] + $executable->getFailedCount(),
      '@ignored' => $context['results'][$migration->id()]['@ignored'] + $executable->getIgnoredCount(),
      '@name' => $migration->label(),
    ];

    // Do some housekeeping.
    if ($result != MigrationInterface::RESULT_INCOMPLETE) {
      $context['finished'] = 1;
    }
    else {
      $context['sandbox']['counter'] = $context['results'][$migration->id()]['@numitems'];
      if ($context['sandbox']['counter'] <= $context['sandbox']['total']) {
        $context['finished'] = ((float) $context['sandbox']['counter'] / (float) $context['sandbox']['total']);
        $context['message'] = t('Importing %migration (@percent%).', [
          '%migration' => $migration->label(),
          '@percent' => (int) ($context['finished'] * 100),
        ]);
      }
    }

  }

}