diff -u b/core/modules/migrate/src/Audit/AuditorInterface.php b/core/modules/migrate/src/Audit/AuditorInterface.php --- b/core/modules/migrate/src/Audit/AuditorInterface.php +++ b/core/modules/migrate/src/Audit/AuditorInterface.php @@ -23,10 +23,8 @@ * @throws \Drupal\migrate\Audit\AuditException * If the audit fails. * - * @return array - * If the audit detects no potential conflicts, an empty array is returned. - * Otherwise, the return value will be an array with a single element: a - * string explaining the nature of the conflict, keyed by the migration ID. + * @return \Drupal\migrate\Audit\AuditResult + * The result of the audit. */ public function audit(MigrationInterface $migration); @@ -36,9 +34,8 @@ * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations * The migrations to audit. * - * @return array - * An array of potential conflict information, keyed by migration ID. See - * audit() for more information. + * @return \Drupal\migrate\Audit\AuditResult[] + * The audit results, keyed by migration ID. */ public function auditMultiple(array $migrations); diff -u b/core/modules/migrate/src/Audit/IdAuditor.php b/core/modules/migrate/src/Audit/IdAuditor.php --- b/core/modules/migrate/src/Audit/IdAuditor.php +++ b/core/modules/migrate/src/Audit/IdAuditor.php @@ -2,6 +2,7 @@ namespace Drupal\migrate\Audit; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\migrate\Plugin\MigrationInterface; /** @@ -9,6 +10,8 @@ */ class IdAuditor implements AuditorInterface { + use StringTranslationTrait; + /** * {@inheritdoc} */ @@ -32,9 +35,11 @@ } if ($destination->getHighestId() > $id_map->getHighestId()) { - return static::conflict($migration); + return AuditResult::fail($migration, [ + $this->t('The destination system contains data which was not created by a migration.'), + ]); } - return []; + return AuditResult::pass($migration); } /** @@ -46,29 +51,9 @@ foreach ($migrations as $migration) { - $conflicts += $this->audit($migration); + $migration_id = $migration->getPluginId(); + $conflicts[$migration_id] = $this->audit($migration); } ksort($conflicts); return $conflicts; } - /** - * Builds a conflict array. - * - * @param \Drupal\migrate\Plugin\MigrationInterface $migration - * The migration that has the conflict. - * - * @return array - * The conflict. See \Drupal\migrate\Audit\AuditorInterface::audit() for - * information on the format of the return value. - */ - public static function conflict(MigrationInterface $migration) { - $base_id = $migration->getBaseId(); - - $conflict = [ - $base_id => $base_id, - ]; - $conflict[$base_id] = (string) $migration->label(); - - return $conflict; - } - } reverted: --- b/core/modules/migrate_drupal/migrate_drupal.services.yml +++ a/core/modules/migrate_drupal/migrate_drupal.services.yml @@ -16,5 +16,3 @@ - '@module_handler' - '\Drupal\migrate_drupal\Annotation\MigrateCckField' deprecated: The "%service_id%" service is deprecated. You should use the 'plugin.manager.migrate.field' service instead. See https://www.drupal.org/node/2751897 - migrate.audit: - class: Drupal\migrate\Audit\IdAuditor diff -u b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php --- b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php +++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php @@ -9,7 +9,7 @@ use Drupal\Core\Render\RendererInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Url; -use Drupal\migrate\Audit\AuditorInterface; +use Drupal\migrate\Audit\IdAuditor; use Drupal\migrate\Plugin\migrate\destination\EntityContentBase; use Drupal\migrate\Plugin\MigrationPluginManagerInterface; use Drupal\migrate_drupal\Plugin\MigrateFieldPluginManagerInterface; @@ -90,17 +90,14 @@ * The field plugin manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler. - * @param \Drupal\migrate\Audit\AuditorInterface $auditor - * The auditor service. */ - public function __construct(StateInterface $state, DateFormatterInterface $date_formatter, RendererInterface $renderer, MigrationPluginManagerInterface $plugin_manager, MigrateFieldPluginManagerInterface $field_plugin_manager, ModuleHandlerInterface $module_handler, AuditorInterface $auditor) { + public function __construct(StateInterface $state, DateFormatterInterface $date_formatter, RendererInterface $renderer, MigrationPluginManagerInterface $plugin_manager, MigrateFieldPluginManagerInterface $field_plugin_manager, ModuleHandlerInterface $module_handler) { $this->state = $state; $this->dateFormatter = $date_formatter; $this->renderer = $renderer; $this->pluginManager = $plugin_manager; $this->fieldPluginManager = $field_plugin_manager; $this->moduleHandler = $module_handler; - $this->auditor = $auditor; } /** @@ -113,8 +110,7 @@ $container->get('renderer'), $container->get('plugin.manager.migration'), $container->get('plugin.manager.migrate.field'), - $container->get('module_handler'), - $container->get('migrate.audit') + $container->get('module_handler') ); } @@ -494,15 +490,24 @@ $migrations = $this->pluginManager->createInstances($migration_ids); $translated_content_conflicts = $content_conflicts = []; - foreach ($migrations as $migration) { - $audit = $this->auditor->audit($migration); - $destination_plugin = $migration->getDestinationPlugin(); - if ($destination_plugin instanceof EntityContentBase && $destination_plugin->isTranslationDestination()) { - $translated_content_conflicts += $audit; + $results = (new IdAuditor())->auditMultiple($migrations); + + /** @var \Drupal\migrate\Audit\AuditResult $result */ + foreach ($results as $migration_id => $result) { + // If the migration passed the audit, we don't need to do anything. + if ($result->passed()) { + continue; + } + + $destination = $result->getMigration()->getDestinationPlugin(); + $definition = $destination->getPluginDefinition(); + + if ($destination instanceof EntityContentBase && $destination->isTranslationDestination()) { + $translated_content_conflicts[$migration_id] = $definition['label']; } else { - $content_conflicts += $audit; + $content_conflicts[$migration_id] = $definition['label']; } } if (empty($content_conflicts) && empty($translated_content_conflicts)) { only in patch2: unchanged: --- /dev/null +++ b/core/modules/migrate/src/Audit/AuditResult.php @@ -0,0 +1,146 @@ +migration = $migration; + $this->status = $status; + array_walk($reasons, [$this, 'addReason']); + } + + /** + * Returns the audited migration. + * + * @return \Drupal\migrate\Plugin\MigrationInterface + * The audited migration. + */ + public function getMigration() { + return $this->migration; + } + + /** + * Returns the boolean result of the audit. + * + * @return bool + * The result of the audit. TRUE if the migration passed the audit, FALSE + * otherwise. + */ + public function passed() { + return $this->status; + } + + /** + * Adds a reason why the migration passed or failed the audit. + * + * @param string|object $reason + * The reason to add. Can be a string or a string-castable object. + * + * @return $this + */ + public function addReason($reason) { + array_push($this->reasons, (string) $reason); + return $this; + } + + /** + * Creates a passing audit result for a migration. + * + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The audited migration. + * @param string[] $reasons + * (optional) The reasons why the migration passed the audit. + * + * @return static + */ + public static function pass(MigrationInterface $migration, array $reasons = []) { + return new static($migration, TRUE, $reasons); + } + + /** + * Creates a failing audit result for a migration. + * + * @param \Drupal\migrate\Plugin\MigrationInterface $migration + * The audited migration. + * @param array $reasons + * (optional) The reasons why the migration failed the audit. + * + * @return static + */ + public static function fail(MigrationInterface $migration, array $reasons = []) { + return new static($migration, FALSE, $reasons); + } + + /** + * Implements \Countable::count() for Twig template compatibility. + * + * @return int + * + * @see \Drupal\Component\Render\MarkupInterface + */ + public function count() { + return count($this->reasons); + } + + /** + * Returns the reasons the migration passed or failed, as a string. + * + * @return string + * + * @see \Drupal\Component\Render\MarkupInterface + */ + public function __toString() { + return implode("\n", $this->reasons); + } + + /** + * Returns the reasons the migration passed or failed, for JSON serialization. + * + * @return string[] + */ + public function jsonSerialize() { + return $this->reasons; + } + +} only in patch2: unchanged: --- a/core/modules/migrate/src/Plugin/migrate/destination/Entity.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/Entity.php @@ -94,6 +94,10 @@ * The list of bundles this entity type has. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles) { + $plugin_definition += [ + 'label' => $storage->getEntityType()->getPluralLabel(), + ]; + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration); $this->storage = $storage; $this->bundles = $bundles;