diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php index 4c2689b..ddf5629 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntity.php @@ -1,12 +1,14 @@ entityTypeManager = $entity_type_manager; $this->entityFieldManager = $entity_field_manager; - $this->entityType = $plugin_definition['entity_type']; - $entityDefinition = $this->entityTypeManager->getDefinition($this->entityType); - $this->bundleKey = $entityDefinition->getKey('bundle'); - if (!empty($this->configuration['bundle'])) { - if (!$this->bundleKey) { - throw new InvalidPluginDefinitionException('A bundle was provided but entity is not bundleable.'); - } + $this->entityType = $this->entityTypeManager->getDefinition($plugin_definition['entity_type']); + if (!$this->entityType instanceof ContentEntityTypeInterface) { + throw new InvalidPluginDefinitionException($plugin_id, 'The "entity" source plugin only supports content entities.'); + } + if (!empty($this->configuration['bundle']) && !$this->entityType->getKey('bundle')) { + throw new InvalidPluginDefinitionException('A bundle was provided but the entity type is not bundleable.'); } parent::__construct($configuration + ['bundle' => NULL], $plugin_id, $plugin_definition, $migration); } @@ -95,7 +89,7 @@ public static function create(ContainerInterface $container, array $configuratio * {@inheritdoc} */ public function __toString() { - return $this->entityType; + return (string) sprintf('%s source', $this->entityType->id()); } /** @@ -106,7 +100,7 @@ public function __toString() { */ protected function initializeIterator() { $ids = $this->query()->execute(); - return $this->yield($ids); + return $this->yieldEntities($ids); } /** @@ -118,8 +112,9 @@ protected function initializeIterator() { * @return \Generator * And iterable of loaded entities. */ - protected function yield(array $ids) { - $storage = $this->entityTypeManager->getStorage($this->entityType); + protected function yieldEntities(array $ids) { + $storage = $this->entityTypeManager + ->getStorage($this->entityType->id()); foreach ($ids as $id) { /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $storage->load($id); @@ -133,6 +128,9 @@ protected function yield(array $ids) { /** * Convert entity to array. * + * Make all IDs flat values. All other values are returned as per + * $entity->toArray(), which is a nested array. + * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The entity to convert. * @@ -140,14 +138,17 @@ protected function yield(array $ids) { * The entity converted to array. */ protected function toArray(ContentEntityInterface $entity) { - $return = []; - foreach ($entity->toArray() as $field => $values) { - $return[$field] = $values; - } - // The ids must be flat, they cannot be nested for the id map. + $return = $entity->toArray(); + // This is necessary because the IDs must be flat. They cannot be nested for + // the ID map. foreach (array_keys($this->getIds()) as $id) { $reset = reset($return[$id]); + // Force the IDs over top the previous values. + unset($return[$id]); $return[$id] = reset($reset); + if (empty($return[$id])) { + throw new MigrateException(sprintf('Entity of type %s and id %s is missing its id.', $entity->getEntityType(), $entity->id())); + } } return $return; } @@ -156,35 +157,39 @@ protected function toArray(ContentEntityInterface $entity) { * Query to retrieve entities. * * @return \Drupal\Core\Entity\Query\QueryInterface + * The query. */ public function query() { $query = $this->entityTypeManager - ->getStorage($this->entityType) + ->getStorage($this->entityType->id()) ->getQuery(); if (!empty($this->configuration['bundle'])) { - $query->condition($this->bundleKey, $this->configuration['bundle']); + $query->condition($this->entityType->getKey('bundle'), $this->configuration['bundle']); } return $query; } + /** * {@inheritdoc} */ - protected function doCount() { - return $this->query()->count()->execute(); + public function count($refresh = FALSE) { + // @TODO: Figure out a better way to retrieve a valid count. + // https://www.drupal.org/project/drupal/issues/2937166 + return -1; } /** * {@inheritdoc} */ public function fields() { - $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType); + $field_definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id()); $fields = []; foreach ($field_definitions as $field_name => $definition) { $fields[$field_name] = (string) $definition->getLabel(); } if (!empty($this->configuration['bundle'])) { - foreach ($this->entityFieldManager->getFieldDefinitions($this->entityType, $this->configuration['bundle']) as $field_name => $definition) { + foreach ($this->entityFieldManager->getFieldDefinitions($this->entityType->id(), $this->configuration['bundle']) as $field_name => $definition) { $fields[$field_name] = (string) $definition->getLabel(); } } @@ -195,11 +200,10 @@ public function fields() { * {@inheritdoc} */ public function getIds() { - $entity_definition = $this->entityTypeManager->getDefinition($this->entityType); - $idKey = $entity_definition->getKey('id'); - $ids[$idKey] = $this->getDefinitionFromEntity($idKey); - if ($entity_definition->isTranslatable()) { - $langcode_key = $entity_definition->getKey('langcode'); + $id_key = $this->entityType->getKey('id'); + $ids[$id_key] = $this->getDefinitionFromEntity($id_key); + if ($this->entityType->isTranslatable()) { + $langcode_key = $this->entityType->getKey('langcode'); $ids[$langcode_key] = $this->getDefinitionFromEntity($langcode_key); } return $ids; @@ -220,7 +224,7 @@ public function getIds() { */ protected function getDefinitionFromEntity($key) { /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */ - $field_definition = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType)[$key]; + $field_definition = $this->entityFieldManager->getBaseFieldDefinitions($this->entityType->id())[$key]; return [ 'alias' => 'b', 'type' => $field_definition->getType(), diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntityDeriver.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntityDeriver.php index 33052be..38050ca 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntityDeriver.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/ContentEntityDeriver.php @@ -1,6 +1,6 @@ sourcePluginManager->createInstance('entity:user', [], $this->migration); $this->migration->expects(self::once())->method('getSourcePlugin')->willReturn($userSource); $this->migration->expects(self::once())->method('getDestinationIds')->willReturn([1]); + $this->assertSame('user source', $userSource->__toString()); $ids = $userSource->getIds(); $this->assertArrayHasKey('langcode', $ids); $this->assertArrayHasKey('uid', $ids); @@ -218,6 +219,7 @@ public function testFileSource() { $fileSource = $this->sourcePluginManager->createInstance('entity:file', [], $this->migration); $this->migration->expects(self::once())->method('getSourcePlugin')->willReturn($fileSource); $this->migration->expects(self::once())->method('getDestinationIds')->willReturn([1]); + $this->assertSame('file source', $fileSource->__toString()); $ids = $fileSource->getIds(); $this->assertArrayHasKey('fid', $ids); $fields = $fileSource->fields(); @@ -242,6 +244,7 @@ public function testNodeSource() { $this->migration->expects(self::exactly(2))->method('getSourcePlugin')->willReturn($nodeSource); $this->migration->expects(self::at(0))->method('getDestinationIds')->willReturn([1, 'en']); $this->migration->expects(self::at(1))->method('getDestinationIds')->willReturn([2, 'fr']); + $this->assertSame('node source', $nodeSource->__toString()); $ids = $nodeSource->getIds(); $this->assertArrayHasKey('langcode', $ids); $this->assertArrayHasKey('nid', $ids); @@ -286,6 +289,7 @@ public function testMediaSource() { $mediaSource = $this->sourcePluginManager->createInstance('entity:media', ['bundle' => 'image'], $this->migration); $this->migration->expects(self::once())->method('getSourcePlugin')->willReturn($mediaSource); $this->migration->expects(self::once())->method('getDestinationIds')->willReturn([1]); + $this->assertSame('media source', $mediaSource->__toString()); $ids = $mediaSource->getIds(); $this->assertArrayHasKey('langcode', $ids); $this->assertArrayHasKey('mid', $ids); @@ -319,6 +323,7 @@ public function testTermSource() { $this->migration->expects(self::exactly(2))->method('getSourcePlugin')->willReturn($termSource); $this->migration->expects(self::at(0))->method('getDestinationIds')->willReturn([1]); $this->migration->expects(self::at(1))->method('getDestinationIds')->willReturn([2]); + $this->assertSame('taxonomy_term source', $termSource->__toString()); $ids = $termSource->getIds(); $this->assertArrayHasKey('langcode', $ids); $this->assertArrayHasKey('tid', $ids);