I have a Solr use case where I need to add some custom filter options to the search_form so they are available when the initial search is made, and not just as facet blocks after the search. It's pretty easy to add the filter ($query->add_filter() in hook_apachesolr_prepare_query()), but the problem is getting those values passed from the form submit to this hook implementation. Here's the form_alter code:

    function sprc_search_form_search_form_alter(&$form, &$form_state) {
      $form['inline']['advanced'] = array(
        '#type' => 'fieldset',
        '#title' => t('Advanced Search Options'),
        '#description' => t('Allows you to specify more detailed search option prior to search'),
        '#collapsible' => TRUE,
        '#collapesed' => FALSE,
      );
       
      $form['inline']['advanced']['resource_type'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Resource Type'),
        '#options' => array('online' => t('Online Library'), 'sprc' => t('SPRC Resources'), 'bpr' => t('Best Practices Registry'), 'events' => t('Events/Calendar'), 'grantee' => ('Grantee Only (Private Pages) content')),
      );
       
      $form['inline']['library_options'] = array(
        '#type' => 'fieldset',
        '#title' => t('Library Options Only'),
        '#description' => t('Options for library items'),
        '#collapsible' => TRUE,
        '#collapesed' => FALSE,
      );     
      
      $form['inline']['library_options']['title'] = array(
        '#type' => 'textfield',
        '#title' => t('Title'),
        '#description' => t('the title of the resource.  Can contain all or part of the title.'),
        '#size' => 30,
      );
      
      $form['inline']['library_options']['author'] = array(
        '#type' => 'textfield',
        '#title' => t('Author'),
        '#description' => t('The author of the resource.  Can contain all or part of the author\'s name.'),
        '#size' => 30,
      );
       
      $form['inline']['library_options']['from_date'] = array(
        '#type' => 'date_popup',
        '#title' => t('From'),
        '#date_format' => 'm-d-Y',
        '#date_year_range' => '-100:+0',
        '#default_value' => empty($date)? '' : date('Y-m-d H:i:s', $date),
        '#description' => t('Click in the field to see a popup calendar'),
      );
    
      $form['inline']['library_options']['to_date'] = array(
        '#type' => 'date_popup',
        '#title' => t('to'),
        '#date_format' => 'm-d-Y',
        '#date_year_range' => '-100:+0',
        '#default_value' => empty($date)? '' : date('Y-m-d H:i:s', $date),
        '#description' => t('Click in the field to see a popup calendar'),
      );
      
      // Get terms for Library Formats vocab to use in select list.
      $sql = "SELECT tid, name FROM {term_data} WHERE vid = %d";
      $result = db_query(db_rewrite_sql($sql), 6);
      
      $terms = array();
      
      while ($data = db_fetch_object($result)){
        $options[$data->tid] = $data->name;
      }
      
      $form['inline']['library_options']['type'] = array(
        '#type' => 'select',
        '#title' => t('Type'),
        '#options' => $options,
      );
      
      // Add another submit function to add items above to the query string.
      $form['#submit'][] = 'sprc_search_form_search_form_submit';        
    }

I chatted briefly with Peter Wolanin in IRC, and he said the way to do it is to add the terms to the query string with a custom submit function on the form. That part is easy enough, but that brings up some more questions:

  1. How do I add the filters to the query string? I don't want to add them to the $form_state['values']['keys'] array, because I don't want the form values used as keywords.
  2. Once I do get them added, how do I access them in the prepare_query_hook?
  3. Since the add_filter() method requires a Solr field, I'm assuming that I'll need to create a dynamic field in the update_index() hook that contains the value for the resource_type field. Correct? The fields for library_options are already indexed, since they are standard Drupal fields, so I won't need to add any fields there.
      Thanks.

Comments

wonder95’s picture

I've added code to my submit handlers to add the values to $form_state['redirect']:

  $resource_types = $form_state['values']['resource_type'];
  foreach ($resource_types as $rt) {
    if ($rt) {
      $filters[] = 'ss_resource_type:' . $rt; 
    } 
  }
  if ($filters) {
    $filterstring = implode(' ', $filters);
    
    $keys = $form_state['values']['processed_keys'];
    if (variable_get('clean_url', '0')) {
      $keys = str_replace('+', '%2B', $keys);
    }    
    $redirect = array('search/apachesolr_search/'. trim($keys), 'query' => array('filters' => $filterstring));
    $form_state['redirect'] = $redirect;
  }

This seems to work, because the values are available in $query in the modify_query() hook. However, I am unable to access those values there with this:

  foreach ($query->fields as $field) {
      $name = $field['#name'];
      $value = $field['#value'];
   
    $query->add_filter($name, $value);
  }

because I get an error "Fatal error: Cannot access protected property Solr_Base_Query::$fields". The whole idea of using the query string was to make them available here, but now I can't access them. How can I get around this error?

Thanks.

pwolanin’s picture

Did you try $query->get_fq() or $query->get_filters()?

It's really not clear why you need to do anything more if you added them to the filters string already.

wonder95’s picture

Status: Active » Closed (fixed)

I actually got this resolved.

drikc’s picture

Hello wonder95, would you share what you did found?

rwebsys’s picture

Normally we are adding filters like $query->add_filter("field", $value);

This seems to do exact search.

How can i search particular keyword using filters?
By default its searching in title and description but let suppose i have to find something else in another field, say about me, then its not working properly.
Also i need to apply filters for taxonomies.

Please anyone suggest me.