? SolrPhpClient ? Zend ? entity-type-348668-27.patch ? taxo-new-401234-134.patch ? taxo-new-401234-143.patch ? taxo-new-401234-145.patch ? text-analyzer.xml ? update-schema-641954-5.patch Index: Solr_Base_Query.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Solr_Base_Query.php,v retrieving revision 1.1.4.43 diff -u -p -r1.1.4.43 Solr_Base_Query.php --- Solr_Base_Query.php 14 Oct 2009 13:28:40 -0000 1.1.4.43 +++ Solr_Base_Query.php 1 Dec 2009 17:10:09 -0000 @@ -332,7 +332,7 @@ class Solr_Base_Query implements Drupal_ * Optional. When set, this string overrides the query's current keywords. */ public function get_path($new_keywords = NULL) { - if ($new_keywords) { + if (isset($new_keywords)) { return $this->base_path . '/' . $new_keywords; } return $this->base_path . '/' . $this->get_query_basic(); Index: apachesolr.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v retrieving revision 1.1.2.12.2.173 diff -u -p -r1.1.2.12.2.173 apachesolr.module --- apachesolr.module 25 Nov 2009 15:22:09 -0000 1.1.2.12.2.173 +++ apachesolr.module 1 Dec 2009 17:10:10 -0000 @@ -714,7 +714,7 @@ function apachesolr_facet_block($respons else { $new_query->add_filter($facet_field, $facet, $exclude); $options['query'] = $new_query->get_url_queryvalues(); - $link = theme('apachesolr_facet_link', $facet_text, $new_query->get_path(), $options, $count, $active, $response->response->numFound); + $link = theme('apachesolr_facet_link', $facet_text, $new_query->get_path(), $options, $count, FALSE, $response->response->numFound); } if ($count || $active) { $items[$sortpre . '*' . $facet_text] = $link; @@ -1470,8 +1470,11 @@ function theme_apachesolr_facet_list($it 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) { + if (!is_array($hidden_item)) { + $hidden_item = array('data' => $hidden_item); + } + $items[] = $hidden_item + array('class' => 'apachesolr-hidden-facet'); } } $admin_link = ''; Index: apachesolr_search.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v retrieving revision 1.1.2.6.2.119 diff -u -p -r1.1.2.6.2.119 apachesolr_search.module --- apachesolr_search.module 20 Nov 2009 17:19:05 -0000 1.1.2.6.2.119 +++ apachesolr_search.module 1 Dec 2009 17:10:10 -0000 @@ -575,79 +575,13 @@ function apachesolr_search_block($op = ' $limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10); // 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(); - - foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) { - $options = array(); - 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); - $options['query'] = $new_query->get_url_queryvalues(); - $link = theme('apachesolr_unclick_link', $term->name, $new_query->get_path(), $options); - } - else { - $new_query->add_filter('tid', $term->tid); - $options['query'] = $new_query->get_url_queryvalues(); - $link = theme('apachesolr_facet_link', $term->name, $new_query->get_path(), $options, $count, $active, $response->response->numFound); - } - $countsort = $count == 0 ? '' : 1 / $count; - $countsort += .000001; - $countsort = number_format($countsort, 6); - - // 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] = $link; - } - } - } - $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; + if ((strpos($delta, 'im_vid_') === 0)) { + return apachesolr_search_taxonomy_facet_block($response, $query, $delta); } switch ($delta) { case 'currentsearch': - $fields = $query->get_filters(); - $path = $query->get_path(); - $options = array(); - if (!$fields) { - $options['attributes']['class'] = 'active'; - } - $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']); - $options['query'] = $new_query->get_url_queryvalues(); - $fielddisplay = theme("apachesolr_breadcrumb_". $field['#name'], $field['#value']); - if (!$fielddisplay) { - $fielddisplay = $field['#value']; - } - $links[] = theme('apachesolr_unclick_link', $fielddisplay, $new_query->get_path(), $options); - } - } - $content = theme('apachesolr_currentsearch', $response->response->numFound, $links); - return array('subject' => t('Current search'), 'content' => $content); + return apachesolr_search_currentsearch_block($response, $query); case 'is_book_bid': return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by book'), 'apachesolr_search_get_book'); case 'language': @@ -690,6 +624,88 @@ function apachesolr_search_block($op = ' } /** + * Generate a list including the field and all its children. + */ +function apachesolr_search_collect_children($field) { + $remove[] = $field; + if (!empty($field['#children'])) { + foreach ($field['#children'] as $child_field) { + $remove = array_merge($remove, apachesolr_search_collect_children($child_field)); + } + } + return $remove; +} + +/** + * Generate the facet block for a taxonomy vid delta. + */ +function apachesolr_search_taxonomy_facet_block($response, $query, $delta) { + $vid = substr($delta, 7); + if (!module_exists('taxonomy') || !is_numeric($vid)) { + return; + } + + // Check that we have a response and a valid vid. + if (is_object($response->facet_counts->facet_fields->$delta) && ($vocab = taxonomy_vocabulary_load($vid))) { + $reflect_hierarchy = apachesolr_search_get_hierarchical_vocabularies(); + $contains_active = FALSE; + $facets = array(); + + foreach ($response->facet_counts->facet_fields->$delta as $tid => $count) { + // TODO - for now we don't handle facet missing. + if ($tid != '_empty_') { + $active = $query->has_filter('tid', $tid); + if ($active) { + $contains_active = TRUE; + } + $facets[$tid] = array( + '#name' => 'tid', + '#value' => $tid, + '#count' => $count, + '#parent' => 0, + '#children' => array(), + '#has_children' => FALSE, + '#active' => $active, + ); + } + } + + if ($facets && $reflect_hierarchy[$vocab->vid]) { + $placeholders = db_placeholders($facets); + $tids = array_keys($facets); + $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE parent > 0 AND (tid IN ($placeholders) OR parent IN ($placeholders))", array_merge($tids, $tids)); + while ($term = db_fetch_object($result)) { + // Mark all terms that are parents for later CSS class. + if (isset($facets[$term->parent])) { + $facets[$term->parent]['#has_children'] = TRUE; + if (isset($facets[$term->tid])) { + $facets[$term->tid]['#parent'] = $term->parent; + // Use a reference so we see the updated data. + $facets[$term->parent]['#children'][] = &$facets[$term->tid]; + } + } + } + foreach ($facets as $tid => $field) { + if (!empty($field['#parent'])) { + // We will render it via its parent. + unset($facets[$tid]); + } + } + } + + $items = apachesolr_search_nested_facet_items($query, $facets, $response->response->numFound); + // Process all terms into an item list + if ($items && ($response->response->numFound > 1 || $contains_active)) { + $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), + ); + } + } +} + +/** * Callback function for the 'Filter by book' facet block. */ function apachesolr_search_get_book($facet, &$options) { @@ -703,6 +719,63 @@ function apachesolr_search_get_book($fac } /** + * Recursive function that returns a nested array of facet values for use with + * theme_item_list(). + * + * @param $query + * The current Solr query. + * @param $facets + * Array of facet items to prepare for rendering, possibly as nested lists. + * @param $num_found + * The number of documents in the current response. + * @param $sort + * If true, the returned list will be sorted based on the count of each + * facets, it's text representation and wither it's active. If false, + * the facets will be returned in the order they were received. + */ +function apachesolr_search_nested_facet_items($query, $facets, $num_found, $sort = TRUE) { + + $items = array(); + foreach($facets as $field) { + $facet_text = theme('apachesolr_breadcrumb_' . $field['#name'], $field['#value']); + if (!$facet_text) { + $facet_text = $field['#value']; + } + $link = array(); + $new_query = clone $query; + if (!empty($field['#active'])) { + // '*' sorts before all numbers. + $sortpre = '*'; + foreach (apachesolr_search_collect_children($field) as $child) { + $new_query->remove_filter($child['#name'], $child['#value']); + } + $options['query'] = $new_query->get_url_queryvalues(); + $link['data'] = theme('apachesolr_unclick_link', $facet_text, $new_query->get_path(), $options); + } + else { + $sortpre = 1000000 - $field['#count']; + $new_query->add_filter($field['#name'], $field['#value']); + $options = array('query' => $new_query->get_url_queryvalues()); + $link['data'] = theme('apachesolr_facet_link', $facet_text, $new_query->get_path(), $options, $field['#count'], FALSE, $num_found); + } + // We don't display children unless the parent is clicked. + if (!empty($field['#children']) && $field['#active'] == TRUE) { + $link['children'] = apachesolr_search_nested_facet_items($query, $field['#children'], $num_found, $sort); + $link['class'] = "expanded-facet"; + } + elseif (!empty($field['#has_children'])) { + $link['class'] = "collapsed"; + } + $items[$sortpre . '*' . $facet_text . $field['#name'] . $field['#value']] = $link; + } + + if ($sort) { + ksort($items); + } + return array_values($items); +} + +/** * Callback function for the 'Filter by name' facet block. */ function apachesolr_search_get_username($facet) { @@ -996,11 +1069,15 @@ function theme_apachesolr_breadcrumb_uid } /** - * Return the term name from $tid. + * Return the term name from $tid, or $tid as a fallback. */ function theme_apachesolr_breadcrumb_tid($tid) { - $term = taxonomy_get_term($tid); - return $term->name; + if (function_exists('taxonomy_get_term')) { + if ($term = taxonomy_get_term($tid)) { + return $term->name; + } + } + return $tid; } /** @@ -1040,3 +1117,85 @@ function theme_apachesolr_search_snippet return implode(' ... ', $snippets) .' ...'; } +/** + * Return the contents of the "Current search" block. + * + * @param $response + * The Solr response object. + * @param $query + * The Solr query object. + */ +function apachesolr_search_currentsearch_block($response, $query) { + $fields = $query->get_filters(); + $links = array(); + + // If current search has keys, offer current search without them + if ($keys = $query->get_query_basic()) { + $links[] = theme('apachesolr_unclick_link', $keys, $query->get_path(''), array('query' => $query->get_url_queryvalues())); + } + // Find all taxonomy terms to be treated in a hierarchy. + if (module_exists('taxonomy')) { + $reflect_hierarchy = apachesolr_search_get_hierarchical_vocabularies(); + foreach($fields as $index => $field) { + if ($field['#name'] && 'tid' == $field['#name']) { + $term = taxonomy_get_term($field['#value']); + if ($reflect_hierarchy[$term->vid]) { + $fields[$index] += array('#parent' => 0, '#children' => array()); + // Just save the index for later lookup. + $facets[$term->tid] = $index; + } + } + } + if ($facets) { + // Get all term hierarchy information. + $result = db_query("SELECT tid, parent FROM {term_hierarchy} WHERE tid IN (". db_placeholders($facets) .")", array_keys($facets)); + while ($term = db_fetch_object($result)) { + $index = $facets[$term->tid]; + if (isset($facets[$term->parent])) { + // Use a reference so we see the updated data. + $fields[$facets[$term->parent]]['#children'][] = &$fields[$index]; + $fields[$index]['#parent'] = $term->parent; + } + } + } + } + + // We don't directly render any items with a parent. + foreach($fields as $index => $field) { + $fields[$index]['#active'] = TRUE; + if (!empty($fields[$index]['#parent']) || !$field['#name']) { + // We will render it via its parent. + unset($fields[$index]); + } + } + + $links = array_merge($links, apachesolr_search_nested_facet_items($query, $fields, $response->response->numFound, FALSE)); + if ($links) { + $content = theme('apachesolr_currentsearch', $response->response->numFound, $links); + return array('subject' => t('Current search'), 'content' => $content); + } +} + +/** + * Return an array of taxonomy facets that should be displayed hierarchically. + */ +function apachesolr_search_get_hierarchical_vocabularies() { + static $result; + + if (!isset($result)) { + $result = array(); + if (function_exists('taxonomy_get_vocabularies')) { + $vocabularies = taxonomy_get_vocabularies(); + $force_flat = variable_get('apachesolr_search_force_flat_vocabularies', array()); + foreach ($vocabularies as $voc) { + // If the vocabulary is not multiple-parent hierarchical and not + // freetagging and not designated to be forced to display flat. + if ($voc->hierarchy != 2 && $voc->tags != 1 && empty($force_flat[$voc->vid])) { + $result[$voc->vid] = 1; + } + } + } + } + + return $result; +} \ No newline at end of file