function SqlContentEntityStorage::loadFromDedicatedTables

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

Loads values of fields stored in dedicated tables for a group of entities.

Parameters

array &$values: An array of values keyed by entity ID.

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

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

1 call to SqlContentEntityStorage::loadFromDedicatedTables()
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 1247

Class

SqlContentEntityStorage
A content entity database storage implementation.

Namespace

Drupal\Core\Entity\Sql

Code

protected function loadFromDedicatedTables(array &$values, $load_from_revision, &$translations) {
  if (empty($values)) {
    return;
  }
  // Collect entities ids, bundles and languages.
  $bundles = [];
  $ids = [];
  $default_langcodes = [];
  foreach ($values as $key => $entity_values) {
    $bundles[$this->bundleKey ? $entity_values[$this->bundleKey][LanguageInterface::LANGCODE_DEFAULT] : $this->entityTypeId] = TRUE;
    $ids[] = !$load_from_revision ? $key : $entity_values[$this->revisionKey][LanguageInterface::LANGCODE_DEFAULT];
    if ($this->langcodeKey && isset($entity_values[$this->langcodeKey][LanguageInterface::LANGCODE_DEFAULT])) {
      $default_langcodes[$key] = $entity_values[$this->langcodeKey][LanguageInterface::LANGCODE_DEFAULT];
    }
  }
  // Collect impacted fields.
  $storage_definitions = [];
  $definitions = [];
  $table_mapping = $this->getTableMapping();
  foreach ($bundles as $bundle => $v) {
    $definitions[$bundle] = $this->entityFieldManager
      ->getFieldDefinitions($this->entityTypeId, $bundle);
    foreach ($definitions[$bundle] as $field_name => $field_definition) {
      $storage_definition = $field_definition->getFieldStorageDefinition();
      if ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
        $storage_definitions[$field_name] = $storage_definition;
      }
    }
  }
  $single_cardinality_fields = [];
  $multiple_cardinality_fields = [];
  $field_definition_columns = [];
  $field_columns = [];
  foreach ($storage_definitions as $field_name => $storage_definition) {
    $field_columns[$field_name] = $this->tableMapping
      ->getColumnNames($field_name);
    $field_definition_columns[$field_name] = $storage_definition->getColumns();
    if ($storage_definition->getCardinality() === 1) {
      $single_cardinality_fields[$field_name] = $storage_definition;
    }
    else {
      $multiple_cardinality_fields[$field_name] = $storage_definition;
    }
  }
  $id_key = !$load_from_revision ? 'entity_id' : 'revision_id';
  // Because any field could potentially have no data, we need to begin
  // the query from a table that will reliably exist, which means the base,
  // data, or revision table.
  $base_table = $load_from_revision ? $this->revisionDataTable ?? $this->revisionTable : $this->dataTable ?? $this->baseTable;
  $base_id_key = !$load_from_revision ? $this->idKey : $this->revisionKey;
  $base_query = $this->database
    ->select($base_table, $base_table)
    ->fields($base_table)
    ->condition("[{$base_table}].[{$base_id_key}]", $ids, 'IN');
  // Alias the base langcode field so that it does not get overwritten by
  // results from field tables.
  $base_langcode_alias = '';
  if ($this->langcodeKey) {
    $base_langcode_alias = $base_table . '__' . $this->langcodeKey;
    $base_query->addField($base_table, $this->langcodeKey, $base_langcode_alias);
  }
  // When the number of fields exceeds the chunk size, split the fields to
  // load into chunks. The SQL limits for table joins are over 60, so always
  // combine the last two chunks. This means that 26 fields end up in a single
  // chunk of 26, instead of chunks of 25 and 1.
  $load_shared_table_fields = TRUE;
  if (count($single_cardinality_fields) > static::FIELD_MINIMUM_CHUNK_SIZE) {
    $chunks = array_chunk($single_cardinality_fields, static::FIELD_MINIMUM_CHUNK_SIZE, TRUE);
    $last_chunk = array_pop($chunks);
    $last_key = array_key_last($chunks);
    $chunks[$last_key] = array_merge($chunks[$last_key], $last_chunk);
  }
  else {
    $chunks = [
      $single_cardinality_fields,
    ];
  }
  foreach ($chunks as $fields) {
    $this->loadSingleCardinalityFields($values, $base_query, $base_table, $id_key, $base_id_key, $base_langcode_alias, $load_from_revision, $fields, $definitions, $field_columns, $field_definition_columns, $default_langcodes, $load_shared_table_fields, $translations);
    $load_shared_table_fields = FALSE;
  }
  if ($multiple_cardinality_fields) {
    if (count($multiple_cardinality_fields) > static::FIELD_MINIMUM_CHUNK_SIZE) {
      $chunks = array_chunk($multiple_cardinality_fields, static::FIELD_MINIMUM_CHUNK_SIZE, TRUE);
      $last_chunk = array_pop($chunks);
      $last_key = array_key_last($chunks);
      $chunks[$last_key] = array_merge($chunks[$last_key], $last_chunk);
    }
    else {
      $chunks = [
        $multiple_cardinality_fields,
      ];
    }
    foreach ($chunks as $fields) {
      $this->loadMultipleCardinalityFields($values, $base_query, $base_table, $id_key, $base_id_key, $base_langcode_alias, $load_from_revision, $fields, $definitions, $field_columns, $field_definition_columns, $default_langcodes);
    }
    // Ensure that all of the deltas from all of the multiple cardinality
    // fields are returned in the correct order.
    foreach ($values as &$fields) {
      foreach ($fields as $field_name => &$field_data) {
        if (isset($multiple_cardinality_fields[$field_name])) {
          foreach ($field_data as &$language_data) {
            ksort($language_data);
          }
        }
      }
    }
  }
}

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