You are here

MigrateBatchExecutable.php in Migrate source UI 8

File

src/MigrateBatchExecutable.php
View source
<?php

namespace Drupal\migrate_source_ui;

use Drupal\migrate\MigrateMessageInterface;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate_tools\MigrateBatchExecutable as BaseMigrateBatchExecutable;

/**
 * Defines a migrate executable class for batch migrations through UI.
 */
class MigrateBatchExecutable extends BaseMigrateBatchExecutable {

  /**
   * The file path.
   *
   * @var string
   */
  protected $filePath;

  /**
   * {@inheritdoc}
   */
  public function __construct(MigrationInterface $migration, MigrateMessageInterface $message, array $options = []) {
    parent::__construct($migration, $message, $options);
    $this->filePath = $options['file_path'];
  }

  /**
   * Helper to generate the batch operations for importing migrations.
   *
   * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations
   *   The migrations.
   * @param string $operation
   *   The batch operation to perform.
   * @param array $options
   *   The migration options.
   *
   * @return array
   *   The batch operations to perform.
   */
  protected function batchOperations(array $migrations, $operation, array $options = []) {
    $operations = [];
    foreach ($migrations as $migration) {
      if (!empty($options['update'])) {
        $migration
          ->getIdMap()
          ->prepareUpdate();
      }
      if (!empty($options['force'])) {
        $migration
          ->set('requirements', []);
      }
      else {
        $dependencies = $migration
          ->getMigrationDependencies();
        if (!empty($dependencies['required'])) {
          $required_migrations = $this->migrationPluginManager
            ->createInstances($dependencies['required']);

          // For dependent migrations will need to be migrate all items.
          $operations += $this
            ->batchOperations($required_migrations, $operation, [
            'limit' => 0,
            'update' => $options['update'],
            'force' => $options['force'],
          ]);
        }
      }
      $operations[] = [
        [
          get_class($this),
          'batchProcessImport',
        ],
        [
          $migration
            ->id(),
          $options + [
            'file_path' => $this->filePath,
          ],
        ],
      ];
    }
    return $operations;
  }

  /**
   * Batch 'operation' callback.
   *
   * @param string $migration_id
   *   The migration id.
   * @param array $options
   *   The batch executable options.
   * @param array|\DrushBatchContext $context
   *   The sandbox context.
   */
  public static function batchProcessImport($migration_id, array $options, &$context) {
    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'] = MigrateBatchExecutable::BATCH_IMPORT;
    }

    // Prepare the migration executable.
    $message = new StubMigrationMessage();
    $definition = \Drupal::getContainer()
      ->get('plugin.manager.migration')
      ->getDefinition($migration_id);

    // Override the file path.
    $definition['source']['path'] = $options['file_path'];

    /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
    $migration = \Drupal::getContainer()
      ->get('plugin.manager.migration')
      ->createStubMigration($definition);
    $executable = new MigrateBatchExecutable($migration, $message, $options);
    if (empty($context['sandbox']['total'])) {
      $context['sandbox']['total'] = $executable
        ->getSource()
        ->count();
      $context['sandbox']['batch_limit'] = $executable
        ->calculateBatchLimit($context);
      $context['results'][$migration
        ->id()] = [
        '@numitems' => 0,
        '@created' => 0,
        '@updated' => 0,
        '@failures' => 0,
        '@ignored' => 0,
        '@name' => $migration
          ->id(),
      ];
    }

    // 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
        ->id(),
    ];

    // 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'] = (double) $context['sandbox']['counter'] / (double) $context['sandbox']['total'];
        $context['message'] = t('Importing %migration (@percent%).', [
          '%migration' => $migration
            ->label(),
          '@percent' => (int) ($context['finished'] * 100),
        ]);
      }
    }
  }

}

Classes

Namesort descending Description
MigrateBatchExecutable Defines a migrate executable class for batch migrations through UI.