function SqlContentEntityStorage::loadSingleCardinalityFields
Same name and namespace in other branches
- 11.x core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::loadSingleCardinalityFields()
Load single cardinality fields.
Parameters
array &$values: The entity values populated so far.
\Drupal\Core\Database\Query\SelectInterface $base_query: The base database query.
string $base_table: The base table used in the query.
string $id_key: The ID key depending on whether regular entities or revisions are being loaded.
string $base_id_key: The base ID key depending on whether regular entities or revisions are being loaded.
string $base_langcode_alias: The base langcode alias.
bool $load_from_revision: Whether we're loading from revisions.
array $single_cardinality_fields: The single cardinality fields to load.
array $definitions: The field definitions.
array $field_columns: The field columns.
array $field_definition_columns: The field definition columns.
array $default_langcodes: The default langcodes.
bool $load_shared_table_fields: Whether to also load fields from the shared data/revision data tables. Should be TRUE only on the first chunk iteration to avoid overwriting shared field values.
array $translations: The translations array, keyed by entity ID and langcode.
1 call to SqlContentEntityStorage::loadSingleCardinalityFields()
- SqlContentEntityStorage::loadFromDedicatedTables in core/
lib/ Drupal/ Core/ Entity/ Sql/ SqlContentEntityStorage.php - Loads values of fields stored in dedicated tables for a group of entities.
File
-
core/
lib/ Drupal/ Core/ Entity/ Sql/ SqlContentEntityStorage.php, line 1394
Class
- SqlContentEntityStorage
- A content entity database storage implementation.
Namespace
Drupal\Core\Entity\SqlCode
private function loadSingleCardinalityFields(array &$values, SelectInterface $base_query, string $base_table, string $id_key, string $base_id_key, string $base_langcode_alias, bool $load_from_revision, array $single_cardinality_fields, array $definitions, array $field_columns, array $field_definition_columns, array $default_langcodes, bool $load_shared_table_fields = TRUE, array &$translations = []) : void {
$query = clone $base_query;
$shared_fields = [];
$table_mapping = $this->getTableMapping();
if ($load_shared_table_fields) {
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.
$shared_fields = $revisioned_fields;
if ($data_fields) {
$shared_fields = array_merge($revisioned_fields, $data_fields);
if ($load_from_revision) {
$query->leftJoin($this->dataTable, 'data', "([data].[{$this->idKey}] = [{$base_table}].[{$this->idKey}] AND [{$base_table}].[{$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_values($table_mapping->getColumnNames($data_field));
}
$column_names = array_merge(...$column_names);
$query->fields('data', $column_names);
}
}
}
else {
$shared_fields = $table_mapping->getFieldNames($base_table);
}
foreach ($shared_fields as $field_name) {
$storage_definition = $this->fieldStorageDefinitions[$field_name];
$field_definition_columns[$field_name] = $storage_definition->getColumns();
$field_columns[$field_name] = $table_mapping->getColumnNames($field_name);
}
}
// Add a left join for each single cardinality field.
foreach ($single_cardinality_fields as $field_name => $storage_definition) {
$table = !$load_from_revision ? $table_mapping->getDedicatedDataTableName($storage_definition) : $table_mapping->getDedicatedRevisionTableName($storage_definition);
// If the entity is translatable, add the langcode to the join and
// a condition on valid langcodes.
if ($this->langcodeKey) {
$query->leftJoin($table, $table, "[{$table}].[{$id_key}] = [{$base_table}].[{$base_id_key}] AND [{$table}].[langcode] = [{$base_table}].[{$this->langcodeKey}] AND [{$table}].[deleted] = 0");
}
else {
$query->leftJoin($table, $table, "[{$table}].[{$id_key}] = [{$base_table}].[{$base_id_key}] AND [{$table}].[deleted] = 0");
}
$query->fields($table, $table_mapping->getColumnNames($field_name));
}
$results = $query->execute();
$is_not_null = fn($value) => !is_null($value);
foreach ($results as $row) {
$row = (array) $row;
$value_key = $row[$base_id_key];
$bundle = $this->bundleKey ? $values[$value_key][$this->bundleKey][LanguageInterface::LANGCODE_DEFAULT] : $this->entityTypeId;
// Field values in default language are stored with
// LanguageInterface::LANGCODE_DEFAULT as key.
$langcode = $this->langcodeKey && empty($row[$this->defaultLangcodeKey]) ? $row[$base_langcode_alias] : LanguageInterface::LANGCODE_DEFAULT;
$translations[$value_key][$langcode] = TRUE;
foreach ($shared_fields as $field_name) {
$definition_columns = $field_definition_columns[$field_name];
$columns = $field_columns[$field_name];
// Do not key single-column fields by property name.
if (count($columns) == 1) {
$column_name = reset($columns);
// Special case for the langcode key which is aliased in the query
// results.
if ($column_name === $this->langcodeKey) {
$column_name = $base_langcode_alias;
}
$column_attributes = $definition_columns[key($columns)];
$values[$value_key][$field_name][$langcode] = !empty($column_attributes['serialize']) ? $this->handleNullableFieldUnserialize($row[$column_name]) : $row[$column_name];
}
else {
foreach ($columns as $property_name => $column_name) {
$column_attributes = $definition_columns[$property_name];
$values[$value_key][$field_name][$langcode][$property_name] = !empty($column_attributes['serialize']) ? $this->handleNullableFieldUnserialize($row[$column_name]) : $row[$column_name];
}
}
}
$langcode = $this->langcodeKey && empty($row[$this->defaultLangcodeKey]) && isset($default_langcodes[$value_key]) && $row[$base_langcode_alias] != $default_langcodes[$value_key] ? $row[$base_langcode_alias] : LanguageInterface::LANGCODE_DEFAULT;
foreach ($single_cardinality_fields as $field_name => $storage_definition) {
$field_values = array_intersect_key($row, array_flip($field_columns[$field_name]));
// If all the field values are null, then there was no result for this
// field.
// @todo use array_any() once Drupal core requires PHP 8.4.
if (empty(array_filter($field_values, $is_not_null))) {
continue;
}
if (!isset($values[$value_key][$field_name][$langcode])) {
$values[$value_key][$field_name][$langcode] = [];
}
// Ensure that records for non-translatable fields having invalid
// languages are skipped.
if ($langcode == LanguageInterface::LANGCODE_DEFAULT || $definitions[$bundle][$field_name]->isTranslatable()) {
if (empty($values[$value_key][$field_name][$langcode])) {
$item = [];
// For each column declared by the field, populate the item from
// the prefixed database column.
foreach ($field_definition_columns[$field_name] as $column => $attributes) {
$column_name = $table_mapping->getFieldColumnName($storage_definition, $column);
// Unserialize the value if specified in the column schema.
$item[$column] = !empty($attributes['serialize']) ? $this->handleNullableFieldUnserialize($row[$column_name]) : $row[$column_name];
}
// Add the item to the field values for the entity.
$values[$value_key][$field_name][$langcode][] = $item;
}
}
}
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.