function SqlContentEntityStorage::saveToDedicatedTables

Same name in other branches
  1. 9 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::saveToDedicatedTables()
  2. 8.9.x core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::saveToDedicatedTables()
  3. 10 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::saveToDedicatedTables()

Saves values of fields that use dedicated tables.

Parameters

\Drupal\Core\Entity\ContentEntityInterface $entity: The entity.

bool $update: TRUE if the entity is being updated, FALSE if it is being inserted.

string[] $names: (optional) The names of the fields to be stored. Defaults to all the available fields.

2 calls to SqlContentEntityStorage::saveToDedicatedTables()
SqlContentEntityStorage::doSaveFieldItems in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Writes entity field values to the storage.
SqlContentEntityStorage::restore in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Restores a previously saved entity.
1 method overrides SqlContentEntityStorage::saveToDedicatedTables()
EntityTestUpdateStorage::saveToDedicatedTables in core/modules/system/tests/modules/entity_test_update/src/EntityTestUpdateStorage.php
Saves values of fields that use dedicated tables.

File

core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php, line 1286

Class

SqlContentEntityStorage
A content entity database storage implementation.

Namespace

Drupal\Core\Entity\Sql

Code

protected function saveToDedicatedTables(ContentEntityInterface $entity, $update = TRUE, $names = []) {
    $vid = $entity->getRevisionId();
    $id = $entity->id();
    $bundle = $entity->bundle();
    $entity_type = $entity->getEntityTypeId();
    $default_langcode = $entity->getUntranslated()
        ->language()
        ->getId();
    $translation_langcodes = array_keys($entity->getTranslationLanguages());
    $table_mapping = $this->getTableMapping();
    if (!isset($vid)) {
        $vid = $id;
    }
    $original = !empty($entity->original) ? $entity->original : NULL;
    // Use the loaded revision instead of default one to check for data change.
    if ($original && !$entity->isNewRevision() && !$entity->isDefaultRevision()) {
        $original = $this->loadRevision($entity->getLoadedRevisionId());
    }
    // Determine which fields should be actually stored.
    $definitions = $this->entityFieldManager
        ->getFieldDefinitions($entity_type, $bundle);
    if ($names) {
        $definitions = array_intersect_key($definitions, array_flip($names));
    }
    foreach ($definitions as $field_name => $field_definition) {
        $storage_definition = $field_definition->getFieldStorageDefinition();
        if (!$table_mapping->requiresDedicatedTableStorage($storage_definition)) {
            continue;
        }
        // When updating an existing revision, keep the existing records if the
        // field values did not change.
        if (!$entity->isNewRevision() && $original && !$this->hasFieldValueChanged($field_definition, $entity, $original)) {
            continue;
        }
        $table_name = $table_mapping->getDedicatedDataTableName($storage_definition);
        $revision_name = $table_mapping->getDedicatedRevisionTableName($storage_definition);
        // Delete and insert, rather than update, in case a value was added.
        if ($update) {
            // Only overwrite the field's base table if saving the default revision
            // of an entity.
            if ($entity->isDefaultRevision()) {
                $this->database
                    ->delete($table_name)
                    ->condition('entity_id', $id)
                    ->execute();
            }
            if ($this->entityType
                ->isRevisionable()) {
                $this->database
                    ->delete($revision_name)
                    ->condition('entity_id', $id)
                    ->condition('revision_id', $vid)
                    ->execute();
            }
        }
        // Prepare the multi-insert query.
        $do_insert = FALSE;
        $columns = [
            'entity_id',
            'revision_id',
            'bundle',
            'delta',
            'langcode',
        ];
        foreach ($storage_definition->getColumns() as $column => $attributes) {
            $columns[] = $table_mapping->getFieldColumnName($storage_definition, $column);
        }
        $query = $this->database
            ->insert($table_name)
            ->fields($columns);
        if ($this->entityType
            ->isRevisionable()) {
            $revision_query = $this->database
                ->insert($revision_name)
                ->fields($columns);
        }
        $langcodes = $field_definition->isTranslatable() ? $translation_langcodes : [
            $default_langcode,
        ];
        foreach ($langcodes as $langcode) {
            $delta_count = 0;
            $items = $entity->getTranslation($langcode)
                ->get($field_name);
            $items->filterEmptyItems();
            foreach ($items as $delta => $item) {
                // We now know we have something to insert.
                $do_insert = TRUE;
                $record = [
                    'entity_id' => $id,
                    'revision_id' => $vid,
                    'bundle' => $bundle,
                    'delta' => $delta,
                    'langcode' => $langcode,
                ];
                foreach ($storage_definition->getColumns() as $column => $attributes) {
                    $column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
                    // Serialize the value if specified in the column schema.
                    $value = $item->{$column};
                    if (!empty($attributes['serialize'])) {
                        $value = serialize($value);
                    }
                    $record[$column_name] = SqlContentEntityStorageSchema::castValue($attributes, $value);
                }
                $query->values($record);
                if ($this->entityType
                    ->isRevisionable()) {
                    $revision_query->values($record);
                }
                if ($storage_definition->getCardinality() != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && ++$delta_count == $storage_definition->getCardinality()) {
                    break;
                }
            }
        }
        // Execute the query if we have values to insert.
        if ($do_insert) {
            // Only overwrite the field's base table if saving the default revision
            // of an entity.
            if ($entity->isDefaultRevision()) {
                $query->execute();
            }
            if ($this->entityType
                ->isRevisionable()) {
                $revision_query->execute();
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.