? .svn
? SolrPhpClient
? contrib/.svn
? contrib/apachesolr_image/.svn
? contrib/apachesolr_nodeaccess/.svn
? contrib/apachesolr_nodeaccess/tests/.svn
? contrib/apachesolr_og/.svn
? tests/.svn
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 10:49:13 -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_queryvalues = array();
 
   /**
    * @param $solr
@@ -123,17 +127,17 @@ 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() {
     $this->id = ++self::$idCount;
   }
-  
+
   public function add_filter($field, $value, $exclude = FALSE) {
     $this->fields[] = array('#exclude' => $exclude, '#name' => $field, '#value' => trim($value));
   }
@@ -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'),
@@ -263,17 +277,28 @@ class Solr_Base_Query implements Drupal_
   }
 
   /**
+   * Set extra GET parameters that need to be preserved. Typically you'd pass in $_GET or $form_state['values'].
+   */
+  public function set_extra_queryvalues($params, $exclude = array('q', 'page', 'filters', 'solrsort')) {
+    $this->extra_queryvalues = array_diff_key($params, array_flip($exclude));
+  }
+
+  /**
    * Return filters and sort in a form suitable for a query param to url().
    */
   public function get_url_querystring() {
-    $querystring = '';
+    $queryvalues = $this->extra_queryvalues;
     if ($fq = $this->rebuild_fq(TRUE)) {
-      $querystring = 'filters='. rawurlencode(implode(' ', $fq));
+      $queryvalues['filters'] = implode(' ', $fq);
     }
     if ($this->solrsort) {
-      $querystring .= ($querystring ? '&' : '') .'solrsort='. rawurlencode($this->solrsort);
+      $queryvalues['solrsort'] = strtr($this->solrsort, array_flip($this->field_map));
+    }
+    $querystrings = array();
+    foreach ($queryvalues as $key => $value) {
+      $querystrings[] = "{$key}=" . rawurlencode(check_plain($value));
     }
-    return $querystring;
+    return implode('&', $querystrings);
   }
 
   public function get_fq() {
@@ -287,7 +312,7 @@ class Solr_Base_Query implements Drupal_
   public function get_query_basic() {
     return $this->rebuild_query();
   }
-  
+
   /**
    * Return the search path.
    *
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 10:49:13 -0000
@@ -784,7 +784,7 @@ function apachesolr_date_find_query_gap(
 
 /**
  * Format an ISO date string based on the gap used to generate it.
- * 
+ *
  * This function assumes that gaps less than one day will be displayed
  * in a search context in which a larger containing gap including a
  * day is already displayed.  So, HOUR, MINUTE, and SECOND gaps only
@@ -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;
+  }
 }
 
 /**
@@ -1003,7 +1008,7 @@ function apachesolr_has_searched($search
  */
 function apachesolr_get_solr($host = NULL, $port = NULL, $path = NULL) {
   static $solr_cache;
-  
+
   if (empty($host)) {
     $host = variable_get('apachesolr_host', 'localhost');
   }
@@ -1060,7 +1065,7 @@ function apachesolr_static_response_cach
 function apachesolr_drupal_query($keys = '', $filters = '', $solrsort = '', $base_path = '') {
   list($module, $class) = variable_get('apachesolr_query_class', array('apachesolr', 'Solr_Base_Query'));
   include_once drupal_get_path('module', $module) .'/'. $class .'.php';
-  
+
   try {
     $query = new $class(apachesolr_get_solr(), $keys, $filters, $solrsort, $base_path);
   }
@@ -1068,7 +1073,7 @@ function apachesolr_drupal_query($keys =
     watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR);
     $query = NULL;
   }
-  
+
   return $query;
 }
 
@@ -1127,7 +1132,7 @@ function apachesolr_index_key($field) {
  * Try to map a schema field name to a human-readable description.
  */
 function apachesolr_field_name_map($field_name) {
-  require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc'); 
+  require_once(drupal_get_path('module', 'apachesolr') .'/apachesolr.admin.inc');
   return _apachesolr_field_name_map($field_name);
 }
 
@@ -1268,7 +1273,7 @@ function apachesolr_mlt_suggestions($set
       $docs = (array) end($response->response);
       return $docs;
     }
-  } 
+  }
   catch ( Exception $e ) {
     watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR );
   }
