This came from a ticket I raised with Acquia as I had a use case that need an All facet. Robert Douglass asked me to raise this as a feature request on drupal.org.

Use Case: Allow a user to select an 'All' facet that essentially removes all previous facets applied for that particular type (example of a site implementing this type of funtionality - http://www.tripadvisor.com/Hotels-g293924-Hanoi-Hotels.html).

Notes: I see this being an option in the apachesolr facet block configuration in a similar way to the 'Include a facet for missing' i.e. 'Include a facet for all'. Below is the code that works around this through theming (I've marked start and end comments around what has changed from the original theme_apachesolr_facet_list, there is also a help function at the bottom for array insert but maintaining the indices), however I think this is best incorporated into the core apachesolr module.

/**
* An implementation of hook_theme_registry_alter()
* Swap in our own replacement for theme_apachesolr_facet_list()
*
* @param mixed $theme_registry
*/
function example_theme_registry_alter(&$theme_registry) {
  $theme_registry['apachesolr_facet_list']['function'] = 'theme_example_apachesolr_facet_list'; 
} 

/**
* Override of the facet list theme. Allows the "All" facet to be output.
*
* @param array $items
* @param mixed $display_limit
* @param mixed $delta
*/
function theme_example_apachesolr_facet_list($items, $display_limit = 0, $delta = '') {
  apachesolr_js();   
 
  $items = array_values($items);
 
  // START:
  // PATCH TO OUTPUT THE "ALL" FACET LINK
  $response = apachesolr_static_response_cache();
 
  if ($fields = apachesolr_cck_fields()) {
   
    $query = apachesolr_current_query();
   
    foreach ($fields as $name => $field) {
      if ($field['field_name'] == $delta) {
        $facet_field = apachesolr_index_key($field);

        $total = 0;
        $filter_applied = FALSE;

        foreach ($response->facet_counts->facet_fields->$facet_field as $facet => $count) {
          $total += $count;
         
          if ($query->has_filter($facet_field, $facet)) {
            $filter_applied = TRUE;
          }
        }
       
        $new_query = clone $query;
        $new_query->remove_filter($facet_field);
       
        $options = array();
        $options['query'] = $new_query->get_url_queryvalues();
   
        if ($filter_applied) {
          // A filter is already applied so "All" should be in an unchecked state
          $link = theme('apachesolr_facet_link',
            t('All'),
            $new_query->get_path(),
            $options,
            $total,
            FALSE,
            $response->response->numFound
          );
        }
        else {
          // A filter isn't applied so "All" should be in a checked state
          $link = theme('apachesolr_unclick_link',
            t('All') . ' ('. $total .')',
            $new_query->get_path(),
            $options
          );
        }
        example_array_insert($items, $link, 0);
      }
    }
  }
  // END:
  // PATCH TO OUTPUT THE "ALL" FACET LINK

 
  // If there is a limit and the facet count is over the limit, hide the rest.
  if (($display_limit > 0) && (count($items) > $display_limit)) {
    // Split items array into displayed and hidden.
    $hidden_items = array_splice($items, $display_limit);
    foreach ($hidden_items as $hidden_item) {
      if (!is_array($hidden_item)) {
        $hidden_item = array('data' => $hidden_item);
      }
      $items[] = $hidden_item + array('class' => 'apachesolr-hidden-facet');
    }
  }
 
  $admin_link = '';
  if (user_access('administer search')) {
    $admin_link = l(t('Configure enabled filters'), 'admin/settings/apachesolr/enabled-filters');
  }
 
  return theme('item_list', $items) . $admin_link;
}

/**
* Inserts an element into the array at a specific position. Maintains
* original key indicies.
*
* @param array $array
* @param mixed $insert
* @param mixed $position
*/
function example_array_insert(&$array, $insert, $position){
 
  $length = count($array);
 
  if(!is_numeric($position))
    return FALSE;
   
  if($position == $length){
    $array = array_merge($array, array($insert));
  }
  else{
    $head = array_slice($array, 0, $position);
    $insert = array($insert);
    $tail = array_slice($array, $position);
    $array = array_merge($head, $insert, $tail);
  }
 
  return FALSE;
}

Comments

robertdouglass’s picture

Great! Will review before releasing a 1.0 of the branch.

jpmckinney’s picture

Version: 6.x-2.0-alpha2 » 6.x-2.x-dev
kmadel’s picture

Just curious what the status of this is...

pwolanin’s picture

Version: 6.x-2.x-dev » 7.x-1.x-dev
Anonymous’s picture

The last comment moved this to 7.x.1.x-dev but I'd really like to see this implemented in 6.x as well.

jpmckinney’s picture

It will be done in 7.x first, unless someone writes a patch for 6.x.

elliotttf’s picture

Status: Active » Needs review
StatusFileSize
new4.17 KB

Here's a first cut of this. Rather than show an unclick link when no filters are applied for the given block I've just suppressed output of the "All" link.

pifantastic’s picture

Status: Needs review » Needs work

Tested this patch against Drupal 7 head with a node type filter. The 'All' link does not appear to be removing the node type filter.

elliotttf’s picture

Status: Needs work » Needs review
StatusFileSize
new4.11 KB

Fixed the 'All' facet by using field delta rather than field info.

jpmckinney’s picture

Project: Apache Solr Search » Facet API

Moving to Facet API for consideration.

jpmckinney’s picture

Title: Implement "All" Facet to apachesolr facet block configuration » Implement "All" Facet to facet block configuration
cpliakas’s picture

I see the use case here. This will take a little re-thinking due to the architectural change of using Facet API. Thanks for posting the link to the site. I think this range of displays is exactly the type of thing that Facet API is designed to facilitate. Obviously we are not there yet, but I think the foundation is almost there.

cpliakas’s picture

Status: Needs review » Needs work

With the addition of "Empty" facets in beta2, this is pretty much the opposite. Marking as needs work, since the code now has to work with Facet API.

cpliakas’s picture

Project: Facet API » Apache Solr Search

Punting back to Apache Solr Search Integration. I think this is out of the scope of Facet API and needs to be handled by the backend module itself since it has the responsibility of providing Facet API with the data.

nick_vh’s picture

With all flexibility in place I guess you are able to code this now? Can someone confirm?

nick_vh’s picture

Status: Needs work » Postponed (maintainer needs more info)
nick_vh’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

This is doable with contrib or custom coding so marking as won't fix.