Index: apachesolr_search.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v
retrieving revision 1.1.2.6.2.98
diff -u -p -r1.1.2.6.2.98 apachesolr_search.module
--- apachesolr_search.module	10 Jun 2009 12:54:12 -0000	1.1.2.6.2.98
+++ apachesolr_search.module	12 Jun 2009 16:53:47 -0000
@@ -52,6 +52,16 @@ function apachesolr_search_menu() {
   return $items;
 }
 
+ /**
+ * Implementation of hook_menu_alter().
+ */
+function apachesolr_search_menu_alter(&$menu) {
+  if (isset($menu['search/apachesolr_search/%menu_tail'])) {
+    $menu['search']['page callback'] = 'apachesolr_search_view';
+    $menu['search/apachesolr_search/%menu_tail']['page callback'] = 'apachesolr_search_view';
+  }
+}
+
 /**
  * Implementation of hook_update_index().
  */
@@ -104,6 +114,48 @@ function apachesolr_search_search($op = 
 }
 
 /**
+ * Re-implementation of search_view().
+ */
+function apachesolr_search_view($type = NULL) {
+  // Search form submits with POST but redirects to GET.
+  $results = '';
+  if (!isset($_POST['form_id'])) {
+    if (empty($type)) {
+      // Note: search/X can not be a default tab because it would take on the
+      // path of its parent (search). It would prevent remembering keywords when
+      // switching tabs. This is why we drupal_goto to it from the parent instead.
+      drupal_goto('search/apachesolr_search');
+    }
+    $keys = trim(search_get_keys());
+    $filters = '';
+    if ($type == 'apachesolr_search' && isset($_GET['filters'])) {
+      $filters = trim($_GET['filters']);
+    }
+    // Only perform search if there is non-whitespace search term or filters:
+    if ($keys || $filters) {
+      // Log the search keys:
+      $log = $keys;
+      if ($filters) {
+        $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);
+      }
+      else {
+        $results = theme('box', t('Your search yielded no results'), search_help('search#noresults', drupal_help_arg()));
+      }
+    }
+  }
+  // Construct the search form.
+  return drupal_get_form('search_form', NULL, $keys, $type) . $results;
+}
+
+/**
  * Execute a search results based on keyword, filter, and sort strings.
  *
  * @throws Exception
@@ -126,6 +178,14 @@ function apachesolr_search_execute($keys
   // This is the object that does the communication with the solr server.
   $solr = apachesolr_get_solr();
   $params += apachesolr_search_basic_params($query);
+  if ($keys) {
+    $params += apachesolr_search_highlighting_params($query);
+    $params += apachesolr_search_spellcheck_params($query);
+  }
+  else {
+    // No highlighting, use the teaser as a snippet.
+    $params['fl'] .= ',teaser';
+  }
   apachesolr_search_add_facet_params($params, $query);
   apachesolr_search_add_boost_params($params, $query, $solr);
 
@@ -140,6 +200,13 @@ function apachesolr_search_execute($keys
   if (!$query) {
     return array();
   }
+  
+  if ('' == $keys) {
+    // Move the fq params to the q.alt for better performance.
+    $params['q.alt'] = implode(' ', $params['fq']);
+    unset($params['fq']);
+  }
+
   $response = $solr->search($query->get_query_basic(), $params['start'], $params['rows'], $params);
   // The response is cached so that it is accessible to the blocks and anything
   // else that needs it beyond the initial search.
@@ -158,21 +225,28 @@ function apachesolr_search_basic_params(
     'facet.mincount' => 1,
     'facet.sort' => 'true'
   );
+  return $params;
+}
 
-  /**
-   * Highlighting settings
-   * These settings are set in solrconfig.xml.
-   * See the defaults there.
-   * If you wish to override them, you can via settings.php
-   */
-
+/**
+ * Add highlighting settings to the search params.
+ *
+ * These settings are set in solrconfig.xml.
+ * See the defaults there.
+ * If you wish to override them, you can via settings.php
+ */
+function apachesolr_search_highlighting_params($query) {
   $params['hl'] = variable_get('apachesolr_hl_active', NULL);
   $params['hl.fragsize']= variable_get('apachesolr_hl_textsnippetlength', NULL);
   $params['hl.simple.pre'] = variable_get('apachesolr_hl_pretag', NULL);
   $params['hl.simple.post'] = variable_get('apachesolr_hl_posttag', NULL);
   $params['hl.snippets'] = variable_get('apachesolr_hl_numsnippets', NULL);
   $params['hl.fl'] = variable_get('apachesolr_hl_fieldtohightlight', NULL);
+  return $params;
+}
 
