diff --git a/src/Drupal/Driver/Cores/AbstractCore.php b/src/Drupal/Driver/Cores/AbstractCore.php index 89b1e01..4520bc1 100644 --- a/src/Drupal/Driver/Cores/AbstractCore.php +++ b/src/Drupal/Driver/Cores/AbstractCore.php @@ -81,6 +81,9 @@ protected function expandEntityFields($entity_type, \stdClass $entity, array $ba $field_types = $this->getEntityFieldTypes($entity_type, $base_fields); foreach ($field_types as $field_name => $type) { if (isset($entity->$field_name)) { + // Consistently expand into an array of field values. + $entity->$field_name = !isset($entity->$field_name[0]) ? [$entity->$field_name] : $entity->$field_name; + // Expand array of field values using appropriate field handler. $entity->$field_name = $this->getFieldHandler($entity, $entity_type, $field_name) ->expand($entity->$field_name); } diff --git a/src/Drupal/Driver/Cores/Drupal8.php b/src/Drupal/Driver/Cores/Drupal8.php index ddbdf18..9ff3854 100644 --- a/src/Drupal/Driver/Cores/Drupal8.php +++ b/src/Drupal/Driver/Cores/Drupal8.php @@ -91,19 +91,10 @@ public function nodeCreate($node) { } // If 'author' is set, remap it to 'uid'. if (isset($node->author)) { - $user = user_load_by_name($node->author); - /** @var \Drupal\user\Entity\User $user */ - if ($user) { - $node->uid = $user->id(); - } + $node->uid = $node->author; } - $this->expandEntityFields('node', $node); - $entity = Node::create((array) $node); - $entity->save(); - - $node->nid = $entity->id(); - return $node; + return $this->entityCreate('node', $node); } /** @@ -134,14 +125,7 @@ public function userCreate(\stdClass $user) { $user->status = 1; } - // Clone user object, otherwise user_save() changes the password to the - // hashed password. - $this->expandEntityFields('user', $user); - $account = \Drupal::entityTypeManager()->getStorage('user')->create((array) $user); - $account->save(); - - // Store UID. - $user->uid = $account->id(); + return $this->entityCreate('user', $user); } /** @@ -344,12 +328,7 @@ public function termCreate(\stdClass $term) { } } - $this->expandEntityFields('taxonomy_term', $term); - $entity = Term::create((array) $term); - $entity->save(); - - $term->tid = $entity->id(); - return $term; + return $this->entityCreate('taxonomy_term', $term); } /** @@ -383,20 +362,6 @@ public function getExtensionPathList() { return $paths; } - /** - * Expands specified base fields on the entity object. - * - * @param string $entity_type - * The entity type for which to return the field types. - * @param \StdClass $entity - * Entity object. - * @param array $base_fields - * Base fields to be expanded in addition to user defined fields. - */ - public function expandEntityBaseFields($entity_type, \StdClass $entity, array $base_fields) { - $this->expandEntityFields($entity_type, $entity, $base_fields); - } - /** * {@inheritdoc} */ @@ -496,31 +461,56 @@ public function configSet($name, $key, $value) { * {@inheritdoc} */ public function entityCreate($entity_type, $entity) { + if (empty($entity_type)) { + throw new \Exception("You must specify an entity type to create an entity."); + } + + $entity_type_definition = \Drupal::entityTypeManager() + ->getDefinition($entity_type); + $id_key = $entity_type_definition + ->getKey('id'); + $bundle_key = $entity_type_definition + ->getKey('bundle'); + // If the bundle field is empty, put the inferred bundle value in it. - $bundle_key = \Drupal::entityTypeManager()->getDefinition($entity_type)->getKey('bundle'); - if (!isset($entity->$bundle_key) && isset($entity->step_bundle)) { - $entity->$bundle_key = $entity->step_bundle; + // Try first for step_bundle. Use entity type as last resort. + if (!isset($entity->$bundle_key)) { + $entity->$bundle_key = $entity->step_bundle ?? $entity_type; } // Throw an exception if a bundle is specified but does not exist. - if (isset($entity->$bundle_key) && ($entity->$bundle_key !== NULL)) { - /** @var \Drupal\Core\Entity\EntityTypeBundleInfo $bundle_info */ - $bundle_info = \Drupal::service('entity_type.bundle.info'); - $bundles = $bundle_info->getBundleInfo($entity_type); + if (isset($entity->$bundle_key)) { + $bundles = \Drupal::service('entity_type.bundle.info') + ->getBundleInfo($entity_type); if (!in_array($entity->$bundle_key, array_keys($bundles))) { throw new \Exception("Cannot create entity because provided bundle '$entity->$bundle_key' does not exist."); } } - if (empty($entity_type)) { - throw new \Exception("You must specify an entity type to create an entity."); + + // Determine which base fields are set on the source entity object so we + // can include them when expanding field values. + $base_fields = []; + foreach (array_keys(\Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type)) as $base_field_name) { + // The bundle field does not need expanding, so we exclude it even if set. + if (property_exists($entity, $base_field_name) && $base_field_name !== $bundle_key) { + $base_fields[] = $base_field_name; + } } - $this->expandEntityFields($entity_type, $entity); - $createdEntity = \Drupal::entityTypeManager()->getStorage($entity_type)->create((array) $entity); - $createdEntity->save(); + // Expand all fields that are set on the source entity object into a new + // values object we'll use to create the actual entity. This keeps the + // source entity object in the simpler format expected by related methods. + $values = clone $entity; + $this->expandEntityFields($entity_type, $values, $base_fields); - $entity->id = $createdEntity->id(); + // Create the new entity. + $createdEntity = \Drupal::entityTypeManager() + ->getStorage($entity_type) + ->create((array) $values); + $createdEntity->save(); + // Store the ID of the new entity into our source entity and return it. + $entity->$id_key = $createdEntity->id(); return $entity; } @@ -528,7 +518,10 @@ public function entityCreate($entity_type, $entity) { * {@inheritdoc} */ public function entityDelete($entity_type, $entity) { - $entity = $entity instanceof EntityInterface ? $entity : \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity->id); + $id_key = \Drupal::entityTypeManager() + ->getDefinition($entity_type) + ->getKey('id'); + $entity = $entity instanceof EntityInterface ? $entity : \Drupal::entityTypeManager()->getStorage($entity_type)->load($entity->$id_key); if ($entity instanceof EntityInterface) { $entity->delete(); }