diff --git a/core/modules/migrate/src/MigrateExecutable.php b/core/modules/migrate/src/MigrateExecutable.php index 46a0bb0d1282..4755167220d8 100644 --- a/core/modules/migrate/src/MigrateExecutable.php +++ b/core/modules/migrate/src/MigrateExecutable.php @@ -330,11 +330,14 @@ class MigrateExecutable implements MigrateExecutableInterface { foreach ($id_map as $map_row) { $destination_key = $id_map->currentDestination(); if ($destination_key) { - $this->getEventDispatcher() - ->dispatch(MigrateEvents::PRE_ROW_DELETE, new MigrateRowDeleteEvent($this->migration, $destination_key)); - $destination->rollback($destination_key); - $this->getEventDispatcher() - ->dispatch(MigrateEvents::POST_ROW_DELETE, new MigrateRowDeleteEvent($this->migration, $destination_key)); + $map_row = $id_map->getRowByDestination($destination_key); + if ($map_row['rollback_action'] == MigrateIdMapInterface::ROLLBACK_DELETE) { + $this->getEventDispatcher() + ->dispatch(MigrateEvents::PRE_ROW_DELETE, new MigrateRowDeleteEvent($this->migration, $destination_key)); + $destination->rollback($destination_key); + $this->getEventDispatcher() + ->dispatch(MigrateEvents::POST_ROW_DELETE, new MigrateRowDeleteEvent($this->migration, $destination_key)); + } // We're now done with this row, so remove it from the map. $id_map->deleteDestination($destination_key); } diff --git a/core/modules/migrate/src/Tests/MigrateRollbackTest.php b/core/modules/migrate/src/Tests/MigrateRollbackTest.php index 302425012c2b..4fda48c78226 100644 --- a/core/modules/migrate/src/Tests/MigrateRollbackTest.php +++ b/core/modules/migrate/src/Tests/MigrateRollbackTest.php @@ -9,6 +9,8 @@ namespace Drupal\migrate\Tests; use Drupal\migrate\Entity\Migration; use Drupal\migrate\MigrateExecutable; +use Drupal\migrate\Plugin\MigrateIdMapInterface; +use Drupal\migrate\Row; use Drupal\taxonomy\Entity\Term; use Drupal\taxonomy\Entity\Vocabulary; @@ -112,6 +114,12 @@ class MigrateRollbackTest extends MigrateTestBase { // Import and validate term entities were created. $term_executable = new MigrateExecutable($term_migration, $this); $term_executable->import(); + // Mark one row to be preserved on rollback. + $preserved_term_id = 2; + $map_row = $term_id_map->getRowBySource(['id' => $preserved_term_id]); + $dummy_row = new Row(['id' => $preserved_term_id], $ids); + $term_id_map->saveIdMapping($dummy_row, [$map_row['destid1']], + $map_row['source_row_status'], MigrateIdMapInterface::ROLLBACK_PRESERVE); foreach ($term_data_rows as $row) { /** @var Term $term */ $term = Term::load($row['id']); @@ -124,7 +132,12 @@ class MigrateRollbackTest extends MigrateTestBase { $term_executable->rollback(); foreach ($term_data_rows as $row) { $term = Term::load($row['id']); - $this->assertNull($term); + if ($row['id'] == $preserved_term_id) { + $this->assertNotNull($term); + } + else { + $this->assertNull($term); + } $map_row = $term_id_map->getRowBySource(['id' => $row['id']]); $this->assertFalse($map_row); }