You are here

function views_join::join in Views (for Drupal 7) 6.3

Same name and namespace in other branches
  1. 6.2 includes/handlers.inc \views_join::join()

Build the SQL for the join this object represents.

File

includes/handlers.inc, line 1621
handlers.inc Defines the various handler objects to help build and display views.

Class

views_join
A function class to represent a join and create the SQL necessary to implement the join.

Code

function join($table, &$query) {
  if (empty($this->definition['table formula'])) {
    $right_table = "{" . $this->table . "}";
  }
  else {
    $right_table = $this->definition['table formula'];
  }
  if ($this->left_table) {
    $left = $query
      ->get_table_info($this->left_table);
    $left_field = "{$left['alias']}.{$this->left_field}";
  }
  else {

    // This can be used if left_field is a formula or something. It should be used only *very* rarely.
    $left_field = $this->left_field;
  }
  $output = " {$this->type} JOIN {$right_table} {$table['alias']} ON {$left_field} = {$table['alias']}.{$this->field}";

  // Load query tokens replacements.
  $view = views_get_current_view();
  $replacements = array();
  if (!empty($view)) {
    $replacements = $view
      ->substitutions();
  }
  else {
    vpr('The current view is not set, maybe some code missed to execute $view->pre_execute()');
  }

  // Tack on the extra.
  if (isset($this->extra)) {
    if (is_array($this->extra)) {
      $extras = array();
      foreach ($this->extra as $info) {
        $extra = '';

        // Figure out the table name. Remember, only use aliases provided
        // if at all possible.
        $join_table = '';
        if (!array_key_exists('table', $info)) {
          $join_table = $table['alias'] . '.';
        }
        elseif (isset($info['table'])) {
          $join_table = $info['table'] . '.';
        }

        // Apply query token replacements.
        $info['value'] = str_replace(array_keys($replacements), $replacements, $info['value']);

        // And now deal with the value and the operator.  Set $q to
        // a single-quote for non-numeric values and the
        // empty-string for numeric values, then wrap all values in $q.
        if (empty($info['raw'])) {
          $raw_value = $this
            ->db_safe($info['value'], $info);
          $q = empty($info['numeric']) ? "'" : '';
        }
        else {
          $raw_value = $info['value'];
          $q = '';
        }
        if (is_array($raw_value)) {
          $operator = !empty($info['operator']) ? $info['operator'] : 'IN';

          // Transform from IN() notation to = notation if just one value.
          if (count($raw_value) == 1) {
            $value = $q . array_shift($raw_value) . $q;
            $operator = $operator == 'NOT IN' ? '!=' : '=';
          }
          else {
            $value = "({$q}" . implode("{$q}, {$q}", $raw_value) . "{$q})";
          }
        }
        else {
          $operator = !empty($info['operator']) ? $info['operator'] : '=';
          $value = "{$q}{$raw_value}{$q}";
        }
        $extras[] = "{$join_table}{$info['field']} {$operator} {$value}";
      }
      if ($extras) {
        if (count($extras) == 1) {
          $output .= ' AND ' . array_shift($extras);
        }
        else {
          $output .= ' AND (' . implode(' ' . $this->extra_type . ' ', $extras) . ')';
        }
      }
    }
    else {
      if ($this->extra && is_string($this->extra)) {
        $output .= " AND ({$this->extra})";
      }
    }
  }
  return $output;
}