diff --git a/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php new file mode 100644 index 0000000..90390ec --- /dev/null +++ b/src/Plugin/Derivative/MigrateEntityReferenceRevisions.php @@ -0,0 +1,26 @@ +entityDefinitions as $entityType => $entityInfo) { + if ($entityInfo->getKey('revision')) { + $this->derivatives[$entityType] = array( + 'id' => "entity_reference_revisions:$entityType", + 'class' => EntityReferenceRevisions::class, + 'requirements_met' => 1, + 'provider' => $entityInfo->getProvider(), + ); + } + } + return $this->derivatives; + } + +} diff --git a/src/Plugin/migrate/destination/EntityReferenceRevisions.php b/src/Plugin/migrate/destination/EntityReferenceRevisions.php new file mode 100644 index 0000000..647a1d8 --- /dev/null +++ b/src/Plugin/migrate/destination/EntityReferenceRevisions.php @@ -0,0 +1,100 @@ +save(); + + return [ + $this->getKey('id') => $entity->id(), + $this->getKey('revision') => $entity->getRevisionId(), + ]; + } + + /** + * {@inheritdoc} + */ + public function getIds() { + if ($revision_key = $this->getKey('revision')) { + // TODO: Improve after https://www.drupal.org/node/2783715 is finished. + $ids[$revision_key]['type'] = 'integer'; + + $id_key = $this->getKey('id'); + $ids[$id_key]['type'] = 'integer'; + + if ($this->isTranslationDestination()) { + if ($revision_key = $this->getKey('langcode')) { + $ids[$revision_key]['type'] = 'string'; + } + else { + throw new MigrateException('This entity type does not support translation.'); + } + } + + return $ids; + } + throw new MigrateException('This entity type does not support revisions.'); + } + + /** + * {@inheritdoc} + */ + protected function getEntity(Row $row, array $oldDestinationIdValues) { + $entityId = $oldDestinationIdValues ? + reset($oldDestinationIdValues) : + $row->getDestinationProperty($this->getKey('id')); + $revisionId = $oldDestinationIdValues ? + array_pop($oldDestinationIdValues) : + $row->getDestinationProperty($this->getKey('revision')); + if (!empty($entityId) && !empty($revisionId) && ($entities = $this->storage->loadByProperties([$this->getKey('id') => $entityId, $this->getKey('revision') => $revisionId]))) { + $entity = reset($entities); + $entity->setNewRevision(FALSE); + } + else { + // Attempt to ensure we always have a bundle. + if ($bundle = $this->getBundle($row)) { + $row->setDestinationProperty($this->getKey('bundle'), $bundle); + } + + // Stubs might need some required fields filled in. + if ($row->isStub()) { + $this->processStubRow($row); + } + $entity = $this->storage->create($row->getDestination()); + $entity->enforceIsNew(); + } + return $entity; + } + +} diff --git a/tests/modules/err_migration_test/err_migration_test.info.yml b/tests/modules/err_migration_test/err_migration_test.info.yml new file mode 100644 index 0000000..d61822b --- /dev/null +++ b/tests/modules/err_migration_test/err_migration_test.info.yml @@ -0,0 +1,9 @@ +name: 'ERR migration test' +type: module +description: 'Entity migration test' +package: Testing +core: 8.x + +dependencies: + - entity_reference_revisions + - migrate diff --git a/tests/modules/err_migration_test/migration_templates/err_migration_test.yml b/tests/modules/err_migration_test/migration_templates/err_migration_test.yml new file mode 100644 index 0000000..e5d6d34 --- /dev/null +++ b/tests/modules/err_migration_test/migration_templates/err_migration_test.yml @@ -0,0 +1,12 @@ +id: err_migration_test +migration_tags: {} +label: 'ERR Migration Test' +source: + plugin: err_dummy +process: + id: id + revision_id: revision_id + name: name +destination: + plugin: 'entity_reference_revisions:entity_test_composite' +migration_dependencies: { } diff --git a/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php b/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php new file mode 100644 index 0000000..3a13d00 --- /dev/null +++ b/tests/modules/err_migration_test/src/Plugin/migrate/source/DummySource.php @@ -0,0 +1,49 @@ + [ + 'type' => 'integer', + ] + ]; + } + + /** + * {@inheritdoc} + */ + protected function initializeIterator() { + return new \ArrayIterator([ + ['id' => 1, 'revision_id' => 1, 'name' => 'content item 1'], + ['id' => '', 'revision_id' => '', 'name' => 'content item 2'], + ]); + } +} diff --git a/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php new file mode 100644 index 0000000..d61b720 --- /dev/null +++ b/tests/src/Kernel/Plugin/Derivative/EntityReferenceRevisionsDeriverTest.php @@ -0,0 +1,49 @@ +installConfig($this->modules); + } + + /** + * Tests deriver. + * + * @covers ::getDerivativeDefinitions + */ + public function testDestinationDeriver() { + /** @var MigrationPluginManager $migrationManager */ + $migrationManager = \Drupal::service('plugin.manager.migration'); + /** @var MigrateDestinationPluginManager $migrationDestinationManager */ + $migrationDestinationManager = \Drupal::service('plugin.manager.migrate.destination'); + + $definition = $migrationManager->getDefinition('err_migration_test'); + $destination = $migrationDestinationManager->getDefinition($definition['destination']['plugin']); + $this->assertEquals(EntityReferenceRevisions::class, $destination['class']); + } + + + +} diff --git a/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php b/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php new file mode 100644 index 0000000..837ced8 --- /dev/null +++ b/tests/src/Kernel/Plugin/migrate/destination/EntityReferenceRevisionsDestinationTest.php @@ -0,0 +1,97 @@ +installEntitySchema('entity_test_composite'); + $this->installSchema('system', ['sequences']); + $this->installConfig($this->modules); + } + + /** + * Tests get entity type id. + * + * @covers ::getEntityTypeId + */ + public function testGetEntityTypeId() { + /** @var MigrationPluginManager $migrationManager */ + $migrationManager = \Drupal::service('plugin.manager.migration'); + $definition = $migrationManager->getDefinition('err_migration_test'); + /** @var Migration $migration */ + $migration = $migrationManager->createStubMigration($definition); + /** @var EntityReferenceRevisions $destination */ + $destination = $migration->getDestinationPlugin(); + + /** @var EntityStorageBase $storage */ + $storage = $this->readAttribute($destination, 'storage'); + $actual = $this->readAttribute($storage, 'entityTypeId'); + + $expected = 'entity_test_composite'; + $this->assertEquals($expected, $actual); + } + + /** + * Tests get entity. + * + * @covers ::getEntity + */ + public function testGetEntity() { + /** @var MigrationPluginManager $migrationManager */ + $migrationManager = \Drupal::service('plugin.manager.migration'); + $definition = $migrationManager->getDefinition('err_migration_test'); + /** @var Migration $migration */ + $migration = $migrationManager->createStubMigration($definition); + $migrationExecutable = (new MigrateExecutable($migration, $this)); + for ($i = 0; $i < 2; $i++) { + $migrationExecutable->import(); + $migration->getIdMap()->prepareUpdate(); + $entities = \Drupal::entityManager()->getStorage('entity_test_composite')->loadByProperties(['id' => 1, 'revision_id' => 1]); + $entity = reset($entities); + $this->assertEquals('content item 1', $entity->label()); + $entities = \Drupal::entityManager()->getStorage('entity_test_composite')->loadByProperties(['id' => 2, 'revision_id' => 2]); + $entity = reset($entities); + $this->assertEquals('content item 2', $entity->label()); + } + } + + /** + * {@inheritdoc} + */ + public function display($message, $type = 'status') { + $this->assertTrue($type == 'status', $message); + } + +}