You are here

public function SqlContentEntityStorage::countFieldData in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php \Drupal\Core\Entity\Sql\SqlContentEntityStorage::countFieldData()

Determines the number of entities with values for a given field.

Parameters

\Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition: The field for which to count data records.

bool $as_bool: (Optional) Optimizes the query for checking whether there are any records or not. Defaults to FALSE.

Return value

bool|int The number of entities. If $as_bool parameter is TRUE then the value will either be TRUE or FALSE.

Overrides FieldableEntityStorageInterface::countFieldData

See also

\Drupal\Core\Entity\FieldableEntityStorageInterface::purgeFieldData()

File

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

Class

SqlContentEntityStorage
A content entity database storage implementation.

Namespace

Drupal\Core\Entity\Sql

Code

public function countFieldData($storage_definition, $as_bool = FALSE) {

  // Ensure that the table mapping is instantiated with the passed-in field
  // storage definition.
  $storage_definitions = $this->fieldStorageDefinitions;
  $storage_definitions[$storage_definition
    ->getName()] = $storage_definition;
  $table_mapping = $this
    ->getTableMapping($storage_definitions);
  if ($table_mapping
    ->requiresDedicatedTableStorage($storage_definition)) {
    $is_deleted = $storage_definition
      ->isDeleted();
    if ($this->entityType
      ->isRevisionable()) {
      $table_name = $table_mapping
        ->getDedicatedRevisionTableName($storage_definition, $is_deleted);
    }
    else {
      $table_name = $table_mapping
        ->getDedicatedDataTableName($storage_definition, $is_deleted);
    }
    $query = $this->database
      ->select($table_name, 't');
    $or = $query
      ->orConditionGroup();
    foreach ($storage_definition
      ->getColumns() as $column_name => $data) {
      $or
        ->isNotNull($table_mapping
        ->getFieldColumnName($storage_definition, $column_name));
    }
    $query
      ->condition($or);
    if (!$as_bool) {
      $query
        ->fields('t', [
        'entity_id',
      ])
        ->distinct(TRUE);
    }
  }
  elseif ($table_mapping
    ->allowsSharedTableStorage($storage_definition)) {

    // Ascertain the table this field is mapped too.
    $field_name = $storage_definition
      ->getName();
    $table_name = $table_mapping
      ->getFieldTableName($field_name);
    $query = $this->database
      ->select($table_name, 't');
    $or = $query
      ->orConditionGroup();
    foreach (array_keys($storage_definition
      ->getColumns()) as $property_name) {
      $or
        ->isNotNull($table_mapping
        ->getFieldColumnName($storage_definition, $property_name));
    }
    $query
      ->condition($or);
    if (!$as_bool) {
      $query
        ->fields('t', [
        $this->idKey,
      ])
        ->distinct(TRUE);
    }
  }

  // @todo Find a way to count field data also for fields having custom
  //   storage. See https://www.drupal.org/node/2337753.
  $count = 0;
  if (isset($query)) {

    // If we are performing the query just to check if the field has data
    // limit the number of rows.
    if ($as_bool) {
      $query
        ->range(0, 1)
        ->addExpression('1');
    }
    else {

      // Otherwise count the number of rows.
      $query = $query
        ->countQuery();
    }
    $count = $query
      ->execute()
      ->fetchField();
  }
  return $as_bool ? (bool) $count : (int) $count;
}