Index: apachesolr.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v retrieving revision 1.1.2.12.2.149 diff -u -p -r1.1.2.12.2.149 apachesolr.module --- apachesolr.module 29 Jun 2009 23:35:07 -0000 1.1.2.12.2.149 +++ apachesolr.module 30 Jun 2009 01:16:14 -0000 @@ -970,10 +970,15 @@ function apachesolr_modify_query(&$query $function_name = $module . '_apachesolr_modify_query'; $function_name($query, $params, $caller); } + // TODO: The query object should hold all the params. // Add array of fq parameters. if ($query && ($fq = $query->get_fq())) { $params['fq'] = $fq; } + // Add sort if present. + if ($query && ($sort = $query->get_solrsort())) { + $params['sort'] = $sort; + } } /** @@ -1458,8 +1463,13 @@ interface Drupal_Solr_Query_Interface { * Return the search path (including the search keywords). */ function get_path(); - + /** + * Set extra values that will be added when calling get_url_querystring(). + */ + function set_extra_querystrings($get, $exclude = array('q', 'page', 'filters', 'solrsort')) + + /** * Return any query string for use in the l function. * * @see l() @@ -1474,12 +1484,15 @@ interface Drupal_Solr_Query_Interface { /** * Set the solrsort. * - * @param string raw string to set the sort to + * @param $sortstring + * Raw string to set the sort to - optionally use aliased field names. */ function set_solrsort($sortstring); /** * Get the solrsort. + * + * Returns the non-urlencode, non-aliased sort field and direction */ function get_solrsort(); Index: apachesolr_search.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v retrieving revision 1.1.2.6.2.105 diff -u -p -r1.1.2.6.2.105 apachesolr_search.module --- apachesolr_search.module 29 Jun 2009 23:35:07 -0000 1.1.2.6.2.105 +++ apachesolr_search.module 30 Jun 2009 01:16:14 -0000 @@ -126,7 +126,7 @@ function apachesolr_search_search($op = $solrsort = isset($_GET['solrsort']) ? $_GET['solrsort'] : ''; $page = isset($_GET['page']) ? $_GET['page'] : 0; try { - $results = apachesolr_search_execute($keys, $filters, $solrsort, 'search/' . arg(1), $page); + $results = apachesolr_search_execute($keys, $filters, $solrsort, 'search/' . arg(1), $page, $_GET); return $results; } catch (Exception $e) { @@ -184,21 +184,15 @@ function apachesolr_search_view($type = * * @throws Exception */ -function apachesolr_search_execute($keys, $filters, $solrsort, $base_path = '', $page = 0, $caller = 'apachesolr_search') { - // Validate sort parameter - // TODO: move this to the query class. - if (strlen($solrsort) && preg_match('/^([a-z0-9_]+ (asc|desc)(,)?)+$/i', $solrsort)) { - $params['sort'] = $solrsort; - } - else { - $solrsort = ''; - $params = array(); - } +function apachesolr_search_execute($keys, $filters, $solrsort, $base_path = '', $page = 0, $extra_querystrings = array(), $caller = 'apachesolr_search') { + + $params = array(); // This is the object that knows about the query coming from the user. $query = apachesolr_drupal_query($keys, $filters, $solrsort, $base_path); if (empty($query)) { throw new Exception(t('Could not construct a Solr query in function apachesolr_search_search()')); } + $query->set_extra_querystrings($extra_querystrings); // This is the object that does the communication with the solr server. $solr = apachesolr_get_solr(); $params += apachesolr_search_basic_params($query); Index: Solr_Base_Query.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Solr_Base_Query.php,v retrieving revision 1.1.4.37 diff -u -p -r1.1.4.37 Solr_Base_Query.php --- Solr_Base_Query.php 29 Jun 2009 23:35:07 -0000 1.1.4.37 +++ Solr_Base_Query.php 30 Jun 2009 01:16:14 -0000 @@ -65,14 +65,14 @@ class Solr_Base_Query implements Drupal_ * used for filter queries, e.g. array('#name' => 'uid', '#value' => 0) * for anonymous content. */ - protected $fields; + protected $fields = array(); /** * The complete filter string for a query. Usually from $_GET['filters'] * Contains name:value pairs for filter queries. For example, * "type:book" for book nodes. */ - protected $filterstring; + protected $filterstring = ''; /** * A mapping of field names from the URL to real index field names. @@ -87,19 +87,23 @@ class Solr_Base_Query implements Drupal_ /** * The search keywords. */ - protected $keys; + protected $keys = ''; /** * The search base path. */ - protected $base_path; + protected $base_path = ''; /** * Apache_Solr_Service object */ protected $solr; - protected $available_sorts; + protected $available_sorts = array(); + + protected $solrsort = ''; + + protected $extra_querystrings = array(); /** * @param $solr @@ -123,11 +127,11 @@ class Solr_Base_Query implements Drupal_ $this->solr = $solr; $this->keys = trim($keys); $this->filterstring = trim($filterstring); - $this->solrsort = trim($sortstring); - $this->base_path = $base_path; - $this->id = ++self::$idCount; $this->parse_filters(); $this->available_sorts = $this->default_sorts(); + $this->set_solrsort($sortstring); + $this->base_path = $base_path; + $this->id = ++self::$idCount; } function __clone() { @@ -234,7 +238,17 @@ class Solr_Base_Query implements Drupal_ } public function set_solrsort($sortstring) { - $this->solrsort = trim($sortstring); + // Validate sort parameter + $fields = implode('|', array_keys($this->available_sorts)); + // Substitute any field aliases with real field names. + $sortstring = strtr(trim($sortstring), $this->field_map); + // Score is a special case - it's the default sort. + if ('score asc' == $sortstring) { + $sortstring = ''; + } + if (('' == $solrsort) || preg_match('/^(('. $fields .') (asc|desc),?)+$/', $solrsort)) { + $this->solrsort = $sortstring; + } } public function get_solrsort() { @@ -254,7 +268,7 @@ class Solr_Base_Query implements Drupal_ */ protected function default_sorts() { return array( - 'relevancy' => array('name' => t('Relevancy'), 'default' => 'asc'), + 'score' => array('name' => t('Relevancy'), 'default' => 'asc'), 'sort_title' => array('name' => t('Title'), 'default' => 'asc'), 'type' => array('name' => t('Type'), 'default' => 'asc'), 'sort_name' => array('name' => t('Author'), 'default' => 'asc'), @@ -262,18 +276,25 @@ class Solr_Base_Query implements Drupal_ ); } + public function set_extra_querystrings($get, $exclude = array('q', 'page', 'filters', 'solrsort')) { + $this->extra_querystrings = array_diff_key($get, array_flip($exclude)); + } + /** * Return filters and sort in a form suitable for a query param to url(). */ public function get_url_querystring() { - $querystring = ''; + $querystrings = $this->extra_querystrings; if ($fq = $this->rebuild_fq(TRUE)) { - $querystring = 'filters='. rawurlencode(implode(' ', $fq)); + $querystrings['filters'] = implode(' ', $fq); } if ($this->solrsort) { - $querystring .= ($querystring ? '&' : '') .'solrsort='. rawurlencode($this->solrsort); + $querystrings['solrsort'] = strtr($this->solrsort, array_flip($this->field_map)); + } + foreach ($querystrings as $key => $value) { + $querystrings[$key] = rawurlencode(check_plain($value)); } - return $querystring; + return implode('&', $querystrings); } public function get_fq() {