Apachesolr should use standard query strings: instead of those strange filters=field1:value%20field2:value&solrsort=stitle asc, we should use standard query strings like field1=value&field2=value&sort=title:asc.

From:  <>


---

 Solr_Base_Query.php      |  118 ++++++++++++++++++++++------------------------
 apachesolr.module        |   40 +++++++---------
 apachesolr_search.module |    9 ++--
 3 files changed, 81 insertions(+), 86 deletions(-)

diff --git Solr_Base_Query.php Solr_Base_Query.php
index aa23402..c7d0196 100644
--- Solr_Base_Query.php
+++ Solr_Base_Query.php
@@ -54,18 +54,10 @@ class Solr_Base_Query {
    * is an array with #name and #value properties.  Each value is a
    * used for filter queries, e.g. array('#name' => 'uid', '#value' => 0)
    * for anonymous content.
-
    */
   protected $fields;
 
   /**
-   * 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 $filters;
-
-  /**
    * A mapping of field names from the URL to real index field names.
    */
   protected $field_map = array();
@@ -94,16 +86,16 @@ class Solr_Base_Query {
    *   The string that a user would type into the search box. Suitable input
    *   may come from search_get_keys()
    *
-   * @param $filterstring
+   * @param $filters
    *   Key and value pairs that are applied as a filter query.
    *
    * @param $sortstring
    *   Visible string telling solr how to sort - added to output querystring.
    */
-  function __construct($solr, $querypath, $filterstring, $sortstring) {
+  function __construct($solr, $querypath, array $filters, $sortstring) {
     $this->solr = $solr;
     $this->querypath = trim($querypath);
-    $this->filters = trim($filterstring); 
+    $this->filters = $filters;
     $this->solrsort = trim($sortstring);
     $this->id = ++self::$idCount;
     $this->parse_filters();
@@ -201,22 +193,48 @@ class Solr_Base_Query {
   public function set_solrsort($sortstring) {
     $this->solrsort = trim($sortstring);
   }
+
   /**
    * Return filters and sort in a form suitable for a query param to url().
    */
   public function get_url_querystring() {
-    $querystring = '';
-    if ($fq = $this->rebuild_fq(TRUE)) {
-      $querystring = 'filters='. implode(' ', $fq);
+
+    $field_aliases = array_flip($this->field_map);
+
+    $query = array();
+    foreach ($this->fields as $field) {
+      $name = isset($field_aliases[$field['#name']]) ? $field_aliases[$field['#name']] : $field['#name'];
+      $query[$name][] = $field['#value'];
+    }
+
+    // Fold single values into scalars.
+    foreach ($query as $key => $value) {
+      if (count($value) == 1) {
+        $query[$key] = $value[0];
+      }
     }
+
     if ($this->solrsort) {
-      $querystring .= ($querystring ? '&' : '') .'solrsort='. $this->solrsort;
+      $query['solrsort'] = $this->solrsort;
     }
-    return $querystring;
+    return $query;
   }
 
   public function get_fq() {
-    return $this->rebuild_fq();
+    $fields = array();
+    foreach ($this->fields as $pos => $field) {
+      $fq[] = Solr_Base_Query::make_field($field);
+    }
+
+    foreach ($this->subqueries as $id => $data) {
+      $subfq = $data['#query']->get_url_querystring();
+      if ($subfq) {
+        $operator = $data['#fq_operator'];
+        $fq[] = "(" . implode(" {$operator} ", $subfq) .")";
+      }
+    }
+
+    return $fq;
   }
 
   /**
@@ -244,8 +262,9 @@ class Solr_Base_Query {
       if (isset($this->field_map[$name])) {
         $field['#name'] = $this->field_map[$name];
       }
-      $progressive_crumb[] = Solr_Base_Query::make_field($field);
-      $options = array('query' => 'filters=' . implode(' ', $progressive_crumb));
+      $progressive_crumb[] = $field;
+
+      $options = array('query' => $this->get_url_querystring($progressive_crumb));
       if ($themed = theme("apachesolr_breadcrumb_{$name}", $field['#value'])) {
         $breadcrumb[] = l($themed, $base, $options);
       }
@@ -261,59 +280,34 @@ class Solr_Base_Query {
   }
 
   /**
-   * Parse the filter string in $this->filters into $this->fields.
-   *
-   * Builds an array of field name/value pairs.
+   * Parse filters from the URL into $this->fields.
    */
   protected function parse_filters() {
     $this->fields = array();
-    $filters = $this->filters;
 
     // Gets information about the fields already in solr index.
-    $index_fields = $this->solr->getFields();
-
-    foreach ((array) $index_fields as $name => $data) {
-      // Look for a field alias.
-      $alias = isset($this->field_map[$name]) ? $this->field_map[$name] : $name;
-      // Get the values for $name
-      $extracted = Solr_Base_Query::field_extract($filters, $alias);
-      if (count($extracted['values'])) {
-        foreach ($extracted['values'] as $index => $value) {
-          $pos = strpos($this->filters, $extracted['queries'][$index]);
-          // $solr_keys and $solr_crumbs are keyed on $pos so that query order
-          // is maintained. This is important for breadcrumbs.
-          $this->fields[$pos] = array('#name' => $name, '#value' => trim($value));
-        }
+    $index_fields = array_keys((array) $this->solr->getFields());
+    // Transform it in a (key => key) form.
+    $index_fields = array_combine($index_fields, $index_fields);
+    // Add aliases.
+    $index_fields += $this->field_map;
+
+    foreach ($this->filters as $alias => $value) {
+      if (!isset($index_fields[$alias])) {
+        continue;
       }
-    }
-    // Even though the array has the right keys they are likely in the wrong
-    // order. ksort() sorts the array by key while maintaining the key.
-    ksort($this->fields);
-  }
 
-  /**
-   * Builds a set of filter queries from $this->fields and all subqueries.
-   *
-   * Returns an array of strings that can be combined into
-   * a URL query parameter or passed to Solr as fq paramters.
-   */
-  protected function rebuild_fq($aliases = FALSE) {
-    $fields = array();
-    foreach ($this->fields as $pos => $field) {
-      // Look for a field alias.
-      if ($aliases && isset($this->field_map[$field['#name']])) {
-        $field['#name'] = $this->field_map[$field['#name']];
+      $name = $index_fields[$alias];
+
+      // Transform single-values into arrays.
+      if (!is_array($value)) {
+        $value = array($value);
       }
-      $fq[] = Solr_Base_Query::make_field($field);
-    }
-    foreach ($this->subqueries as $id => $data) {
-      $subfq = $data['#query']->rebuild_fq($aliases);
-      if ($subfq) {
-        $operator = $data['#fq_operator'];
-        $fq[] = "(" . implode(" {$operator} ", $subfq) .")";
+
+      foreach ($value as $index => $value) {
+        $this->fields[] = array('#name' => $name, '#value' => trim($value));
       }
     }
-    return $fq;
   }
 
   protected function rebuild_query() {
diff --git apachesolr.module apachesolr.module
index 3279241..867dbe9 100644
--- apachesolr.module
+++ apachesolr.module
@@ -747,7 +747,6 @@ function apachesolr_facetcount_save($edit) {
  * }
  */
 function apachesolr_modify_query(&$query, &$params) {
-
   foreach (module_implements('apachesolr_modify_query') as $module) {
     $function_name = "{$module}_apachesolr_modify_query";
     $function_name($query, $params);
@@ -828,11 +827,14 @@ function apachesolr_static_response_cache($response = NULL) {
  *
  * The query object is built from the keys, filters, and sort.
  */
-function apachesolr_drupal_query($keys = '', $filters = '', $solrsort = '') {
-
+function apachesolr_drupal_query($keys = '', $filters = NULL, $solrsort = '') {
   list($module, $class) = variable_get('apachesolr_query_class', array('apachesolr', 'Solr_Base_Query'));
   include_once drupal_get_path('module', $module) .'/'. $class .'.php';
 
+  if (!isset($filters)) {
+    $filters = $_GET;
+  }
+
   try {
     $query = new $class(apachesolr_get_solr(), $keys, $filters, $solrsort);
   }
@@ -843,34 +845,30 @@ function apachesolr_drupal_query($keys = '', $filters = '', $solrsort = '') {
   return $query;
 }
 
-/**
- * Factory function for query objects representing the current search URL.
+/*
+ * Get (and optionaly store) query objects.
  *
- * The query object is built from the keys in the URL, but these may be
- * overridden by passing in parameters.
+ * @param $index
+ *   The index of the query to get.
+ * @param $set_query
+ *   Set the query to this object.
+ * @param $reset
+ *   Reset the query cache.
+ * @return
+ *   The query object.
  */
-function apachesolr_current_query($keys = '', $filters = '', $solrsort = '', $reset = FALSE) {
+function apachesolr_current_query($index = 'apachesolr_search', $set_query = NULL, $reset = FALSE) {
   static $_queries = array();
 
   if ($reset) {
     $_queries = array();
   }
 
-  if (empty($keys)) {
-    $keys = search_get_keys();
-  }
-  if (empty($filters) && !empty($_GET['filters'])) {
-    $filters = $_GET['filters'];
+  if (isset($set_query)) {
+    $_queries[$index] = $set_query;
   }
-  if (empty($solrsort) && !empty($_GET['solrsort'])) {
-    $solrsort = $_GET['solrsort'];
-  }
-  $index = $keys . '&filters=' . $filters;
 
-  if (empty($_queries) || !array_key_exists($index, $_queries)) {
-    $_queries[$index] = apachesolr_drupal_query($keys, $filters, $solrsort);
-  }
-  return is_object($_queries[$index]) ? clone $_queries[$index] : $_queries[$index];
+  return is_object($_queries[$index]) ? $_queries[$index] : NULL;
 }
 
 /**
diff --git apachesolr_search.module apachesolr_search.module
index bff0bdc..063c3d1 100644
--- apachesolr_search.module
+++ apachesolr_search.module
@@ -91,11 +91,14 @@ function apachesolr_search_search($op = 'search', $keys = NULL) {
 
       try {
         // This is the object that knows about the query coming from the user.
-        $query = apachesolr_current_query($keys);
+        $query = apachesolr_drupal_query($keys);
         if (is_null($query)) {
           throw new Exception(t('Could not construct a Solr query in function apachesolr_search_search()'));
         }
 
+        // Stores the query to be used elsewhere (especially in facet blocks).
+        apachesolr_current_query('apachesolr_search', $query);
+
         $results = array();
 
         $params = array(
@@ -488,11 +491,11 @@ function apachesolr_search_get_type($facet) {
 function apachesolr_search_form_search_form_alter(&$form, $form_state) {
 
   if (($form['module']['#value'] == 'apachesolr_search') && variable_get('apachesolr_search_spellcheck', FALSE) && apachesolr_has_searched() && ($response = apachesolr_static_response_cache())) {
-    //Get spellchecker suggestions into an array.
+    // Get spellchecker suggestions into an array.
     $suggestions = get_object_vars($response->spellcheck->suggestions);
 
     if ($suggestions) {
-      //Get the original query and replace words.
+      // Get the original query and replace words.
       $query = apachesolr_current_query();
 
       foreach($suggestions as $word => $value) {
