diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php index 56260e6..3ce4802 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php @@ -195,6 +195,8 @@ protected function doSave($id, EntityInterface $entity) { * @param string[] $names * (optional) The name of the fields to be written to the storage. If an * empty value is passed all field values are saved. + * + * @api */ abstract protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []); diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php index 927a946..07456aa 100644 --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php @@ -935,130 +935,95 @@ public function save(EntityInterface $entity) { * {@inheritdoc} */ protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = []) { - if (!$names) { - $this->doSaveFieldItemsFull($entity); - } - else { - $this->doSaveFieldItemsPartial($entity, $names); - } - } - - /** - * Writes a full entity to the database. - * - * @param \Drupal\Core\Entity\ContentEntityInterface $entity - * The entity object. - * - * @internal - */ - protected function doSaveFieldItemsFull(ContentEntityInterface $entity) { - // Create the storage record to be saved. - $record = $this->mapToStorageRecord($entity); + $full_save = empty($names); + $update = !$full_save || !$entity->isNew(); - $is_new = $entity->isNew(); - if (!$is_new) { - if ($entity->isDefaultRevision()) { - $this->database - ->update($this->baseTable) - ->fields((array) $record) - ->condition($this->idKey, $record->{$this->idKey}) - ->execute(); - } - if ($this->revisionTable) { - $entity->{$this->revisionKey} = $this->saveRevision($entity); - } - if ($this->dataTable) { - $this->saveToSharedTables($entity); - } - if ($this->revisionDataTable) { - $this->saveToSharedTables($entity, $this->revisionDataTable); - } + if ($full_save) { + $shared_table_fields = TRUE; + $dedicated_table_fields = TRUE; } else { - $insert_id = $this->database - ->insert($this->baseTable, array('return' => Database::RETURN_INSERT_ID)) - ->fields((array) $record) - ->execute(); - // Even if this is a new entity the ID key might have been set, in which - // case we should not override the provided ID. An ID key that is not set - // to any value is interpreted as NULL (or DEFAULT) and thus overridden. - if (!isset($record->{$this->idKey})) { - $record->{$this->idKey} = $insert_id; - } - $entity->{$this->idKey} = (string) $record->{$this->idKey}; - if ($this->revisionTable) { - $record->{$this->revisionKey} = $this->saveRevision($entity); - } - if ($this->dataTable) { - $this->saveToSharedTables($entity); - } - if ($this->revisionDataTable) { - $this->saveToSharedTables($entity, $this->revisionDataTable); - } - } - - $this->saveToDedicatedTables($entity, !$is_new); - } - - /** - * Saves a set of entity fields to the database. - * - * @param \Drupal\Core\Entity\ContentEntityInterface $entity - * The entity object. - * @param string[] $names - * The name of the fields to be written to the database. - * - * @internal - */ - protected function doSaveFieldItemsPartial(ContentEntityInterface $entity, array $names) { - $table_mapping = $this->getTableMapping(); - $storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->entityTypeId); - $shared_table_fields = FALSE; - $dedicated_table_fields = []; - - // Collect the name of fields to be written in dedicated tables and check - // whether shared table records need to be updated. - foreach ($names as $name) { - $storage_definition = $storage_definitions[$name]; - if ($table_mapping->allowsSharedTableStorage($storage_definition)) { - $shared_table_fields = TRUE; - } - elseif ($table_mapping->requiresDedicatedTableStorage($storage_definition)) { - $dedicated_table_fields[] = $name; + $table_mapping = $this->getTableMapping(); + $storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->entityTypeId); + $shared_table_fields = FALSE; + $dedicated_table_fields = []; + + // Collect the name of fields to be written in dedicated tables and check + // whether shared table records need to be updated. + foreach ($names as $name) { + $storage_definition = $storage_definitions[$name]; + if ($table_mapping->allowsSharedTableStorage($storage_definition)) { + $shared_table_fields = TRUE; + } + elseif ($table_mapping->requiresDedicatedTableStorage($storage_definition)) { + $dedicated_table_fields[] = $name; + } } } // Update shared table records if necessary. if ($shared_table_fields) { - $default_revision = $entity->isDefaultRevision(); - if ($default_revision) { - $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->baseTable); - $this->database - ->update($this->baseTable) - ->fields((array) $record) - ->condition($this->idKey, $record->{$this->idKey}) - ->execute(); + $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->baseTable); + // Create the storage record to be saved. + if ($update) { + $default_revision = $entity->isDefaultRevision(); + if ($default_revision) { + $this->database + ->update($this->baseTable) + ->fields((array) $record) + ->condition($this->idKey, $record->{$this->idKey}) + ->execute(); + } + if ($this->revisionTable) { + if ($full_save) { + $entity->{$this->revisionKey} = $this->saveRevision($entity); + } + else { + $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->revisionTable); + $entity->preSaveRevision($this, $record); + $this->database + ->update($this->revisionTable) + ->fields((array) $record) + ->condition($this->revisionKey, $record->{$this->revisionKey}) + ->execute(); + } + } + if ($default_revision && $this->dataTable) { + $this->saveToSharedTables($entity); + } + if ($this->revisionDataTable) { + $new_revision = $full_save ? $entity->isNewRevision() : FALSE; + $this->saveToSharedTables($entity, $this->revisionDataTable, $new_revision); + } } - if ($this->revisionTable) { - $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->revisionTable); - $entity->preSaveRevision($this, $record); - $this->database - ->update($this->revisionTable) + else { + $insert_id = $this->database + ->insert($this->baseTable, array('return' => Database::RETURN_INSERT_ID)) ->fields((array) $record) - ->condition($this->revisionKey, $record->{$this->revisionKey}) ->execute(); - } - if ($default_revision && $this->dataTable) { - $this->saveToSharedTables($entity); - } - if ($this->revisionDataTable) { - $this->saveToSharedTables($entity, $this->revisionDataTable, FALSE); + // Even if this is a new entity the ID key might have been set, in which + // case we should not override the provided ID. An ID key that is not set + // to any value is interpreted as NULL (or DEFAULT) and thus overridden. + if (!isset($record->{$this->idKey})) { + $record->{$this->idKey} = $insert_id; + } + $entity->{$this->idKey} = (string) $record->{$this->idKey}; + if ($this->revisionTable) { + $record->{$this->revisionKey} = $this->saveRevision($entity); + } + if ($this->dataTable) { + $this->saveToSharedTables($entity); + } + if ($this->revisionDataTable) { + $this->saveToSharedTables($entity, $this->revisionDataTable); + } } } // Update dedicated table records if necessary. if ($dedicated_table_fields) { - $this->saveToDedicatedTables($entity, TRUE, $dedicated_table_fields); + $names = is_array($dedicated_table_fields) ? $dedicated_table_fields : []; + $this->saveToDedicatedTables($entity, $update, $names); } }