/**
  * Displays any messages being logged to the ID map.
  *
  * @param \Drupal\migrate\Event\MigrateIdMapMessageEvent $event
  *   The message event.
  */
 public static function onIdMapMessage(MigrateIdMapMessageEvent $event)
 {
     if ($event->getLevel() == MigrationInterface::MESSAGE_NOTICE || $event->getLevel() == MigrationInterface::MESSAGE_INFORMATIONAL) {
         $type = 'status';
     } else {
         $type = 'error';
     }
     $source_id_string = implode(',', $event->getSourceIdValues());
     $message = t('Source ID @source_id: @message', ['@source_id' => $source_id_string, '@message' => $event->getMessage()]);
     static::$messages->display($message, $type);
 }
 /**
  * Run a single migration batch.
  *
  * @param array $initial_ids
  *   The full set of migration IDs to import.
  * @param string $operation
  *   'import' or 'rollback'.
  * @param $context
  *   The batch context.
  */
 public static function run($initial_ids, $operation, &$context)
 {
     if (!static::$listenersAdded) {
         if ($operation == 'import') {
             \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_SAVE, [get_class(), 'onPostRowSave']);
             \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_SAVE, [get_class(), 'onMapSave']);
         } else {
             \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_DELETE, [get_class(), 'onPostRowDelete']);
             \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_DELETE, [get_class(), 'onMapDelete']);
         }
         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;
         // 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;
         $context['results']['operation'] = $operation;
     }
     $migration_id = reset($context['sandbox']['migration_ids']);
     /** @var \Drupal\migrate\Entity\Migration $migration */
     $migration = Migration::load($migration_id);
     if ($migration) {
         $messages = new MigrateMessageCapture();
         $executable = new MigrateExecutable($migration, $messages);
         $migration_name = $migration->label() ? $migration->label() : $migration_id;
         try {
             if ($operation == 'import') {
                 $migration_status = $executable->import();
             } else {
                 $migration_status = $executable->rollback();
             }
         } catch (\Exception $e) {
             static::logger()->error($e->getMessage());
             $migration_status = MigrationInterface::RESULT_FAILED;
         }
         switch ($migration_status) {
             case MigrationInterface::RESULT_COMPLETED:
                 if ($operation == 'import') {
                     $singular_message = 'Upgraded @migration (processed 1 item total)';
                     $plural_message = 'Upgraded @migration (processed @num_processed items total)';
                     // @todo Remove when https://www.drupal.org/node/2598696 is released.
                     if ($migration_id == 'd6_user' || $migration_id == 'd7_user') {
                         $table = 'migrate_map_' . $migration_id;
                         db_merge($table)->key(['sourceid1' => 1])->fields(['destid1' => -1])->execute();
                     }
                 } else {
                     $singular_message = 'Rolled back @migration (processed 1 item total)';
                     $plural_message = 'Rolled back @migration (processed @num_processed items total)';
                     $migration->delete();
                 }
                 // @todo: Not quite right (although it will appear to be right most of the time).
                 // We should instead accumulate per-migration total processed numbers in
                 // the sandbox.
                 if ($operation == 'import') {
                     $processed = $migration->getIdMap()->processedCount();
                 } else {
                     $processed = static::$numProcessed;
                 }
                 $message = \Drupal::translation()->formatPlural($processed, $singular_message, $plural_message, ['@migration' => $migration_name, '@num_processed' => $processed]);
                 $context['sandbox']['messages'][] = $message;
                 static::logger()->notice($message);
                 static::$numProcessed = 0;
                 $context['results']['successes']++;
                 break;
             case MigrationInterface::RESULT_INCOMPLETE:
                 $singular_message = 'Continuing with @migration (processed 1 item)';
                 $plural_message = 'Continuing with @migration (processed @num_processed items)';
                 $context['sandbox']['messages'][] = \Drupal::translation()->formatPlural(static::$numProcessed, $singular_message, $plural_message, ['@migration' => $migration_name, '@num_processed' => static::$numProcessed]);
                 static::$numProcessed = 0;
                 break;
             case MigrationInterface::RESULT_STOPPED:
                 $context['sandbox']['messages'][] = t('Operation stopped by request');
                 break;
             case MigrationInterface::RESULT_FAILED:
                 $context['sandbox']['messages'][] = t('Operation on @migration failed', ['@migration' => $migration_name]);
                 $context['results']['failures']++;
                 static::logger()->error('Operation on @migration failed', ['@migration' => $migration_name]);
                 break;
             case MigrationInterface::RESULT_SKIPPED:
                 $context['sandbox']['messages'][] = t('Operation on @migration skipped due to unfulfilled dependencies', ['@migration' => $migration_name]);
                 static::logger()->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 ($messages->getMessages() as $message) {
             $context['sandbox']['messages'][] = $message;
             static::logger()->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 = Migration::load($migration_id);
             $migration_name = $migration->label() ? $migration->label() : $migration_id;
             if ($operation == 'import') {
                 $message = 'Currently upgrading @migration (@current of @max total tasks)';
             } else {
                 $message = 'Currently rolling back @migration (@current of @max total tasks)';
             }
             $context['message'] = t($message, ['@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'];
 }