diff -u b/core/modules/migrate/src/Entity/Migration.php b/core/modules/migrate/src/Entity/Migration.php --- b/core/modules/migrate/src/Entity/Migration.php +++ b/core/modules/migrate/src/Entity/Migration.php @@ -426,7 +426,15 @@ */ public function getInterruptionResult() { $migrate_interruption_store = \Drupal::keyValue('migrate_interruption'); - return $migrate_interruption_store->get($this->id()); + return $migrate_interruption_store->get($this->id(), NULL); + } + + /** + * {@inheritdoc} + */ + public function clearInterruptionResult() { + $migrate_interruption_store = \Drupal::keyValue('migrate_interruption'); + $migrate_interruption_store->delete($this->id()); } /** diff -u b/core/modules/migrate/src/Entity/MigrationInterface.php b/core/modules/migrate/src/Entity/MigrationInterface.php --- b/core/modules/migrate/src/Entity/MigrationInterface.php +++ b/core/modules/migrate/src/Entity/MigrationInterface.php @@ -199,6 +199,11 @@ public function getInterruptionResult(); /** + * Clears the current migration interruption result. + */ + public function clearInterruptionResult(); + + /** * Get the normalized process pipeline configuration describing the process * plugins. * diff -u b/core/modules/migrate/src/MigrateExecutable.php b/core/modules/migrate/src/MigrateExecutable.php --- b/core/modules/migrate/src/MigrateExecutable.php +++ b/core/modules/migrate/src/MigrateExecutable.php @@ -250,7 +250,9 @@ $this->sourceRowStatus = MigrateIdMapInterface::STATUS_IMPORTED; // If anyone has requested we stop, return the requested result. - if ($return = $this->migration->getInterruptionResult()) { + if ($interruption_return = $this->migration->getInterruptionResult()) { + $return = $interruption_return; + $this->migration->clearInterruptionResult(); break; } only in patch2: unchanged: --- a/core/modules/migrate/src/Tests/MigrateEventsTest.php +++ b/core/modules/migrate/src/Tests/MigrateEventsTest.php @@ -95,8 +95,9 @@ public function testMigrateEvents() { $event = $this->state->get('migrate_events_test.map_save_event', []); $this->assertIdentical($event['event_name'], MigrateEvents::MAP_SAVE); - $this->assertIdentical($event['fields']['sourceid1'], 'dummy value'); - $this->assertIdentical($event['fields']['destid1'], 'dummy value'); + // Validating the last row processed. + $this->assertIdentical($event['fields']['sourceid1'], 'dummy value2'); + $this->assertIdentical($event['fields']['destid1'], 'dummy value2'); $this->assertIdentical($event['fields']['source_row_status'], 0); $event = $this->state->get('migrate_events_test.map_delete_event', []); @@ -105,13 +106,15 @@ public function testMigrateEvents() { $event = $this->state->get('migrate_events_test.pre_row_save_event', []); $this->assertIdentical($event['event_name'], MigrateEvents::PRE_ROW_SAVE); $this->assertIdentical($event['migration']->id(), $migration->id()); - $this->assertIdentical($event['row']->getSourceProperty('data'), 'dummy value'); + // Validating the last row processed. + $this->assertIdentical($event['row']->getSourceProperty('data'), 'dummy value2'); $event = $this->state->get('migrate_events_test.post_row_save_event', []); $this->assertIdentical($event['event_name'], MigrateEvents::POST_ROW_SAVE); $this->assertIdentical($event['migration']->id(), $migration->id()); - $this->assertIdentical($event['row']->getSourceProperty('data'), 'dummy value'); - $this->assertIdentical($event['destination_id_values']['value'], 'dummy value'); + // Validating the last row processed. + $this->assertIdentical($event['row']->getSourceProperty('data'), 'dummy value2'); + $this->assertIdentical($event['destination_id_values']['value'], 'dummy value2'); // Generate a map delete event. $migration->getIdMap()->delete(['data' => 'dummy value']); only in patch2: unchanged: --- /dev/null +++ b/core/modules/migrate/src/Tests/MigrateInterruptionTest.php @@ -0,0 +1,78 @@ +addListener(MigrateEvents::POST_ROW_SAVE, + array($this, 'postRowSaveEventRecorder')); + } + + /** + * Tests migration interruptions. + */ + public function testMigrateEvents() { + // Run a simple little migration, which should trigger one of each event + // other than map_delete. + $config = [ + 'id' => 'sample_data', + 'migration_tags' => ['Event test'], + 'source' => ['plugin' => 'data'], + 'process' => ['value' => 'data'], + 'destination' => ['plugin' => 'dummy'], + 'load' => ['plugin' => 'null'], + ]; + + $migration = Migration::create($config); + + /** @var MigrationInterface $migration */ + $executable = new MigrateExecutable($migration, new MigrateMessage); + // When the import runs, the first row imported will trigger an interruption. + $result = $executable->import(); + + $this->assertEqual($result, MigrationInterface::RESULT_INCOMPLETE); + } + + /** + * Reacts to post-row-save event. + * + * @param \Drupal\Migrate\Event\MigratePostRowSaveEvent $event + * The migration event. + * @param string $name + * The event name. + */ + public function postRowSaveEventRecorder(MigratePostRowSaveEvent $event, $name) { + $event->getMigration()->setInterruptionResult(MigrationInterface::RESULT_INCOMPLETE); + } + +} only in patch2: unchanged: --- a/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/source/DataSource.php +++ b/core/modules/migrate/tests/modules/migrate_events_test/src/Plugin/migrate/source/DataSource.php @@ -31,11 +31,15 @@ public function fields() { * {@inheritdoc} */ public function initializeIterator() { - return new \ArrayIterator(array(array('data' => 'dummy value'))); + return new \ArrayIterator([ + ['data' => 'dummy value'], + ['data' => 'dummy value2'], + ]); + } public function __toString() { - return ''; + return 'Sample data for testing'; } /** @@ -50,7 +54,7 @@ public function getIds() { * {@inheritdoc} */ public function count() { - return 1; + return 2; } }