Index: includes/view.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/view.inc,v retrieving revision 1.123 diff -u -r1.123 view.inc --- includes/view.inc 14 Aug 2008 22:17:11 -0000 1.123 +++ includes/view.inc 16 Aug 2008 14:00:54 -0000 @@ -1,5 +1,5 @@ db_objects() as $object) { $this->$object = array(); } - - $this->query = new stdClass(); } /** @@ -354,7 +352,7 @@ // Load the requested items from the display onto the object. $this->$key = $this->display_handler->get_handlers($key); - // This reference deals with difficult PHP indirection. + // This reference deals with difficult PHP indirection.6/10/2008 $handlers = &$this->$key; // Run through and test for accessibility. @@ -492,7 +490,9 @@ $this->base_database = $views_data['table']['base']['database']; } views_include('query'); - $this->query = new views_query($this->base_table, $this->base_field); + $query_class = empty($views_data['table']['base']['query class']) ? + 'views_query' : $views_data['table']['base']['query class']; + $this->query = new $query_class($this->base_table, $this->base_field); // Call a module hook and see if it wants to present us with a // pre-built query or instruct us not to build the query for @@ -567,18 +567,21 @@ // Allow style handler to affect the query: $this->style_plugin->query(); - if (variable_get('views_sql_signature', FALSE)) { + if (variable_get('views_sql_signature', FALSE) && $query_class == 'views_query') { $this->query->add_field(NULL, "'" . $this->name . ':' . $this->current_display . "'", 'view_name'); } // Let modules modify the query just prior to finalizing it. - foreach (module_implements('views_query_alter') as $module) { - $function = $module . '_views_query_alter'; - $function($this, $this->query); + // Only do this, if the default query class is used. + if ($query_class == 'views_query') { + foreach (module_implements('views_query_alter') as $module) { + $function = $module . '_views_query_alter'; + $function($this, $this->query); + } } - $this->build_info['query'] = $this->query->query(); - $this->build_info['query_args'] = $this->query->get_where_args(); + $this->query->query(); + $this->query->get_where_args(); $this->built = TRUE; $this->build_time = microtime() - $start; return TRUE; @@ -619,81 +622,7 @@ return TRUE; } - $query = db_rewrite_sql($this->build_info['query'], $this->base_table, $this->base_field, array('view' => &$this)); - - $args = $this->build_info['query_args']; - - vpr($query); - - $items = array(); - if ($query) { - $replacements = module_invoke_all('views_query_substitutions', $this); - $query = str_replace(array_keys($replacements), $replacements, $query); - - if (is_array($args)) { - foreach ($args as $id => $arg) { - $args[$id] = str_replace(array_keys($replacements), $replacements, $arg); - } - } - - // Allow for a view to query an external database. - if (isset($this->base_database)) { - db_set_active($this->base_database); - $external = TRUE; - } - - // make count from subselect now - $count_query = "SELECT COUNT(*) FROM ($query) AS count_alias"; - - $start = microtime(); - if (!empty($this->pager['items_per_page'])) { - // We no longer use pager_query() here because pager_query() does not - // support an offset. This is fine as we don't actually need pager - // query; we've already been doing most of what it does, and we - // just need to do a little more playing with globals. - if (!empty($this->pager['use_pager']) || !empty($this->get_total_rows)) { - $this->total_rows = db_result(db_query($count_query, $args)); - } - - if (!empty($this->pager['use_pager'])) { - // dump information about what we already know into the globals - global $pager_page_array, $pager_total, $pager_total_items; - // total rows in query - $pager_total_items[$this->pager['element']] = $this->total_rows; - // total pages - $pager_total[$this->pager['element']] = ceil($pager_total_items[$this->pager['element']] / $this->pager['items_per_page']); - - // What page was requested: - $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array(); - - // If the requested page was within range. $this->pager['current_page'] - // defaults to 0 so we don't need to set it in an out-of-range condition. - if (!empty($pager_page_array[$this->pager['element']])) { - $page = intval($pager_page_array[$this->pager['element']]); - if ($page > 0 && $page < $pager_total[$this->pager['element']]) { - $this->pager['current_page'] = $page; - } - } - $pager_page_array[$this->pager['element']] = $this->pager['current_page']; - } - - $offset = $this->pager['current_page'] * $this->pager['items_per_page'] + $this->pager['offset']; - $result = db_query_range($query, $args, $offset, $this->pager['items_per_page']); - - } - else { - $result = db_query($query, $args); - } - - $this->result = array(); - while ($item = db_fetch_object($result)) { - $this->result[] = $item; - } - if (!empty($external)) { - db_set_active(); - } - } - $this->execute_time = microtime() - $start; + $this->query->execute($this); $this->executed = TRUE; } @@ -1096,7 +1025,7 @@ $cache[$arg] = NULL; } else { - $view = new view(); + $view =& new view(); $view->load_row($data); $view->type = t('Normal'); // Load all of our subtables. @@ -1779,51 +1708,44 @@ * about them. */ function views_object_types() { - static $retval = NULL; - - // statically cache this so t() doesn't run a bajillion times. - if (!isset($retval)) { - $retval = array( - 'field' => array( - 'title' => t('Fields'), // title - 'ltitle' => t('fields'), // lowercase title for mid-sentence - 'stitle' => t('Field'), // singular title - 'lstitle' => t('field'), // singular lowercase title for mid sentence - 'plural' => 'fields', - ), - 'argument' => array( - 'title' => t('Arguments'), - 'ltitle' => t('arguments'), - 'stitle' => t('Argument'), - 'lstitle' => t('Argument'), - 'plural' => 'arguments', - ), - 'sort' => array( - 'title' => t('Sort criteria'), - 'ltitle' => t('sort criteria'), - 'stitle' => t('Sort criterion'), - 'lstitle' => t('sort criterion'), - 'plural' => 'sorts', - ), - 'filter' => array( - 'title' => t('Filters'), - 'ltitle' => t('filters'), - 'stitle' => t('Filter'), - 'lstitle' => t('filter'), - 'plural' => 'filters', - 'options' => 'views_ui_config_filters_form', - ), - 'relationship' => array( - 'title' => t('Relationships'), - 'ltitle' => t('relationships'), - 'stitle' => t('Relationship'), - 'lstitle' => t('Relationship'), - 'plural' => 'relationships', - ), - ); - } - - return $retval; + return array( + 'field' => array( + 'title' => t('Fields'), // title + 'ltitle' => t('fields'), // lowercase title for mid-sentence + 'stitle' => t('Field'), // singular title + 'lstitle' => t('field'), // singular lowercase title for mid sentence + 'plural' => 'fields', + ), + 'argument' => array( + 'title' => t('Arguments'), + 'ltitle' => t('arguments'), + 'stitle' => t('Argument'), + 'lstitle' => t('Argument'), + 'plural' => 'arguments', + ), + 'sort' => array( + 'title' => t('Sort criteria'), + 'ltitle' => t('sort criteria'), + 'stitle' => t('Sort criterion'), + 'lstitle' => t('sort criterion'), + 'plural' => 'sorts', + ), + 'filter' => array( + 'title' => t('Filters'), + 'ltitle' => t('filters'), + 'stitle' => t('Filter'), + 'lstitle' => t('filter'), + 'plural' => 'filters', + 'options' => 'views_ui_config_filters_form', + ), + 'relationship' => array( + 'title' => t('Relationships'), + 'ltitle' => t('relationships'), + 'stitle' => t('Relationship'), + 'lstitle' => t('Relationship'), + 'plural' => 'relationships', + ), + ); } /** Index: includes/query.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/query.inc,v retrieving revision 1.25 diff -u -r1.25 query.inc --- includes/query.inc 14 Aug 2008 22:17:10 -0000 1.25 +++ includes/query.inc 16 Aug 2008 14:00:52 -0000 @@ -66,6 +66,16 @@ var $distinct = FALSE; /** + * The query to use to get the results. + */ + var $_query; + + /** + * The WHERE and HAVING clauses of this query. + */ + var $_args; + + /** * Constructor; Create the basic query object and fill with default values. */ function views_query($base_table = 'node', $base_field = 'nid') { @@ -901,7 +911,7 @@ $replace = array('>' => '>', '<' => '<'); $query = strtr($query, $replace); - return $query; + $this->_query = $query; } /** @@ -915,7 +925,89 @@ foreach ($this->having as $group => $having) { $args = array_merge($args, $having['args']); } - return $args; + $this->_args = $args; } -} + + /** + * Executes the query and fills the associated view object with according + * values. + * + * Values to set: $view->result, $view->total_rows, $view->execute_time, + * $view->pager['current_page']. + */ + function execute(&$view) { + $query = db_rewrite_sql($this->_query, $view->base_table, $view->base_field, array('view' => &$view)); + + $args = $this->_args; + + vpr($query); + $items = array(); + $results = NULL; + if ($query) { + $replacements = module_invoke_all('views_query_substitutions', $view); + $query = str_replace(array_keys($replacements), $replacements, $query); + + if (is_array($args)) { + foreach ($args as $id => $arg) { + $args[$id] = str_replace(array_keys($replacements), $replacements, $arg); + } + } + + // Allow for a view to query an external database. + if (isset($view->base_database)) { + db_set_active($view->base_database); + $external = TRUE; + } + + // make count from subselect now + $count_query = "SELECT COUNT(*) FROM ($query) AS count_alias"; + + $start = microtime(); + if (!empty($view->pager['items_per_page'])) { + // We no longer use pager_query() here because pager_query() does not + // support an offset. This is fine as we don't actually need pager + // query; we've already been doing most of what it does, and we + // just need to do a little more playing with globals. + $view->total_rows = db_result(db_query($count_query, $args)); + + if (!empty($view->pager['use_pager'])) { + // dump information about what we already know into the globals + global $pager_page_array, $pager_total, $pager_total_items; + // total rows in query + $pager_total_items[$view->pager['element']] = $view->total_rows; + // total pages + $pager_total[$view->pager['element']] = ceil($pager_total_items[$view->pager['element']] / $view->pager['items_per_page']); + + // What page was requested: + $pager_page_array = isset($_GET['page']) ? explode(',', $_GET['page']) : array(); + + // If the requested page was within range. $view->pager['current_page'] + // defaults to 0 so we don't need to set it in an out-of-range condition. + if (!empty($pager_page_array[$view->pager['element']])) { + $page = intval($pager_page_array[$view->pager['element']]); + if ($page > 0 && $page < $pager_total[$view->pager['element']]) { + $view->pager['current_page'] = $page; + } + } + $pager_page_array[$view->pager['element']] = $view->pager['current_page']; + } + + $offset = $view->pager['current_page'] * $view->pager['items_per_page'] + $view->pager['offset']; + $result = db_query_range($query, $args, $offset, $view->pager['items_per_page']); + } + else { + $result = db_query($query, $args); + } + + $view->result = array(); + while ($item = db_fetch_object($result)) { + $view->result[] = $item; + } + if (!empty($external)) { + db_set_active(); + } + $view->execute_time = microtime() - $start; + } + } +}