? SolrPhpClient
Index: Solr_Base_Query.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Solr_Base_Query.php,v
retrieving revision 1.1.4.40.2.4
diff -u -p -r1.1.4.40.2.4 Solr_Base_Query.php
--- Solr_Base_Query.php	27 Aug 2009 20:07:02 -0000	1.1.4.40.2.4
+++ Solr_Base_Query.php	13 Sep 2009 20:59:31 -0000
@@ -313,7 +313,9 @@ class Solr_Base_Query implements Drupal_
    public function get_url_queryvalues() {
     $queryvalues = array();
     if ($fq = $this->rebuild_fq(TRUE)) {
-      $queryvalues['filters'] = implode(' ', $fq);
+      foreach ($fq as $delta => $values) {
+        $queryvalues['filters'] .= ' ' . implode(' ', $values);
+      }
     }
     $solrsort = $this->solrsort;
     if ($solrsort && ($solrsort['#name'] != 'score' || $solrsort['#direction'] != 'asc')) {
@@ -436,7 +438,7 @@ class Solr_Base_Query implements Drupal_
       if ($aliases && isset($this->field_map[$field['#name']])) {
         $field['#name'] = $this->field_map[$field['#name']];
       }
-      $fq[] = $this->make_filter($field);
+      $fq[$field['#name']][] = $this->make_filter($field);
     }
     foreach ($this->subqueries as $id => $data) {
       $subfq = $data['#query']->rebuild_fq($aliases);
Index: apachesolr.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v
retrieving revision 1.1.2.12.2.155.2.22
diff -u -p -r1.1.2.12.2.155.2.22 apachesolr.module
--- apachesolr.module	10 Sep 2009 13:45:47 -0000	1.1.2.12.2.155.2.22
+++ apachesolr.module	13 Sep 2009 20:59:32 -0000
@@ -692,11 +692,11 @@ function apachesolr_block_visibility($qu
   // This variable is not static cached because variable_get() already does that.
   $type_filters = variable_get('apachesolr_type_filter', array());
   if (isset($type_filters[$module][$delta]) && $type_filters[$module][$delta] == TRUE) {
-    $facet_info = module_invoke($module, 'apachesolr_facets');
-    if (isset($facet_info[$delta]['content types'])) {
-      $has_filter = $query->get_filters($facet_info[$delta]['facet_field']);
+    $facet_info = apachesolr_get_facet_definitions();
+    if (isset($facet_info[$module][$delta]['content types'])) {
+      $has_filter = $query->get_filters($facet_info[$module][$delta]['facet_field']);
       $show = count($has_filter);
-      foreach ($facet_info[$delta]['content types'] as $content_type) {
+      foreach ($facet_info[$module][$delta]['content types'] as $content_type) {
         if ($query->has_filter('type', $content_type)) {
           $show = TRUE;
         }
@@ -709,6 +709,23 @@ function apachesolr_block_visibility($qu
   return TRUE;
 }
 
+function apachesolr_get_facet_definitions() {
+  static $definitions;
+  if (is_null($definitions)) {
+    $operator_settings = variable_get('apachesolr_operator', array());
+    foreach (module_implements('apachesolr_facets') as $module) {
+      $facets = module_invoke($module, 'apachesolr_facets');
+      foreach ($facets as $delta => $info) {
+        $definitions[$module][$delta] = $info;
+        if(isset($definitions[$module][$delta])) {
+          $definitions[$module][$delta]['operator'] = $operator_settings[$module][$delta];
+        }
+      }
+    }
+  }
+  return $definitions;
+}
+
 /**
  * Implementation of hook_form_[form_id]_alter().
  *
@@ -732,25 +749,31 @@ function apachesolr_form_block_admin_con
     return;
   }
 
-  $facet_info = module_invoke($module, 'apachesolr_facets');
+  $facet_info = apachesolr_get_facet_definitions();
 
-  // If this facet doesn't define any content type array, get out of here.
-  if (!isset($facet_info[$delta]['content types'])) {
-    return;
+  if (isset($facet_info[$module][$delta]['content types'])) {
+    $type_filter_settings = variable_get('apachesolr_type_filter', array());
+    // Set up some variables for the verbiage of the form element.
+    $count = count($facet_info[$module][$delta]['content types']);
+    $types = format_plural($count, t('type'), t('types'));
+    $are = format_plural($count, t('is'), t('are'));
+    $content_types = implode(', ', $facet_info[$module][$delta]['content types']) . '.';
+    $form['block_settings']['apachesolr_type_filter'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show this block only when the type filter is selected for: %content_types',  array('%content_types' => $content_types)),
+      '#default_value' => isset($type_filter_settings[$module][$delta]) ? $type_filter_settings[$module][$delta] : FALSE,
+      '#description' => t('This filter is relevant only for specific content types. Check this to display the block only when the type filter has been selected for one of the relevant content types.'),
+      '#weight' => 11,
+    );
   }
-
-  $settings = variable_get('apachesolr_type_filter', array());
-  // Set up some variables for the verbiage of the form element.
-  $count = count($facet_info[$delta]['content types']);
-  $types = format_plural($count, t('type'), t('types'));
-  $are = format_plural($count, t('is'), t('are'));
-  $content_types = implode(', ', $facet_info[$delta]['content types']) . '.';
-  $form['block_settings']['apachesolr_type_filter'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Show this block only when the type filter is selected for: %content_types',  array('%content_types' => $content_types)),
-    '#default_value' => isset($settings[$module][$delta]) ? $settings[$module][$delta] : FALSE,
-    '#description' => t('This filter is relevant only for specific content types. Check this to display the block only when the type filter has been selected for one of the relevant content types.'),
-    '#weight' => 11,
+  $operator_settings = variable_get('apachesolr_operator', array());
+  $form['block_settings']['apachesolr_operator'] = array(
+    '#type' => 'radios',
+    '#title' => t('Operator to use for facets'),
+    '#options' => drupal_map_assoc(array('AND', 'OR')),
+    '#default_value' => isset($operator_settings[$module][$delta]) ? $operator_settings[$module][$delta] : 'AND',
+    '#description' => t('AND filters are exclusive. OR filters are inclusive. Selecting more AND filters narrows the result set. Selecting more OR filters widens the result set.'),
+    '#weight' => 12,
   );
   // Add a submit handler to save the value.
   $form['#validate'][] = 'apachesolr_block_admin_configure_submit';
@@ -758,12 +781,20 @@ function apachesolr_form_block_admin_con
 
 function apachesolr_block_admin_configure_submit($form, &$form_state) {
   if (isset($form_state['values']['apachesolr_type_filter'])) {
-    $settings = variable_get('apachesolr_type_filter', array());
+    $type_filter_settings = variable_get('apachesolr_type_filter', array());
     $module = $form_state['values']['module'];
     $delta = $form_state['values']['delta'];
-    unset($settings[$module][$delta]);
-    $settings[$module][$delta] = $form_state['values']['apachesolr_type_filter'];
-    variable_set('apachesolr_type_filter', $settings);
+    unset($type_filter_settings[$module][$delta]);
+    $type_filter_settings[$module][$delta] = $form_state['values']['apachesolr_type_filter'];
+    variable_set('apachesolr_type_filter', $type_filter_settings);
+  }
+  if (isset($form_state['values']['apachesolr_operator'])) {
+    $operator_settings = variable_get('apachesolr_operator', array());
+    $module = $form_state['values']['module'];
+    $delta = $form_state['values']['delta'];
+    unset($operator_settings[$module][$delta]);
+    $operator_settings[$module][$delta] = $form_state['values']['apachesolr_operator'];
+    variable_set('apachesolr_operator', $operator_settings);
   }
 }
 
@@ -1115,15 +1146,14 @@ function apachesolr_facetcount_save($edi
  * }
  */
 function apachesolr_modify_query(&$query, &$params, $caller) {
-
-  foreach (module_implements('apachesolr_modify_query') as $module) {
-    $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;
+    foreach ($fq as $delta => $values) {
+      foreach ($values as $value) {
+        $params['fq'][$delta][] = $value;
+      }
+    }
   }
   // Add sort if present.
   if ($query) {
@@ -1134,6 +1164,32 @@ function apachesolr_modify_query(&$query
       $params['sort'] = $sortstring;
     }
   }
+  $ors = array();
+  $facet_info = apachesolr_get_facet_definitions();
+  foreach ($facet_info as $infos) {
+    foreach($infos as $delta => $facet) {
+      if ($facet['operator'] == 'OR') {
+        $ors[] = $delta;
+      }
+    }
+  }
+  foreach (module_implements('apachesolr_modify_query') as $module) {
+    $function_name = $module . '_apachesolr_modify_query';
+    $function_name($query, $params, $caller);
+  }
+  if ($filter_queries = $params['fq']) {
+    foreach ($filter_queries as $delta => $value) {
+      $fq = $tag = '';
+      $op = 'AND';
+      if (in_array($delta, $ors)) {
+        $tag = "{!tag=$delta}";
+        $op = 'OR';
+      }
+      $fq = implode(" $op ", $params['fq'][$delta]);
+      $params['fq'][] = $tag . $fq;
+      unset($params['fq'][$delta]);
+    }
+  }
 }
 
 /**
Index: apachesolr_search.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v
retrieving revision 1.1.2.6.2.111.2.16
diff -u -p -r1.1.2.6.2.111.2.16 apachesolr_search.module
--- apachesolr_search.module	13 Sep 2009 14:15:13 -0000	1.1.2.6.2.111.2.16
+++ apachesolr_search.module	13 Sep 2009 20:59:32 -0000
@@ -307,7 +307,7 @@ function apachesolr_search_execute($keys
     // No highlighting, use the teaser as a snippet.
     $params['fl'] .= ',teaser';
   }
-  apachesolr_search_add_facet_params($params, $query);
+  $has_or = apachesolr_search_add_facet_params($params, $query);
   apachesolr_search_add_boost_params($params, $query, $solr);
 
   $params['start'] = $page * $params['rows'];
@@ -322,12 +322,11 @@ function apachesolr_search_execute($keys
     return array();
   }
 
-  if (('' == $keys) && isset($params['fq'])) {
+  if (!$has_or && ('' == $keys) && isset($params['fq'])) {
     // 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.
@@ -379,6 +378,8 @@ function apachesolr_search_spellcheck_pa
 function apachesolr_search_add_facet_params(&$params, $query) {
   $facet_query_limits = variable_get('apachesolr_facet_query_limits', array());
   $facet_missing = variable_get('apachesolr_facet_missing', array());
+  $facet_info = apachesolr_get_facet_definitions();
+  $ors = array();
 
   foreach (apachesolr_get_enabled_facets() as $module => $module_facets) {
     foreach($module_facets as $delta => $facet_field) {
@@ -393,7 +394,10 @@ function apachesolr_search_add_facet_par
         }
       }
       else {
-        $params['facet.field'][] = $facet_field;
+        if ($facet_info[$module][$delta]['operator'] == 'OR') {
+          $ors[$delta] = $delta;
+        }
+        $params['facet.field'][$delta][] = $facet_field;
         // Facet limits
         if (isset($facet_query_limits[$module][$delta])) {
           $params['f.' . $facet_field . '.facet.limit'] = $facet_query_limits[$module][$delta];
@@ -409,7 +413,23 @@ function apachesolr_search_add_facet_par
   if (!empty($params['facet.field'])) {
     // Add a default limit for fields where no limit was set.
     $params['facet.limit'] = variable_get('apachesolr_facet_query_limit_default', 20);
+    if ($facet_fields = $params['facet.field']) {
+      foreach ($facet_fields as $delta => $values) {
+        $ex = $ff = '';
+        $op = 'AND';
+
+        if (in_array($delta, $ors)) {
+          $ex = "{!ex=$delta}";
+          $op = 'OR';
+        }
+        $ff = implode(" $op ", $params['facet.field'][$delta]);
+        $params['facet.field'][] = $ex . $ff;
+
+        unset($params['facet.field'][$delta]);
+      }
+    }
   }
+  return count($ors);
 }
 
 function apachesolr_search_add_boost_params(&$params, $query, $solr) {
@@ -567,7 +587,6 @@ function apachesolr_search_date_range($q
  */
 function apachesolr_search_apachesolr_facets() {
   $facets = array();
-
   $facets['type'] = array(
     'info' => t('Node attribute: Filter by content type'),
     'facet_field' => 'type',
@@ -681,7 +700,7 @@ function apachesolr_search_block($op = '
             $terms = array();
 
             foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) {
-              $options = array();
+              $options = array('delta' => $delta);
               if ($tid == '_empty_') {
                 // TODO - for now we don't handle facet missing.
                 continue;
