You are here

function relation_handler_relationship::query in Relation 7

Called to implement a relationship in a query.

Overrides views_handler_relationship::query

File

views/relation_handler_relationship.inc, line 57
Views relationship support.

Class

relation_handler_relationship
@file Views relationship support.

Code

function query() {
  $field = field_info_field('endpoints');
  $relation_data_table_name = _field_sql_storage_tablename($field);
  $entity_id_field_name = _field_sql_storage_columnname('endpoints', 'entity_id');
  $entity_type_field_name = _field_sql_storage_columnname('endpoints', 'entity_type');
  $r_index_field_name = _field_sql_storage_columnname('endpoints', 'r_index');
  $join_type = empty($this->options['required']) ? 'LEFT' : 'INNER';
  $endpoints_twice = isset($this->definition['entity_type_left']) && isset($this->definition['entity_type_right']);
  $this
    ->ensure_my_table();

  // Join the left table with the entity type to the endpoints field data table.
  $join = new views_join();
  $join->definition = array(
    'left_table' => $this->table_alias,
    'left_field' => $this->real_field,
    'table' => $relation_data_table_name,
    'type' => $join_type,
    'extra' => array(
      array(
        'field' => 'bundle',
        'value' => $this->definition['relation_type'],
      ),
    ),
  );
  if (isset($this->definition['entity_type_left'])) {

    // The left table is an entity, not a relation.
    $join->definition['field'] = $entity_id_field_name;
    $this
      ->ensure_no_duplicate_entities($join->definition['extra'], $this->options['entity_deduplication_left'], $this->definition['relation_type'], $this->definition['entity_type_left'], $this->table_alias, $this->real_field);
    $join->definition['extra'][] = array(
      'field' => $entity_type_field_name,
      'value' => $this->definition['entity_type_left'],
    );
  }
  else {

    // The left table is relation.
    $join->definition['field'] = 'entity_id';
  }
  if ($this->definition['directional'] && $this->options['r_index'] > -1) {
    $join->definition['extra'][] = array(
      'field' => $r_index_field_name,
      'value' => $this->options['r_index'],
    );
  }
  $join
    ->construct();
  $join->adjusted = TRUE;
  $l = $this->query
    ->add_table($relation_data_table_name, $this->relationship, $join);
  if ($endpoints_twice) {

    // Execute a self-join.
    $join = new views_join();
    $join->definition = array(
      'left_table' => $l,
      'left_field' => 'entity_id',
      'table' => $relation_data_table_name,
      'field' => 'entity_id',
      'type' => $join_type,
      'extra' => array(
        array(
          'field' => $entity_type_field_name,
          'value' => $this->definition['entity_type_right'],
        ),
      ),
    );
    if ($this->definition['entity_type_left'] == $this->definition['entity_type_right']) {
      $join->definition['extra'][] = array(
        // This definition is a bit funny but there's no other way to tell
        // Views to use an expression in join extra as it is.
        'field' => $r_index_field_name . ' !=  ' . $l . '.' . $r_index_field_name . ' AND 1',
        'value' => 1,
      );
    }
    $join
      ->construct();
    $join->adjusted = TRUE;
    $r = $this->query
      ->add_table($relation_data_table_name, $this->relationship, $join);
  }
  else {
    $r = $l;
  }
  $join = new views_join();
  $join->definition = array(
    'left_table' => $r,
    'table' => $this->definition['base'],
    'field' => $this->definition['base field'],
    'type' => $join_type,
  );
  if (isset($this->definition['entity_type_right'])) {

    // We are finishing on an entity table.
    $join->definition['left_field'] = $entity_id_field_name;
    $this
      ->ensure_no_duplicate_entities($join->definition['extra'], $this->options['entity_deduplication_right'], $this->definition['relation_type'], $this->definition['entity_type_right'], $r, $entity_id_field_name);
    $join->definition['extra'][] = array(
      'table' => $r,
      'field' => $entity_type_field_name,
      'value' => $this->definition['entity_type_right'],
    );
  }
  else {

    // We are finishing on relation.
    $join->definition['left_field'] = 'entity_id';
  }
  $join
    ->construct();
  $join->adjusted = TRUE;

  // use a short alias for this:
  $alias = $this->definition['base'] . '_' . $this->table;
  $this->alias = $this->query
    ->add_relationship($alias, $join, $this->definition['base'], $this->relationship);
}