function views_join::join

Build the SQL for the join this object represents.

File

includes/handlers.inc, line 1621

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;
}