Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance entity creation with base field expansion and dynamic id key #271

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Drupal/Driver/Cores/AbstractCore.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
99 changes: 46 additions & 53 deletions src/Drupal/Driver/Cores/Drupal8.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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}
*/
Expand Down Expand Up @@ -496,39 +461,67 @@ 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;
}

/**
* {@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();
}
Expand Down
Loading