@@ -1425,7 +1430,7 @@ interface Drupal_Solr_Query_Interface {
    * The facet value to check against
    */
   function has_filter($field, $value);
-  
+
   /**
    * Remove a filter from the query
    *
@@ -1437,7 +1442,7 @@ interface Drupal_Solr_Query_Interface {
    * This value can be NULL
    */
   function remove_filter($field, $value = NULL);
-  
+
   /**
    * Add a filter to a query
    *
@@ -1453,33 +1458,47 @@ interface Drupal_Solr_Query_Interface {
    *   result set.
    */
   function add_filter($field, $value, $exclude = FALSE);
-  
+
   /**
    * Return the search path (including the search keywords).
    */
   function get_path();
-  
+
   /**
+   * Set extra values that will be added when calling get_url_querystring().
+   *
+   * @param $params
+   *   An array of parameters to be URL encoded. Typically $_GET.
+   * @param $exclude
+   *   An array of keys to exclude from $params.
+   * @return None.
+   */
+  function set_extra_queryvalues($params, $exclude = array('q', 'page', 'filters', 'solrsort'));
+
+ /**
    * Return any query string for use in the l function.
    *
    * @see l()
    */
   function get_url_querystring();
-  
+
   /**
    * return the basic string query
    */
   function get_query_basic();
-  
+
   /**
    * 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();
 
@@ -1487,7 +1506,7 @@ interface Drupal_Solr_Query_Interface {
    * Return an array of all filters.
    */
   function get_filters($name = NULL);
-  
+
   /**
    * Add a subquery to the query.
    *
@@ -1504,14 +1523,14 @@ interface Drupal_Solr_Query_Interface {
    *   keywords.
    */
   function add_subquery(Drupal_Solr_Query_Interface $query, $fq_operator = 'OR', $q_operator = 'AND');
-  
+
   /**
    * return the sorts that are provided by the query object
    *
    * @return array all the sorts provided
    */
   function get_available_sorts();
-  
+
   /**
    * Remove a specific subquery
    *
@@ -1519,12 +1538,12 @@ interface Drupal_Solr_Query_Interface {
    * the query to remove
    */
   function remove_subquery(Drupal_Solr_Query_Interface $query);
-  
+
   /**
    * remove all subqueries
    */
   function remove_subqueries();
-  
+
   /**
    * make a sort available
    */
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 10:49:13 -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) {
@@ -163,10 +163,10 @@ function apachesolr_search_view($type = 
         $log .= 'filters='. $filters;
       }
       watchdog('search', '%keys (@type).', array('%keys' => $log, '@type' => t('Search')), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys));
-    
+
       // Collect the search results:
       $results = search_data($keys, $type);
-    
+
       if ($results) {
         $results = theme('box', t('Search results'), $results);
       }
@@ -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_queryvalues($extra_querystrings);
   // This is the object that does the communication with the solr server.
   $solr = apachesolr_get_solr();
   $params += apachesolr_search_basic_params($query);
@@ -789,23 +783,23 @@ function apachesolr_search_form_search_f
       $form['basic']['apachesolr_search']['retain-filters'] = array(
         '#type' => 'checkbox',
         '#title' => t('Retain current filters'),
-        '#default_value' => (int) isset($_GET['retain-filters']), 
+        '#default_value' => (int) isset($_GET['retain-filters']),
       );
     }
 
     if (variable_get('apachesolr_search_spellcheck', FALSE) && $apachesolr_has_searched && ($response = apachesolr_static_response_cache())) {
       //Get spellchecker suggestions into an array.
       $suggestions = get_object_vars($response->spellcheck->suggestions);
-  
+
       if ($suggestions) {
         //Get the original query and replace words.
         $query = apachesolr_current_query();
-  
+
         foreach($suggestions as $word => $value) {
           $replacements[$word] = $value->suggestion[0];
         }
         $new_keywords = strtr($query->get_query_basic(), $replacements);
-  
+
         $form['basic']['suggestion'] = array(
           '#prefix' => '<div class="spelling-suggestions">',
           '#suffix' => '</div>',
