function MigrateUpgradeImportBatch::run

Same name in other branches
  1. 9 core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php \Drupal\migrate_drupal_ui\Batch\MigrateUpgradeImportBatch::run()
  2. 8.9.x core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php \Drupal\migrate_drupal_ui\Batch\MigrateUpgradeImportBatch::run()
  3. 11.x core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php \Drupal\migrate_drupal_ui\Batch\MigrateUpgradeImportBatch::run()

Runs a single migrate batch import.

Parameters

int[] $initial_ids: The full set of migration IDs to import.

array $config: An array of additional configuration from the form.

array $context: The batch context.

File

core/modules/migrate_drupal_ui/src/Batch/MigrateUpgradeImportBatch.php, line 79

Class

MigrateUpgradeImportBatch
Runs a single migration batch.

Namespace

Drupal\migrate_drupal_ui\Batch

Code

public static function run($initial_ids, $config, &$context) {
    if (!static::$listenersAdded) {
        $event_dispatcher = \Drupal::service('event_dispatcher');
        $event_dispatcher->addListener(MigrateEvents::POST_ROW_SAVE, [
            static::class,
            'onPostRowSave',
        ]);
        $event_dispatcher->addListener(MigrateEvents::POST_IMPORT, [
            static::class,
            'onPostImport',
        ]);
        $event_dispatcher->addListener(MigrateEvents::MAP_SAVE, [
            static::class,
            'onMapSave',
        ]);
        $event_dispatcher->addListener(MigrateEvents::IDMAP_MESSAGE, [
            static::class,
            'onIdMapMessage',
        ]);
        static::$maxExecTime = ini_get('max_execution_time');
        if (static::$maxExecTime <= 0) {
            static::$maxExecTime = 60;
        }
        // Set an arbitrary threshold of 3 seconds (e.g., if max_execution_time is
        // 45 seconds, we will quit at 42 seconds so a slow item or cleanup
        // overhead don't put us over 45).
        static::$maxExecTime -= 3;
        static::$listenersAdded = TRUE;
    }
    if (!isset($context['sandbox']['migration_ids'])) {
        $context['sandbox']['max'] = count($initial_ids);
        $context['sandbox']['current'] = 1;
        // Total number processed for this migration.
        $context['sandbox']['num_processed'] = 0;
        // migration_ids will be the list of IDs remaining to run.
        $context['sandbox']['migration_ids'] = $initial_ids;
        $context['sandbox']['messages'] = [];
        $context['results']['failures'] = 0;
        $context['results']['successes'] = 0;
    }
    // Number processed in this batch.
    static::$numProcessed = 0;
    $migration_id = reset($context['sandbox']['migration_ids']);
    $definition = \Drupal::service('plugin.manager.migration')->getDefinition($migration_id);
    $configuration = [];
    // Set the source plugin constant, source_base_path, for all migrations with
    // a file entity destination.
    // @todo https://www.drupal.org/node/2804611.
    //   Find a way to avoid having to set configuration here.
    if ($definition['destination']['plugin'] === 'entity:file') {
        // Use the private file path if the scheme property is set in the source
        // plugin definition and is 'private' otherwise use the public file path.
        $scheme = $definition['source']['scheme'] ?? NULL;
        $base_path = $scheme === 'private' && $config['source_private_file_path'] ? $config['source_private_file_path'] : $config['source_base_path'];
        $configuration['source']['constants']['source_base_path'] = rtrim($base_path, '/');
    }
    
    /** @var \Drupal\migrate\Plugin\Migration $migration */
    $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id, $configuration);
    if ($migration) {
        static::$messages = new MigrateMessageCapture();
        $executable = new MigrateExecutable($migration, static::$messages);
        $migration_name = $migration->label() ? $migration->label() : $migration_id;
        try {
            $migration_status = $executable->import();
        } catch (\Exception $e) {
            \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
            $migration_status = MigrationInterface::RESULT_FAILED;
        }
        switch ($migration_status) {
            case MigrationInterface::RESULT_COMPLETED:
                // Store the number processed in the sandbox.
                $context['sandbox']['num_processed'] += static::$numProcessed;
                $message = new PluralTranslatableMarkup($context['sandbox']['num_processed'], 'Upgraded @migration (processed 1 item total)', 'Upgraded @migration (processed @count items total)', [
                    '@migration' => $migration_name,
                ]);
                $context['sandbox']['messages'][] = (string) $message;
                \Drupal::logger('migrate_drupal_ui')->notice($message);
                $context['sandbox']['num_processed'] = 0;
                $context['results']['successes']++;
                // If the completed migration has any follow-up migrations, add them
                // to the batch migrations.
                // @see onPostImport()
                if (!empty(static::$followUpMigrations)) {
                    foreach (static::$followUpMigrations as $migration_id => $migration) {
                        if (!in_array($migration_id, $context['sandbox']['migration_ids'], TRUE)) {
                            // Add the follow-up migration ID to the batch migration IDs for
                            // later execution.
                            $context['sandbox']['migration_ids'][] = $migration_id;
                            // Increase the number of migrations in the batch to update the
                            // progress bar and keep it accurate.
                            $context['sandbox']['max']++;
                            // Unset the follow-up migration to make sure it won't get added
                            // to the batch twice.
                            unset(static::$followUpMigrations[$migration_id]);
                        }
                    }
                }
                break;
            case MigrationInterface::RESULT_INCOMPLETE:
                $context['sandbox']['messages'][] = (string) new PluralTranslatableMarkup(static::$numProcessed, 'Continuing with @migration (processed 1 item)', 'Continuing with @migration (processed @count items)', [
                    '@migration' => $migration_name,
                ]);
                $context['sandbox']['num_processed'] += static::$numProcessed;
                break;
            case MigrationInterface::RESULT_STOPPED:
                $context['sandbox']['messages'][] = (string) new TranslatableMarkup('Operation stopped by request');
                break;
            case MigrationInterface::RESULT_FAILED:
                $context['sandbox']['messages'][] = (string) new TranslatableMarkup('Operation on @migration failed', [
                    '@migration' => $migration_name,
                ]);
                $context['results']['failures']++;
                \Drupal::logger('migrate_drupal_ui')->error('Operation on @migration failed', [
                    '@migration' => $migration_name,
                ]);
                break;
            case MigrationInterface::RESULT_SKIPPED:
                $context['sandbox']['messages'][] = (string) new TranslatableMarkup('Operation on @migration skipped due to unfulfilled dependencies', [
                    '@migration' => $migration_name,
                ]);
                \Drupal::logger('migrate_drupal_ui')->error('Operation on @migration skipped due to unfulfilled dependencies', [
                    '@migration' => $migration_name,
                ]);
                break;
            case MigrationInterface::RESULT_DISABLED:
                // Skip silently if disabled.
                break;
        }
        // Unless we're continuing on with this migration, take it off the list.
        if ($migration_status != MigrationInterface::RESULT_INCOMPLETE) {
            array_shift($context['sandbox']['migration_ids']);
            $context['sandbox']['current']++;
        }
        // Add and log any captured messages.
        foreach (static::$messages->getMessages() as $message) {
            $context['sandbox']['messages'][] = (string) $message;
            \Drupal::logger('migrate_drupal_ui')->error($message);
        }
        // Only display the last MESSAGE_LENGTH messages, in reverse order.
        $message_count = count($context['sandbox']['messages']);
        $context['message'] = '';
        for ($index = max(0, $message_count - self::MESSAGE_LENGTH); $index < $message_count; $index++) {
            $context['message'] = $context['sandbox']['messages'][$index] . "<br />\n" . $context['message'];
        }
        if ($message_count > self::MESSAGE_LENGTH) {
            // Indicate there are earlier messages not displayed.
            $context['message'] .= '&hellip;';
        }
        // At the top of the list, display the next one (which will be the one
        // that is running while this message is visible).
        if (!empty($context['sandbox']['migration_ids'])) {
            $migration_id = reset($context['sandbox']['migration_ids']);
            $migration = \Drupal::service('plugin.manager.migration')->createInstance($migration_id);
            $migration_name = $migration->label() ? $migration->label() : $migration_id;
            $context['message'] = (string) new TranslatableMarkup('Currently upgrading @migration (@current of @max total tasks)', [
                '@migration' => $migration_name,
                '@current' => $context['sandbox']['current'],
                '@max' => $context['sandbox']['max'],
            ]) . "<br />\n" . $context['message'];
        }
    }
    else {
        array_shift($context['sandbox']['migration_ids']);
        $context['sandbox']['current']++;
    }
    $context['finished'] = 1 - count($context['sandbox']['migration_ids']) / $context['sandbox']['max'];
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.