+function apachesolr_search_spellcheck_params($query) {
+  $params = array();
   if (variable_get('apachesolr_search_spellcheck', FALSE)) {
     //Add new parameter to the search request
     $params['spellcheck.q'] = $query->get_query_basic();
@@ -294,7 +368,18 @@ function apachesolr_process_response($re
   if ($total > 0) {
     foreach ($response->response->docs as $doc) {
       $extra = array();
-      $snippet = isset($response->highlighting->{$doc->id}->$hl_fl) ? theme('apachesolr_search_snippets', $doc, $response->highlighting->{$doc->id}->$hl_fl) : '';
+
+      // Find the nicest available snippet.
+      if (isset($response->highlighting->{$doc->id}->$hl_fl)) {
+        $snippet = theme('apachesolr_search_snippets', $doc, $response->highlighting->{$doc->id}->$hl_fl);
+      }
+      elseif (isset($doc->teaser)) {
+        $snippet = theme('apachesolr_search_snippets', $doc, array(truncate_utf8($doc->teaser, 256, TRUE)));
+      }
+      else {
+        $snippet = '';
+      }
+
       if (!isset($doc->body)) {
         $doc->body = $snippet;
       }
@@ -616,9 +701,9 @@ function apachesolr_search_form_search_f
 
   if ($form['module']['#value'] == 'apachesolr_search') {
     $filters = isset($_REQUEST['filters']) ? trim($_REQUEST['filters']) : '';
-    $form['apachesolr_search']['#tree'] = TRUE;
+    $form['basic']['apachesolr_search']['#tree'] = TRUE;
     if ($filters) {
-      $form['apachesolr_search']['retain-filters'] = array(
+      $form['basic']['apachesolr_search']['retain-filters'] = array(
         '#type' => 'checkbox',
         '#title' => t('Retain current filters'),
         '#default_value' => !empty($_GET['retain-filters']), 
@@ -629,7 +714,7 @@ function apachesolr_search_form_search_f
       '#default_value' => $filters,
     );
 
-    $form['#submit'][] = 'apachesolr_search_form_search_submit';
+    $form['#submit'] = array('apachesolr_search_form_search_submit');
     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);
@@ -661,16 +746,19 @@ function apachesolr_search_form_search_f
  * @see apachesolr_search_form_search_form_alter()
  */
 function apachesolr_search_form_search_submit($form, &$form_state) {
-  $keys = $form_state['values']['processed_keys'];
-  $base = 'search/'. $form_state['values']['module'] . '/';
+  $fv = $form_state['values'];
+  $keys = $fv['processed_keys'];
+  $query = '';
+  $base = 'search/'. $fv['module'] . '/';
   if (variable_get('clean_url', '0')) {
     $keys = str_replace('+', '%2B', $keys);
-    $form_state['redirect'] = $base . $keys;
   }
-  if (!empty($form_state['values']['apachesolr_search']['retain-filters'])) {
-    $query['retain-filters'] = '1';
-    $query['filters'] = $form_state['values']['filters'];
-    $form_state['redirect'] = array($base . $keys, $query);
+  if (!empty($fv['apachesolr_search']['retain-filters']) && $fv['filters']) {
+    $query = 'filters=' . rawurlencode($fv['filters']) . '&retain-filters=1';
+  }
+  $form_state['redirect'] = array($base . $keys, $query);
+  if ($keys == '' && $query == '') {
+    form_set_error('keys', t('Please enter some keywords.'));
   }
 }
 
@@ -811,5 +899,6 @@ function theme_apachesolr_currentsearch(
  *
  */
 function theme_apachesolr_search_snippets($doc, $snippets) {
-  return implode(' ... ', $snippets);
+  return implode(' ... ', $snippets) .' ...';
 }
+
Index: schema.xml
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/schema.xml,v
retrieving revision 1.1.2.1.2.31
diff -u -p -r1.1.2.1.2.31 schema.xml
--- schema.xml	2 Mar 2009 04:47:44 -0000	1.1.2.1.2.31
+++ schema.xml	12 Jun 2009 16:53:47 -0000
@@ -11,7 +11,7 @@
  http://wiki.apache.org/solr/SchemaXml
 -->
 
-<schema name="drupal-0.9.2" version="1.1">
+<schema name="drupal-0.9.3" version="1.1">
   <!-- attribute "name" is the name of this schema and is only used for display purposes.
        Applications should change this to reflect the nature of the search collection.
        version="1.1" is Solr's version number for the schema syntax and semantics.  It should
@@ -263,6 +263,7 @@
    <field name="title" type="text" indexed="true" stored="true" termVectors="true" omitNorms="true"/>
    <field name="sort_title" type="sortString" indexed="true" stored="false"/>
    <field name="body" type="text" indexed="true" stored="true" termVectors="true"/>
+   <field name="teaser" type="text" indexed="false" stored="true"/>
    <field name="type" type="string" indexed="true" stored="true"/>
    <field name="type_name" type="string" indexed="true" stored="true"/>
    <field name="path" type="string" indexed="true" stored="true"/>
@@ -293,7 +294,9 @@
    <copyField source="name" dest="sort_name"/>
    <!-- Copy terms to a single field that contains all taxonomy term names -->
    <copyField source="ts_vid_*" dest="taxonomy_names"/>
-
+   <!-- The teaser can be used when a better snippet is not available -->
+   <copyField source="body" dest="teaser" maxChars="300"/>
+  
    <!-- A set of fields to contain text extracted from tag contents which we
         can boost at query time. -->
    <field name="tags_h1" type="text" indexed="true" stored="false" omitNorms="true"/>
