View source
<?php
function _views_build_query(&$view, $args = array(), $filters = array()) {
$query = new _views_query('node', 'nid', !empty($view->use_alias_prefix) ? $view->use_alias_prefix : '');
_views_view_build_filters($query, $view, $filters);
$view->args = $args;
foreach ($view->argument as $i => $argument) {
if ($args[$i] != NULL && $args[$i] != '' && $args[$i] != '$arg') {
_views_view_build_arg($query, $args[$i], $argument);
}
else {
switch ($argument['argdefault']) {
case 1:
$info['fail'] = TRUE;
return $info;
case 3:
case 4:
$self_sort = "ASC";
case 5:
if (!$self_sort) {
$self_sort = "DESC";
}
case 6:
$level = $i;
_views_build_summary($query, $argument['type'], $argument['options'], $self_sort);
$summary = true;
if (!$self_sort) {
$sort = true;
}
break 2;
case 7:
$info['query'] = NULL;
return $info;
}
}
}
if (!$summary || $sort) {
_views_view_build_sorts($query, $view);
$plugins = _views_get_style_plugins();
if ($view->page && $plugins[$view->page_type]['needs_fields'] || $view->block && $plugins[$view->block_type]['needs_fields']) {
_views_view_build_fields($query, $view);
}
}
foreach (module_implements('views_query_alter') as $module) {
$function = $module . '_views_query_alter';
$results = $function($query, $view, $summary, $level);
}
$info['query'] = $query
->query();
$info['countquery'] = $query
->query(true);
$info['summary'] = $summary;
$info['level'] = $level;
$info['args'] = $query->where_args;
return $info;
}
function _views_view_build_filters(&$query, &$view, $exposed_filter_values) {
$filters = _views_get_filters();
$view->used_filters = array();
foreach ($view->filter as $i => $filter) {
$filterinfo = $filters[$filter['field']];
if (!$filterinfo['field']) {
$fieldbits = explode('.', $filter['field']);
$filterinfo['field'] = $fieldbits[1];
}
foreach ($view->exposed_filter as $count => $expose) {
if ($filter['id'] == $expose['id']) {
$id = $expose['id'];
if (isset($view->exposed_filter_offset)) {
$count += $view->exposed_filter_offset;
}
if (!$expose['operator'] && $exposed_filter_values[$count]['op']) {
$filter['operator'] = check_plain($exposed_filter_values[$count]['op']);
$view->used_filters["op{$count}"] = $exposed_filter_values[$count]['op'];
}
if ($expose['optional']) {
if ((!isset($exposed_filter_values[$count]['filter']) || $exposed_filter_values[$count]['filter'] == '') && !$expose['is_default']) {
continue 2;
}
if ($exposed_filter_values[$count]['filter'] == '**ALL**' || is_array($exposed_filter_values[$count]['filter']) && in_array('**ALL**', $exposed_filter_values[$count]['filter'])) {
$view->used_filters["filter{$count}"] = $exposed_filter_values[$count]['filter'];
continue 2;
}
}
if (isset($exposed_filter_values[$count]['filter']) && $exposed_filter_values[$count]['filter'] != '') {
$value = $exposed_filter_values[$count]['filter'];
if ($filterinfo['value-type'] == 'array' && !is_array($value)) {
$value = array(
$value,
);
}
$filter['value'] = $value;
$view->used_filters["filter{$count}"] = $exposed_filter_values[$count]['filter'];
}
break;
}
}
$replace = array(
'>' => '>',
'<' => '<',
);
$filter['operator'] = strtr($filter['operator'], $replace);
if (!function_exists($filterinfo['handler'])) {
$filterinfo['handler'] = 'views_handler_filter_default';
}
$filterinfo['handler']('handler', $filter, $filterinfo, $query);
}
}
function views_handler_filter_default($op, $filter, $filterinfo, &$query) {
$table = $filterinfo['table'];
$field = $filterinfo['field'];
if (is_array($filter['value']) && count($filter['value'])) {
if ($filter['operator'] == 'OR' || $filter['operator'] == 'NOR') {
$query
->ensure_table($table);
$where_args = array_merge(array(
$query->use_alias_prefix . $table,
$field,
), $filter['value']);
$placeholder = array_fill(0, count($filter['value']), '%s');
if ($filter['operator'] == 'OR') {
$query
->add_where("%s.%s IN ('" . implode("','", $placeholder) . "')", $where_args);
}
else {
$where_args[] = $where_args[0];
$where_args[] = $where_args[1];
$query
->add_where("(%s.%s NOT IN ('" . implode("','", $placeholder) . "') OR %s.%s IS NULL)", $where_args);
}
}
else {
$howmany = count($filter['value']);
$high_table = $query
->add_table($table, true, $howmany);
if (!$high_table) {
return;
}
$table_num = $high_table - $howmany;
foreach ($filter['value'] as $item) {
$table_num++;
$tn = $query
->get_table_name($table, $table_num);
$query
->add_where("%s.%s = '%s'", $tn, $field, $item);
}
}
}
else {
$query
->ensure_table("{$table}");
$query
->add_where("%s.%s %s '%s'", $query->use_alias_prefix . $table, $field, $filter['operator'], $filter['value']);
}
}
function _views_view_build_arg(&$query, $arg, $argdata) {
$arginfo = _views_get_arguments();
if (!function_exists($arginfo[$argdata['type']]['handler'])) {
return false;
}
if ($arg != $argdata['wildcard']) {
$arginfo[$argdata['type']]['handler']('filter', $query, $argdata, $arg);
}
}
function _views_view_build_sorts(&$query, $view) {
$sorts = _views_get_sorts();
foreach ($view->sort as $i => $sort) {
$sortinfo = $sorts[$sort['field']];
$field = $sortinfo['field'];
if (!$field) {
$fieldbits = explode('.', $sort['field']);
$field = $fieldbits[1];
}
$table = $sortinfo['table'];
if (isset($sortinfo['handler']) && function_exists($sortinfo['handler'])) {
$sortinfo['field'] = $field;
$sortinfo['handler']('sort', $query, $sortinfo, $sort);
}
else {
$query
->add_orderby($table, $field, $sort['sortorder']);
}
}
}
function _views_view_build_fields(&$query, &$view) {
$fields = _views_get_fields();
foreach ($view->field as $field) {
$fieldname = $field['fullname'];
$fieldinfo = $fields[$fieldname];
if (isset($fieldinfo['query_handler']) && function_exists($fieldinfo['query_handler'])) {
$fieldinfo['query_handler']($field, $fieldinfo, $query);
}
if (!$fieldinfo['notafield']) {
if ($fieldinfo['field']) {
$query
->add_field($fieldinfo['field'], $field['tablename'], $field['queryname']);
}
else {
$query
->add_field($field['field'], $field['tablename'], $field['queryname']);
}
}
if (is_array($fieldinfo['addlfields'])) {
foreach ($fieldinfo['addlfields'] as $name) {
$query
->add_field($name, $field['tablename'], "{$field['tablename']}_{$name}");
}
}
}
$plugins = _views_get_style_plugins();
if ($view->page && $plugins[$view->page_type]['needs_table_header'] || $view->block && $plugins[$view->block_type]['needs_table_header']) {
$view->table_header = _views_construct_header($view, $fields);
$query
->set_header($view->table_header);
}
}
function _views_build_summary(&$query, $argtype, $option, $self_sort) {
$arginfo = _views_get_arguments();
if (!function_exists($arginfo[$argtype]['handler'])) {
return false;
}
$primary_field = $query->fields[0];
$query
->clear_fields();
$fieldinfo = $arginfo[$argtype]['handler']('summary', $query, $argtype, $option);
if ($fieldinfo['fieldname']) {
$query
->add_field($fieldinfo[field], '', $fieldinfo[fieldname]);
}
$query
->add_field("count({$primary_field})", '', 'num_nodes');
$query
->add_groupby($fieldinfo['field']);
$query
->set_count_field("DISTINCT({$fieldinfo['field']})");
if ($self_sort) {
$arginfo[$argtype]['handler']('sort', $query, $self_sort);
}
$query->no_distinct = TRUE;
}
class _views_query {
function _views_query($primary_table = 'node', $primary_field = 'nid', $alias_prefix = '') {
$this->primary_table = $primary_table;
$this->primary_field = $primary_field;
$this->joins = array();
$this->where = array();
$this->orderby = array();
$this->groupby = array();
$this->tables = array();
$this->where_args = array();
$this->use_alias_prefix = $alias_prefix;
$this->tablequeue = array();
if ($primary_field) {
$this->fields = array(
$alias_prefix . "{$primary_table}.{$primary_field}",
);
}
$this->count_field = $alias_prefix . "{$primary_table}.{$primary_field}";
$this->header = array();
}
function add_field($field, $table = '$$', $alias = '') {
if ($table == '$$') {
$table = $this->primary_table;
}
if ($table == $this->primary_table && $field == $this->primary_field) {
return;
}
if ($table) {
$this
->ensure_table($table);
$table = $this->use_alias_prefix . $table . ".";
}
if ($alias) {
$a = " AS {$this->use_alias_prefix}{$alias}";
}
if (!in_array("{$table}{$field}{$a}", $this->fields)) {
$this->fields[] = "{$table}{$field}{$a}";
}
}
function set_distinct($value = TRUE) {
if (!($this->no_distinct && $value)) {
$this->distinct = $value;
}
}
function clear_fields() {
$this->fields = array();
}
function set_count_field($field) {
$this->count_field = $field;
}
function add_where($clause) {
$args = func_get_args();
array_shift($args);
if (count($args) == 1 && is_array(reset($args))) {
$args = current($args);
}
if (is_array($args)) {
$this->where[] = $clause;
$this->where_args = array_merge($this->where_args, $args);
}
}
function add_orderby($table, $field, $order, $alias = '') {
if (!$alias && $table) {
$alias = $this->use_alias_prefix . $table;
}
elseif ($alias) {
$alias = $this->use_alias_prefix . $alias;
}
if ($table) {
$this
->ensure_table($table);
}
if (!is_array($field)) {
$field = array(
$field,
);
}
foreach ($field as $f) {
if ($table) {
$as = $alias . '_' . $f;
}
else {
$as = $alias;
}
$this
->add_field($f, $table, $as);
$this->orderby[] = "{$as} {$order}";
if ($this->groupby) {
$this
->add_groupby($as);
}
}
}
function add_groupby($clause) {
$this->groupby[] = $clause;
}
function ensure_table($table) {
if ($table == $this->primary_table || $this->tables[$table]) {
return;
}
if ($this
->ensure_path($table)) {
$this
->queue_table($table);
}
}
function add_table($table, $ensure_path = false, $howmany = 1, $joininfo = NULL) {
if ($table == $this->primary_table) {
return;
}
if ($ensure_path && !$this
->ensure_path($table)) {
return false;
}
$this->tables[$table] += $howmany;
for ($i = $this->tables[$table] - $howmany + 1; $i <= $this->tables[$table]; $i++) {
if ($joininfo) {
$this->joins[$table][$i] = $joininfo;
}
$this->tablequeue[] = array(
'table' => $table,
'num' => $i,
'alias_prefix' => $this->use_alias_prefix,
);
}
return $this->tables[$table];
}
function queue_table($table) {
if (!isset($this->tables[$table])) {
$this->tables[$table] = 1;
}
else {
$this->tables[$table]++;
}
$this->tablequeue[] = array(
'table' => $table,
'num' => $this->tables[$table],
'alias_prefix' => $this->use_alias_prefix,
);
}
function set_header($header) {
$this->header = $header;
}
function ensure_path($table, $traced = array(), $add = array()) {
if ($table == $this->primary_table) {
return true;
}
$table_data = _views_get_tables();
$left_table = $table_data[$table]['join']['left']['table'];
if ($left_table == $this->primary_table) {
foreach (array_reverse($add) as $table) {
$this
->queue_table($table);
}
return true;
}
if (isset($traced[$left_table])) {
return false;
}
if (!isset($this->tables[$left_table])) {
$add[] = $left_table;
}
$traced[$left_table] = 1;
return $this
->ensure_path($left_table, $traced, $add);
}
function get_table_name($table, $table_num, $alias_prefix = null) {
if (is_null($alias_prefix)) {
$alias_prefix = $this->use_alias_prefix;
}
return $table_num < 2 ? $alias_prefix . $table : $alias_prefix . $table . $table_num;
}
function query($getcount = false) {
$table_data = _views_get_tables();
if (!$this->no_distinct && $this->distinct && count($this->fields)) {
$field = $this->fields[0];
$this->fields[0] = "DISTINCT({$field})";
$this->count_field = "DISTINCT({$this->count_field})";
$this->no_distinct = TRUE;
}
foreach ($this->tablequeue as $tinfo) {
$table = $tinfo['table'];
$table_real = isset($table_data[$table]['name']) ? $table_data[$table]['name'] : $table;
$table_num = $tinfo['num'];
$table_alias = $this
->get_table_name($table, $table_num, $tinfo['alias_prefix']);
$joininfo = !$this->joins[$table][$table_num] ? $table_data[$table]['join'] : $this->joins[$table][$table_num];
$left_table_alias = isset($joininfo['left']['alias']) ? $joininfo['left']['alias'] : $tinfo['alias_prefix'];
$left_table_alias .= $joininfo['left']['table'];
$join_type = $joininfo['type'] == 'inner' ? 'INNER' : 'LEFT';
$joins .= " {$join_type} JOIN {" . $table_real . "} {$table_alias} ON " . $left_table_alias . "." . $joininfo['left']['field'] . " = {$table_alias}." . $joininfo['right']['field'];
if (isset($joininfo['extra'])) {
foreach ($joininfo['extra'] as $field => $value) {
$joins .= " AND {$table_alias}.{$field}";
if (is_array($value) && count($value)) {
$joins .= " IN ('" . implode("','", $value) . "')";
}
else {
if ($value !== NULL) {
$joins .= " = '{$value}'";
}
}
}
}
}
if (!$getcount) {
$fields = implode(', ', $this->fields);
if ($this->groupby) {
$groupby = "GROUP BY " . implode(', ', $this->groupby);
}
if ($this->header) {
$result = tablesort_sql($this->header);
if ($result) {
$this->orderby[] = str_replace('ORDER BY ', '', $result);
}
}
if ($this->orderby) {
$orderby = "ORDER BY " . implode(', ', $this->orderby);
}
}
else {
$fields = "count({$this->count_field})";
}
if ($this->where) {
$where = "WHERE (" . implode(') AND (', $this->where) . ')';
}
$query = "SELECT {$fields} FROM {" . $this->primary_table . "} {$this->primary_table} {$joins} {$where} {$groupby} {$orderby}";
$replace = array(
'>' => '>',
'<' => '<',
);
$query = strtr($query, $replace);
return $query;
}
}