function SqlContentEntityStorage::loadFromSharedTables

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

Loads values for fields stored in the shared data tables.

Parameters

array &$values: Associative array of entities values, keyed on the entity ID or the revision ID.

array &$translations: List of translations, keyed on the entity ID.

bool $load_from_revision: Flag to indicate whether revisions should be loaded or not.

1 call to SqlContentEntityStorage::loadFromSharedTables()
SqlContentEntityStorage::mapFromStorageRecords in core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
Maps from storage records to entity objects, and attaches fields.

File

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

Class

SqlContentEntityStorage
A content entity database storage implementation.

Namespace

Drupal\Core\Entity\Sql

Code

protected function loadFromSharedTables(array &$values, array &$translations, $load_from_revision) {
    $record_key = !$load_from_revision ? $this->idKey : $this->revisionKey;
    if ($this->dataTable) {
        // If a revision table is available, we need all the properties of the
        // latest revision. Otherwise we fall back to the data table.
        $table = $this->revisionDataTable ?: $this->dataTable;
        $alias = $this->revisionDataTable ? 'revision' : 'data';
        $query = $this->database
            ->select($table, $alias, [
            'fetch' => \PDO::FETCH_ASSOC,
        ])
            ->fields($alias)
            ->condition($alias . '.' . $record_key, array_keys($values), 'IN')
            ->orderBy($alias . '.' . $record_key);
        $table_mapping = $this->getTableMapping();
        if ($this->revisionDataTable) {
            // Find revisioned fields that are not entity keys. Exclude the langcode
            // key as the base table holds only the default language.
            $base_fields = array_diff($table_mapping->getFieldNames($this->baseTable), [
                $this->langcodeKey,
            ]);
            $revisioned_fields = array_diff($table_mapping->getFieldNames($this->revisionDataTable), $base_fields);
            // Find fields that are not revisioned or entity keys. Data fields have
            // the same value regardless of entity revision.
            $data_fields = array_diff($table_mapping->getFieldNames($this->dataTable), $revisioned_fields, $base_fields);
            // If there are no data fields then only revisioned fields are needed
            // else both data fields and revisioned fields are needed to map the
            // entity values.
            $all_fields = $revisioned_fields;
            if ($data_fields) {
                $all_fields = array_merge($revisioned_fields, $data_fields);
                $query->leftJoin($this->dataTable, 'data', "([revision].[{$this->idKey}] = [data].[{$this->idKey}] AND [revision].[{$this->langcodeKey}] = [data].[{$this->langcodeKey}])");
                $column_names = [];
                // Some fields can have more then one columns in the data table so
                // column names are needed.
                foreach ($data_fields as $data_field) {
                    // \Drupal\Core\Entity\Sql\TableMappingInterface::getColumnNames()
                    // returns an array keyed by property names so remove the keys
                    // before array_merge() to avoid losing data with fields having the
                    // same columns i.e. value.
                    $column_names = array_merge($column_names, array_values($table_mapping->getColumnNames($data_field)));
                }
                $query->fields('data', $column_names);
            }
            // Get the revision IDs.
            $revision_ids = [];
            foreach ($values as $entity_values) {
                $revision_ids[] = $entity_values[$this->revisionKey][LanguageInterface::LANGCODE_DEFAULT];
            }
            $query->condition('revision.' . $this->revisionKey, $revision_ids, 'IN');
        }
        else {
            $all_fields = $table_mapping->getFieldNames($this->dataTable);
        }
        $result = $query->execute();
        foreach ($result as $row) {
            $id = $row[$record_key];
            // Field values in default language are stored with
            // LanguageInterface::LANGCODE_DEFAULT as key.
            $langcode = empty($row[$this->defaultLangcodeKey]) ? $row[$this->langcodeKey] : LanguageInterface::LANGCODE_DEFAULT;
            $translations[$id][$langcode] = TRUE;
            foreach ($all_fields as $field_name) {
                $storage_definition = $this->fieldStorageDefinitions[$field_name];
                $definition_columns = $storage_definition->getColumns();
                $columns = $table_mapping->getColumnNames($field_name);
                // Do not key single-column fields by property name.
                if (count($columns) == 1) {
                    $column_name = reset($columns);
                    $column_attributes = $definition_columns[key($columns)];
                    $values[$id][$field_name][$langcode] = !empty($column_attributes['serialize']) ? unserialize($row[$column_name]) : $row[$column_name];
                }
                else {
                    foreach ($columns as $property_name => $column_name) {
                        $column_attributes = $definition_columns[$property_name];
                        $values[$id][$field_name][$langcode][$property_name] = !empty($column_attributes['serialize']) ? unserialize($row[$column_name]) : $row[$column_name];
                    }
                }
            }
        }
    }
}

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