You are here

public function views_handler_field_field::query in Views (for Drupal 7) 7.3

Called to add the field to a query.

By default, the only columns added to the query are entity_id and entity_type. This is because other needed data is fetched by entity_load(). Other columns are added only if they are used in groupings, or if 'add fields to query' is specifically set to TRUE in the field definition.

The 'add fields to query' switch is used by modules which need all data present in the query itself (such as "sphinx").

Overrides views_handler_field::query

File

modules/field/views_handler_field_field.inc, line 172
Definition of views_handler_field_field.

Class

views_handler_field_field
A field that displays fieldapi fields.

Code

public function query($use_groupby = FALSE) {
  $this
    ->get_base_table();
  $params = array();
  if ($use_groupby) {

    // When grouping on a "field API" field (whose "real_field" is set to
    // entity_id), retrieve the minimum entity_id to have a valid entity_id to
    // pass to field_view_field().
    $params = array(
      'function' => 'min',
    );
    $this
      ->ensure_my_table();
  }

  // Get the entity type according to the base table of the field.
  // Then add it to the query as a formula. That way we can avoid joining
  // the field table if all we need is entity_id and entity_type.
  $entity_type = $this->definition['entity_tables'][$this->base_table];
  $entity_info = entity_get_info($entity_type);
  if (isset($this->relationship)) {
    $this->base_table_alias = $this->relationship;
  }
  else {
    $this->base_table_alias = $this->base_table;
  }

  // We always need the base field (entity_id / revision_id).
  if (empty($this->definition['is revision'])) {
    $this->field_alias = $this->query
      ->add_field($this->base_table_alias, $entity_info['entity keys']['id'], '', $params);
  }
  else {
    $this->field_alias = $this->query
      ->add_field($this->base_table_alias, $entity_info['entity keys']['revision'], '', $params);
    $this->aliases['entity_id'] = $this->query
      ->add_field($this->base_table_alias, $entity_info['entity keys']['id'], '', $params);
  }

  // The alias needs to be unique, so we use both the field table and the
  // entity type.
  $entity_type_alias = $this->definition['table'] . '_' . $entity_type . '_entity_type';
  $this->aliases['entity_type'] = $this->query
    ->add_field(NULL, "'{$entity_type}'", $entity_type_alias);
  $fields = $this->additional_fields;

  // We've already added entity_type, so we can remove it from the list.
  $entity_type_key = array_search('entity_type', $fields);
  if ($entity_type_key !== FALSE) {
    unset($fields[$entity_type_key]);
  }
  if ($use_groupby) {

    // Add the fields that we're actually grouping on.
    $options = array();
    if ($this->options['group_column'] != 'entity_id') {
      $options = array(
        $this->options['group_column'] => $this->options['group_column'],
      );
    }
    $options += is_array($this->options['group_columns']) ? $this->options['group_columns'] : array();
    $fields = array();
    $rkey = $this->definition['is revision'] ? 'FIELD_LOAD_REVISION' : 'FIELD_LOAD_CURRENT';

    // Go through the list and determine the actual column name from field
    // API.
    foreach ($options as $column) {
      $name = $column;
      if (isset($this->field_info['storage']['details']['sql'][$rkey][$this->table][$column])) {
        $name = $this->field_info['storage']['details']['sql'][$rkey][$this->table][$column];
      }
      $fields[$column] = $name;
    }
    $this->group_fields = $fields;
  }

  // Add additional fields (and the table join itself) if needed.
  if ($this
    ->add_field_table($use_groupby)) {
    $this
      ->ensure_my_table();
    $this
      ->add_additional_fields($fields);

    // Filter by language, if field translation is enabled.
    $field = $this->field_info;
    if (field_is_translatable($entity_type, $field) && !empty($this->view->display_handler->options['field_language_add_to_query'])) {
      $column = $this->table_alias . '.language';

      // By the same reason as field_language the field might be
      // LANGUAGE_NONE in reality so allow it as well.
      // @see this::field_language()
      global $language_content;
      $default_language = language_default('language');
      $language = str_replace(array(
        '***CURRENT_LANGUAGE***',
        '***DEFAULT_LANGUAGE***',
      ), array(
        $language_content->language,
        $default_language,
      ), $this->view->display_handler->options['field_language']);
      $placeholder = $this
        ->placeholder();
      $language_fallback_candidates = array(
        $language,
      );
      if (variable_get('locale_field_language_fallback', TRUE)) {
        require_once DRUPAL_ROOT . '/includes/language.inc';
        $language_fallback_candidates = array_merge($language_fallback_candidates, language_fallback_get_candidates());
      }
      else {
        $language_fallback_candidates[] = LANGUAGE_NONE;
      }
      $this->query
        ->add_where_expression(0, "{$column} IN({$placeholder}) OR {$column} IS NULL", array(
        $placeholder => $language_fallback_candidates,
      ));
    }
  }

  // The revision id inhibits grouping.
  // So, stop here if we're using grouping, or if aren't adding all columns to
  // the query.
  if ($use_groupby || empty($this->definition['add fields to query'])) {
    return;
  }
  $this
    ->add_additional_fields(array(
    'revision_id',
  ));
}