Index: apachesolr.module =================================================================== --- apachesolr.module (revision 27194) +++ apachesolr.module (working copy) @@ -932,6 +932,14 @@ '#description' => t('A facet can be generated corresponding to all documents entirely missing this field.'), '#default_value' => isset($facet_missing[$module][$delta]) ? $facet_missing[$module][$delta] : 0, ); + $reflect_hierarchy = variable_get('apachesolr_facet_reflect_hierarchy', array()); + $form['apachesolr_facet_reflect_hierarchy'] = array( + '#type' => 'checkbox', + '#title' => t('Links reflect hierarchy'), + '#description' => t('Facet will be sorted hierarchically if it bases on a hierarchical taxonomy vocabulary.'), + '#default_value' => !empty($reflect_hierarchy[$module][$delta]), + ); + return $form; } @@ -952,6 +960,9 @@ $facet_missing = variable_get('apachesolr_facet_missing', array()); $facet_missing[$module][$delta] = (int)$edit['apachesolr_facet_missing']; variable_set('apachesolr_facet_missing', $facet_missing); + $reflect_hierarchy = variable_get('apachesolr_facet_reflect_hierarchy', array()); + $reflect_hierarchy[$module][$delta] = $edit['apachesolr_facet_reflect_hierarchy']; + variable_set('apachesolr_facet_reflect_hierarchy', $reflect_hierarchy); } /** @@ -1372,8 +1383,8 @@ drupal_add_js(drupal_get_path('module', 'apachesolr') . '/apachesolr.js'); // Split items array into displayed and hidden. $hidden_items = array_splice($items, $display_limit); - foreach ($hidden_items as $link) { - $items[] = array('data' => $link, 'class' => 'apachesolr-hidden-facet'); + foreach ($hidden_items as $hidden_item) { + $items[] = $hidden_item + array('class' => 'apachesolr-hidden-facet'); } } $admin_link = ''; Index: apachesolr_search.module =================================================================== --- apachesolr_search.module (revision 27194) +++ apachesolr_search.module (working copy) @@ -460,51 +460,77 @@ $initial_limits = variable_get('apachesolr_facet_query_initial_limits', array()); $limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10); + $reflect_hierarchy = variable_get('apachesolr_facet_reflect_hierarchy', array()); + // Handle taxonomy vocabulary facets if ((strpos($delta, 'im_vid_') === 0) && module_exists('taxonomy')) { if (is_object($response->facet_counts->facet_fields->$delta)) { - $contains_active = FALSE; - $terms = array(); + $vid = substr($delta, 7); + if (is_numeric($vid)) { + $vocab = taxonomy_vocabulary_load($vid); + $terms = array(); - foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) { - if ($tid == '_empty_') { - // TODO - for now we don't handle facet missing. - continue; - } - $unclick_link = ''; - unset($active); - $term = taxonomy_get_term($tid); - $new_query = clone $query; - if ($active = $query->has_filter('tid', $tid)) { - $contains_active = TRUE; - $new_query->remove_filter('tid', $term->tid); - $path = $new_query->get_path(); - $querystring = $new_query->get_url_querystring(); - $unclick_link = theme('apachesolr_unclick_link', $path, $querystring); - } - else { - $new_query->add_filter('tid', $term->tid); - $path = $new_query->get_path(); - $querystring = $new_query->get_url_querystring(); + foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) { + if ($tid == '_empty_') { + // TODO - for now we don't handle facet missing. + continue; + } + $unclick_link = ''; + unset($active); + + $parents = array(); + if ($reflect_hierarchy['apachesolr_search'][$delta]) { + $parents = taxonomy_get_parents_all($tid); + if (!empty($parents[1]) && !$query->has_filter('tid', $parents[1]->tid)) { + continue; + } + + } + else if ($term = taxonomy_get_term($tid)) { + $parents[] = $term; + } + + $new_query = clone $query; + + $active = $query->has_filter('tid', $tid); + if ($active) { + $unclick_link = apachesolr_get_unclick_link($query, 'tid', $tid, $reflect_hierarchy['apachesolr_search'][$delta] ? $vid : FALSE); + } + else { + $new_query->add_filter('tid', $tid); + $path = $new_query->get_path(); + $querystring = $new_query->get_url_querystring(); + } + + // if numdocs == 1 and !active, don't add. + if ($response->response->numFound > 1 || $active) { + $sort_key = ''; + $term = NULL; + foreach (array_reverse($parents) as $term) { + $count = $response->facet_counts->facet_fields->$delta->{$term->tid}; + $countsort = $count == 0 ? '' : 1 / $count; + $countsort = $query->has_filter('tid', $term->tid) ? $countsort : 1 + $countsort; + $sort_key .= ($sort_key ? '|' : '') . $countsort . ':' . $term->name; + } + $terms[$term->vid][$sort_key] = theme('apachesolr_facet_item', $term->name, $count, $path, $querystring, $active, $unclick_link, $response->response->numFound, array()); + } } - $countsort = $count == 0 ? '' : 1 / $count; - // if numdocs == 1 and !active, don't add. - if ($response->response->numFound > 1 || $active) { - $terms[$term->vid][$active ? $countsort . $term->name : 1 + $countsort . $term->name] = theme('apachesolr_facet_item', $term->name, $count, $path, $querystring, $active, $unclick_link, $response->response->numFound); + + // Process all terms into an item list + if (is_array($terms) && isset($terms[$vid]) && is_array($terms[$vid])) { + + // Create array of nested items + $items = _apachesolr_search_nested_facet_items($terms[$vid]); + + $limit = isset($initial_limits['apachesolr_search'][$delta]) ? $initial_limits['apachesolr_search'][$delta] : $limit_default; + return array( + 'subject' => t('Filter by @name', array('@name' => $vocab->name)), + 'content' => theme('apachesolr_facet_list', $items, $limit), + ); } } } - $vid = substr($delta, 7); - $vocab = taxonomy_vocabulary_load($vid); - if (is_numeric($vid) && is_array($terms) && isset($terms[$vid]) && is_array($terms[$vid])) { - ksort($terms[$vid]); - $limit = isset($initial_limits['apachesolr_search'][$delta]) ? $initial_limits['apachesolr_search'][$delta] : $limit_default; - return array( - 'subject' => t('Filter by @name', array('@name' => $vocab->name)), - 'content' => theme('apachesolr_facet_list', $terms[$vid], $limit), - ); - } return; } @@ -519,11 +545,14 @@ $links[] = apachesolr_l($query->get_query_basic(), $path, $options); foreach($fields as $field) { if ($field['#name']) { - $new_query = clone $query; - $new_query->remove_filter($field['#name'], $field['#value']); - $path = $new_query->get_path(); - $querystring = $new_query->get_url_querystring(); - $unclick_link = theme('apachesolr_unclick_link', $path, $querystring); + $vid = FALSE; + if (module_exists('taxonomy') && 'tid' == $field['#name']) { + $term = taxonomy_get_term($field['#value']); + if ($reflect_hierarchy['apachesolr_search']['im_vid_'.$term->vid]) { + $vid = $term->vid; + } + } + $unclick_link = apachesolr_get_unclick_link($query, $field['#name'], $field['#value'], $vid); if (! $fielddisplay = theme("apachesolr_breadcrumb_". $field['#name'], $field['#value'])) { $fielddisplay = $field['#value']; } @@ -573,6 +602,30 @@ } } +function apachesolr_get_unclick_link(&$query, $field_name, $field_value, $vid = FALSE) { + static $unclick_links = array(); + + if (empty($unclick_links[$field_name][$field_value])) { + $new_query = clone $query; + + $new_query->remove_filter($field_name, $field_value); + + if ($vid && 'tid' == $field_name) { + $childs = taxonomy_get_tree($vid, $field_value); + foreach ($childs as $child) { + $new_query->remove_filter('tid', $child->tid); + } + } + + $path = 'search/' . arg(1) . '/' . $new_query->get_query_basic(); + $querystring = $new_query->get_url_querystring(); + + $unclick_links[$field_name][$field_value] = theme('apachesolr_unclick_link', $path, $querystring); + } + + return $unclick_links[$field_name][$field_value]; +} + /** * Callback function for the 'Filter by book' facet block. */ @@ -777,3 +830,24 @@ function theme_apachesolr_search_snippets($doc, $snippets) { return implode(' ... ', $snippets); } + +/** + * Return nested array of nested facet values for use with theme_item_list() + */ +function _apachesolr_search_nested_facet_items($input, $parent = '', $level = 0) { + if ($level == 0) { + ksort($input); + } + $result = array(); + foreach ($input as $key => $item) { + // For items on current level, and their $key is son of $parent + if (substr_count($key, "|") == $level && ($parent == '' || strpos($key, $parent) === 0)) { + // Add this item and all items on next level + $result[$key] = array( + 'data' => $item, + 'children' => _apachesolr_search_nested_facet_items($input, $key, $level+1) + ); + } + } + return $result; +}