function hook_field_storage_query

Execute an EntityFieldQuery.

This hook is called to find the entities having certain entity and field conditions and sort them in the given field order. If the field storage engine also handles property sorts and orders, it should unset those properties in the called object to signal that those have been handled.

Parameters

EntityFieldQuery $query: An EntityFieldQuery.

Return value

See EntityFieldQuery::execute() for the return values.

Related topics

3 functions implement hook_field_storage_query()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

field_sql_storage_field_storage_query in drupal/modules/field/modules/field_sql_storage/field_sql_storage.module
Implements hook_field_storage_query().
field_test_dummy_field_storage_query in drupal/modules/field/tests/field_test.module
Pseudo-implements hook_field_storage_query().
field_test_field_storage_query in drupal/modules/field/tests/field_test.storage.inc
Implements hook_field_storage_query().

File

drupal/modules/field/field.api.php, line 2006
Hooks provided by the Field module.

Code

function hook_field_storage_query($query) {
  $groups = array();
  if ($query->age == FIELD_LOAD_CURRENT) {
    $tablename_function = '_field_sql_storage_tablename';
    $id_key = 'entity_id';
  }
  else {
    $tablename_function = '_field_sql_storage_revision_tablename';
    $id_key = 'revision_id';
  }
  $table_aliases = array();

  // Add tables for the fields used.
  foreach ($query->fields as $key => $field) {
    $tablename = $tablename_function($field);

    // Every field needs a new table.
    $table_alias = $tablename . $key;
    $table_aliases[$key] = $table_alias;
    if ($key) {
      $select_query
        ->join($tablename, $table_alias, "{$table_alias}.entity_type = {$field_base_table}.entity_type AND {$table_alias}.{$id_key} = {$field_base_table}.{$id_key}");
    }
    else {
      $select_query = db_select($tablename, $table_alias);
      $select_query
        ->addTag('entity_field_access');
      $select_query
        ->addMetaData('base_table', $tablename);
      $select_query
        ->fields($table_alias, array(
        'entity_type',
        'entity_id',
        'revision_id',
        'bundle',
      ));
      $field_base_table = $table_alias;
    }
    if ($field['cardinality'] != 1) {
      $select_query
        ->distinct();
    }
  }

  // Add field conditions.
  foreach ($query->fieldConditions as $key => $condition) {
    $table_alias = $table_aliases[$key];
    $field = $condition['field'];

    // Add the specified condition.
    $sql_field = "{$table_alias}." . _field_sql_storage_columnname($field['field_name'], $condition['column']);
    $query
      ->addCondition($select_query, $sql_field, $condition);

    // Add delta / language group conditions.
    foreach (array(
      'delta',
      'language',
    ) as $column) {
      if (isset($condition[$column . '_group'])) {
        $group_name = $condition[$column . '_group'];
        if (!isset($groups[$column][$group_name])) {
          $groups[$column][$group_name] = $table_alias;
        }
        else {
          $select_query
            ->where("{$table_alias}.{$column} = " . $groups[$column][$group_name] . ".{$column}");
        }
      }
    }
  }
  if (isset($query->deleted)) {
    $select_query
      ->condition("{$field_base_table}.deleted", (int) $query->deleted);
  }

  // Is there a need to sort the query by property?
  $has_property_order = FALSE;
  foreach ($query->order as $order) {
    if ($order['type'] == 'property') {
      $has_property_order = TRUE;
    }
  }
  if ($query->propertyConditions || $has_property_order) {
    if (empty($query->entityConditions['entity_type']['value'])) {
      throw new EntityFieldQueryException('Property conditions and orders must have an entity type defined.');
    }
    $entity_type = $query->entityConditions['entity_type']['value'];
    $entity_base_table = _field_sql_storage_query_join_entity($select_query, $entity_type, $field_base_table);
    $query->entityConditions['entity_type']['operator'] = '=';
    foreach ($query->propertyConditions as $property_condition) {
      $query
        ->addCondition($select_query, "{$entity_base_table}." . $property_condition['column'], $property_condition);
    }
  }
  foreach ($query->entityConditions as $key => $condition) {
    $query
      ->addCondition($select_query, "{$field_base_table}.{$key}", $condition);
  }

  // Order the query.
  foreach ($query->order as $order) {
    if ($order['type'] == 'entity') {
      $key = $order['specifier'];
      $select_query
        ->orderBy("{$field_base_table}.{$key}", $order['direction']);
    }
    elseif ($order['type'] == 'field') {
      $specifier = $order['specifier'];
      $field = $specifier['field'];
      $table_alias = $table_aliases[$specifier['index']];
      $sql_field = "{$table_alias}." . _field_sql_storage_columnname($field['field_name'], $specifier['column']);
      $select_query
        ->orderBy($sql_field, $order['direction']);
    }
    elseif ($order['type'] == 'property') {
      $select_query
        ->orderBy("{$entity_base_table}." . $order['specifier'], $order['direction']);
    }
  }
  return $query
    ->finishQuery($select_query, $id_key);
}