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;
}
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | optional-all-facet-738076-9.patch | 4.11 KB | elliotttf |
| #7 | optional-all-facet-738076-7.patch | 4.17 KB | elliotttf |
Comments
Comment #1
robertdouglass commentedGreat! Will review before releasing a 1.0 of the branch.
Comment #2
jpmckinney commentedComment #3
kmadel commentedJust curious what the status of this is...
Comment #4
pwolanin commentedComment #5
Anonymous (not verified) commentedThe last comment moved this to 7.x.1.x-dev but I'd really like to see this implemented in 6.x as well.
Comment #6
jpmckinney commentedIt will be done in 7.x first, unless someone writes a patch for 6.x.
Comment #7
elliotttf commentedHere'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.
Comment #8
pifantastic commentedTested this patch against Drupal 7 head with a node type filter. The 'All' link does not appear to be removing the node type filter.
Comment #9
elliotttf commentedFixed the 'All' facet by using field delta rather than field info.
Comment #10
jpmckinney commentedMoving to Facet API for consideration.
Comment #11
jpmckinney commentedComment #12
cpliakas commentedI 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.
Comment #13
cpliakas commentedWith 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.
Comment #14
cpliakas commentedPunting 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.
Comment #15
nick_vhWith all flexibility in place I guess you are able to code this now? Can someone confirm?
Comment #16
nick_vhComment #17
nick_vhThis is doable with contrib or custom coding so marking as won't fix.