? SolrPhpClient Index: Solr_Base_Query.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/Solr_Base_Query.php,v retrieving revision 1.1.4.40.2.10 diff -u -p -r1.1.4.40.2.10 Solr_Base_Query.php --- Solr_Base_Query.php 26 Dec 2009 13:08:51 -0000 1.1.4.40.2.10 +++ Solr_Base_Query.php 13 Feb 2010 18:17:32 -0000 @@ -409,7 +409,6 @@ class Solr_Base_Query implements Drupal_ // Gets information about the fields already in solr index. $index_fields = $this->solr->getFields(); - foreach ((array) $index_fields as $name => $data) { // Look for a field alias. $alias = isset($this->field_map[$name]) ? $this->field_map[$name] : $name; Index: apachesolr.admin.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.admin.inc,v retrieving revision 1.1.2.28.2.23 diff -u -p -r1.1.2.28.2.23 apachesolr.admin.inc --- apachesolr.admin.inc 27 Dec 2009 17:29:34 -0000 1.1.2.28.2.23 +++ apachesolr.admin.inc 13 Feb 2010 18:17:32 -0000 @@ -249,6 +249,9 @@ function apachesolr_enabled_facets_form_ foreach ($form_state['values']['apachesolr_enabled_facets'] as $module => $facets) { $enabled[$module] = array_filter($facets); } + // This cache being stale can prevent new facet filters from working. + $solr = apachesolr_get_solr(); + $solr->clearCache(); variable_set('apachesolr_enabled_facets', $enabled); drupal_set_message($form_state['values']['submit_message'], 'warning'); } @@ -265,9 +268,12 @@ function apachesolr_enabled_facets_form( $module_facets = array(); $module_list = array(); foreach (module_implements('apachesolr_facets') as $module) { - $module_facets[$module] = module_invoke($module, 'apachesolr_facets'); - uasort($module_facets[$module], 'apachesolr_sort_facets'); - $module_list[$module] = $module; + $return = module_invoke($module, 'apachesolr_facets'); + if (!empty($return)) { + $module_facets[$module] = $return; + uasort($module_facets[$module], 'apachesolr_sort_facets'); + $module_list[$module] = $module; + } } $enabled_facets = apachesolr_get_enabled_facets(); @@ -284,6 +290,7 @@ function apachesolr_enabled_facets_form( } } foreach($module_facets as $module => $facets) { + $form['apachesolr_enabled_facets'][$module] = array( '#type' => 'fieldset', '#title' => check_plain($module_list[$module]['name']), @@ -381,8 +388,8 @@ function apachesolr_clear_index_submit($ $form_state['redirect'] = 'admin/settings/apachesolr/index/batch/confirm'; } else { - $form_state['redirect'] = 'admin/settings/apachesolr/index/clear/confirm'; -} + $form_state['redirect'] = 'admin/settings/apachesolr/index/clear/confirm'; + } } /** Index: apachesolr.index.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.index.inc,v retrieving revision 1.1.2.6.2.18 diff -u -p -r1.1.2.6.2.18 apachesolr.index.inc --- apachesolr.index.inc 2 Jan 2010 23:44:04 -0000 1.1.2.6.2.18 +++ apachesolr.index.inc 13 Feb 2010 18:17:32 -0000 @@ -110,43 +110,55 @@ function apachesolr_node_to_document($no // Get CCK fields list $cck_fields = apachesolr_cck_fields(); + // NOTE: One CCK field might result in multiple Solr fields. foreach ($cck_fields as $key => $cck_info) { if (isset($node->$key)) { // Got a CCK field. See if it is to be indexed. $function = $cck_info['indexing_callback']; + $fields = NULL; if ($cck_info['indexing_callback'] && function_exists($function)) { - $field = $function($node, $key); + // NOTE: This function should always return an array. + $fields = $function($node, $key, $cck_info); } - else { - $field = $node->$key; - } - $index_key = apachesolr_index_key($cck_info); - if (is_array($field)) { - foreach ($field as $value) { + // NOTE: By commenting this I'm making it so there is no default $fields. + // Only when there is an indexing_callback in the cck_info will + // this CCK field get indexed. + //else { + // $fields = $node->$key; + //} + // NOTE: This is now being done in the mandatory indexing callback. + // $index_key = apachesolr_index_key($cck_info); + if (is_array($fields)) { + // NOTE: If this were done as $key => $value, and the $index_key were + // done within the loop, could we support indexing one CCK field to + // multiple Solr fields? + foreach ($fields as $field) { // Don't index NULLs or empty strings // We can use 'value' rather than 'safe' since we strip tags and later check_plain(). // Furthermore, what is being indexed is the KEY for the CCK value. It will need // a trip through content_format() later to display the value. - switch ($cck_info['field_type']) { - case 'nodereference': - $index_value = (isset($value['nid']) && strlen($value['nid'])) ? $value['nid'] : FALSE; - break; - - case 'userreference': - $index_value = (isset($value['uid']) && strlen($value['uid'])) ? $value['uid'] : FALSE; - break; - - default: - $index_value = (isset($value['value']) && strlen($value['value'])) ? $value['value'] : FALSE; - break; + //switch ($cck_info['field_type']) { + // // NOTE: It seems like it would be cleaner to give these all + // // indexing callbacks and then let the callback generate the + // // $index_value. + // case 'nodereference': + // $index_value = (isset($value['nid']) && strlen($value['nid'])) ? $value['nid'] : FALSE; + // break; + // + // case 'userreference': + // $index_value = (isset($value['uid']) && strlen($value['uid'])) ? $value['uid'] : FALSE; + // break; + // + // default: + // $index_value = (isset($value['value']) && strlen($value['value'])) ? $value['value'] : FALSE; + // break; + //} + + if ($cck_info['multiple']) { + $document->setMultiValue($field['key'], apachesolr_clean_text($field['value'])); } - if ($index_value) { - if ($cck_info['multiple']) { - $document->setMultiValue($index_key, apachesolr_clean_text($index_value)); - } - else { - $document->$index_key = apachesolr_clean_text($index_value); - } + else { + $document->{$field['key']} = apachesolr_clean_text($field['value']); } } } @@ -169,6 +181,38 @@ function apachesolr_node_to_document($no return $document; } +function apachesolr_cck_nodereference_indexing_callback($node, $field_name, $cck_info) { + $fields = array(); + if (isset($node->{$field_name})) { + $index_key = apachesolr_index_key($cck_info); + foreach ($node->$field_name as $field) { + if ($index_value = (isset($field['nid']) && strlen($field['nid'])) ? $field['nid'] : FALSE) { + $fields[] = array( + 'key' => $index_key, + 'value' => $index_value, + ); + } + } + } + return $fields; +} + +function apachesolr_cck_userreference_indexing_callback($node, $field_name, $cck_info) { + $fields = array(); + if (isset($node->$field_name)) { + $index_key = apachesolr_index_key($cck_info); + foreach ($node->{$field_name} as $field) { + if ($index_value = (isset($field['uid']) && strlen($field['uid'])) ? $field['uid'] : FALSE) { + $fields[] = array( + 'key' => $index_key, + 'value' => $index_value, + ); + } + } + } + return $fields; +} + /** * Extract taxonomy from $node and add to dynamic fields. */ @@ -251,7 +295,7 @@ function apachesolr_add_tags_to_document /** * Additional index utility functions */ - + /** * hook_cron() helper to try to make {apachesolr_search_node} consistent with {node}. */ @@ -303,7 +347,7 @@ function apachesolr_cron_check_node_tabl } } } - + function apachesolr_nodeapi_mass_update($nodes) { if (empty($nodes)) { return TRUE; @@ -330,7 +374,7 @@ function apachesolr_nodeapi_mass_update( return FALSE; } } - + function apachesolr_nodeapi_mass_delete($nodes) { if (empty($nodes)) { return TRUE; @@ -354,4 +398,3 @@ function apachesolr_nodeapi_mass_delete( return FALSE; } } - Index: apachesolr.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr.module,v retrieving revision 1.1.2.12.2.155.2.57 diff -u -p -r1.1.2.12.2.155.2.57 apachesolr.module --- apachesolr.module 2 Jan 2010 14:42:58 -0000 1.1.2.12.2.155.2.57 +++ apachesolr.module 13 Feb 2010 18:17:33 -0000 @@ -280,6 +280,7 @@ function apachesolr_rebuild_index_table( db_query("UPDATE {apachesolr_search_node} SET changed = %d WHERE changed > %d", $time, $time); apachesolr_clear_last_index(); } + cache_clear_all('*', 'cache_apachesolr', TRUE); } function apachesolr_exclude_types($namespace) { @@ -744,10 +745,12 @@ function apachesolr_get_facet_definition $operator_settings = variable_get('apachesolr_operator', array()); foreach (module_implements('apachesolr_facets') as $module) { $facets = module_invoke($module, 'apachesolr_facets'); - foreach ($facets as $delta => $info) { - $definitions[$module][$delta] = $info; - if(isset($definitions[$module][$delta])) { - $definitions[$module][$delta]['operator'] = isset($operator_settings[$module][$delta]) ? $operator_settings[$module][$delta] : 'AND'; + if (!empty($facets)) { + foreach ($facets as $delta => $info) { + $definitions[$module][$delta] = $info; + if(isset($definitions[$module][$delta])) { + $definitions[$module][$delta]['operator'] = isset($operator_settings[$module][$delta]) ? $operator_settings[$module][$delta] : 'AND'; + } } } } @@ -756,6 +759,24 @@ function apachesolr_get_facet_definition } /** + * Returns a member of the facet definitions array if it contains + * $field as the 'field_name' element. + * + * @param string $field + * The field_name being sought. + */ +function apachesolr_get_facet_definition_by_field($field) { + $definitions = apachesolr_get_facet_definitions(); + foreach ($definitions as $module => $facets) { + foreach ($facets as $key => $values) { + if ($facet = array_search($field, $values)) { + return $definitions[$module][$key]; + } + } + } +} + +/** * Implementation of hook_form_[form_id]_alter(). * * Hide the core 'title' field in favor of our 'name' field. @@ -1145,7 +1166,7 @@ function apachesolr_facetcount_form($mod '#description' => t('The maximum number of filter links to show in this block.'), '#default_value' => isset($limits[$module][$delta]) ? $limits[$module][$delta] : variable_get('apachesolr_facet_query_limit_default', 20), ); - + // TODO: Generalize how we know what type a facet block is by putting field // type into the facet definition. 'created' and 'changed' are date blocks. if ($delta != 'created' && $delta != 'changed') { @@ -1406,7 +1427,7 @@ function apachesolr_static_response_cach function apachesolr_drupal_query($keys = '', $filters = '', $solrsort = '', $base_path = '', $solr = NULL) { list($module, $class) = variable_get('apachesolr_query_class', array('apachesolr', 'Solr_Base_Query')); include_once drupal_get_path('module', $module) .'/'. $class .'.php'; - + if (empty($solr)) { $solr = apachesolr_get_solr(); } @@ -1546,14 +1567,17 @@ function apachesolr_cck_fields() { $mappings['nodereference'] = array( 'nodereference_buttons' => array( 'display_callback' => 'apachesolr_cck_nodereference_field_callback', + 'indexing_callback' => 'apachesolr_cck_nodereference_indexing_callback', 'index_type' => 'integer', ), 'nodereference_select' => array( 'display_callback' => 'apachesolr_cck_nodereference_field_callback', + 'indexing_callback' => 'apachesolr_cck_nodereference_indexing_callback', 'index_type' => 'integer', ), 'nodereference_autocomplete' => array( 'display_callback' => 'apachesolr_cck_nodereference_field_callback', + 'indexing_callback' => 'apachesolr_cck_nodereference_indexing_callback', 'index_type' => 'integer', ), ); @@ -1564,10 +1588,12 @@ function apachesolr_cck_fields() { ), 'userreference_select' => array( 'display_callback' => 'apachesolr_cck_userreference_field_callback', + 'indexing_callback' => 'apachesolr_cck_userreference_indexing_callback', 'index_type' => 'integer', ), 'userreference_autocomplete' => array( 'display_callback' => 'apachesolr_cck_userreference_field_callback', + 'indexing_callback' => 'apachesolr_cck_userreference_indexing_callback', 'index_type' => 'integer', ), ); @@ -1579,20 +1605,21 @@ function apachesolr_cck_fields() { // Only deal with fields that have option widgets (facets don't make sense otherwise), or fields that have specific mappings. if ((isset($mappings[$row->field_type][$row->widget_type]) || isset($mappings['per-field'][$row->field_name]))) { if (isset($mappings['per-field'][$row->field_name])) { - $fields[$row->field_name] = $mappings['per-field'][$row->field_name]; - $row->index_type = $mappings['per-field'][$row->field_name]['index_type']; - $row->indexing_callback = $mappings['per-field'][$row->field_name]['indexing_callback']; - $row->display_callback = $mappings['per-field'][$row->field_name]['display_callback']; + $field = $mappings['per-field'][$row->field_name]; + $fields[$row->field_name] = $field; } else { - $row->index_type = $mappings[$row->field_type][$row->widget_type]['index_type']; - $row->indexing_callback = $mappings[$row->field_type][$row->widget_type]['indexing_callback']; - $row->display_callback = $mappings[$row->field_type][$row->widget_type]['display_callback']; + $field = $mappings[$row->field_type][$row->widget_type]; } - $row->multiple = (bool) $row->multiple; // It's important that we put the 'cck_' here because several points in the later processing // depend on it to route program flow to cck specific handlers. - $row->name = 'cck_' . $row->field_name; + $row->name = 'cck_' . $row->field_name; + $row->index_type = $field['index_type']; + $row->indexing_callback = $field['indexing_callback']; + $row->display_callback = $field['display_callback']; + $row->facet_block_callback = $field['facet_block_callback']; + $row->multiple = (bool) $row->multiple; + $fields[$row->field_name] = array_merge((array) $fields[$row->field_name], (array) $row); $fields[$row->field_name]['content_types'][] = $row->content_type; unset($fields[$row->field_name]['content_type']); @@ -1605,6 +1632,15 @@ function apachesolr_cck_fields() { } /** + * Implementation of hook_content_fieldapi + */ +function apachesolr_content_fieldapi($op) { + if ($op == 'update instance') { + cache_clear_all('*', 'cache_apachesolr', TRUE); + } +} + +/** * Use the content.module's content_format() to format the * field based on its value ($facet). * @@ -1739,7 +1775,7 @@ function apachesolr_mlt_suggestions($set } } $query = apachesolr_drupal_query('id:' . $id); - + $type_filters = array(); if (is_array($settings['mlt_type_filters'])) { foreach ($settings['mlt_type_filters'] as $type_filter) { Index: apachesolr_search.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/apachesolr_search.module,v retrieving revision 1.1.2.6.2.111.2.45 diff -u -p -r1.1.2.6.2.111.2.45 apachesolr_search.module --- apachesolr_search.module 4 Jan 2010 14:27:56 -0000 1.1.2.6.2.111.2.45 +++ apachesolr_search.module 13 Feb 2010 18:17:33 -0000 @@ -1,5 +1,5 @@ facet_counts->facet_fields->$facet_field) > 0) { + if (count((array)$response->facet_counts->facet_fields->$facet_field) > 0 || + count((array)$response->facet_counts->facet_dates->$facet_field) > 0) { // This bit is modeled on block.modul, block_list(). $result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta @@ -385,6 +386,7 @@ function apachesolr_search_execute($keys return apachesolr_search_process_response($response, $query, $params); } +// NOTE: Why does this take the $query object? function apachesolr_search_basic_params($query) { $params = array( 'fl' => 'id,nid,title,comment_count,type,created,changed,score,path,url,uid,name', @@ -436,7 +438,17 @@ function apachesolr_search_add_facet_par if (apachesolr_block_visibility($query, $module, $delta)) { // TODO: generalize handling of date and range facets. // TODO: put field type in the facet definitions. - if ($module == 'apachesolr_search' && ($facet_field == 'created' || $facet_field == 'changed')) { + // NOTE: This is a dependency on the apachesolr_date module. Using function_exists to avoid problems. + if (strpos($facet_field, 'cck_field_date') && function_exists('apachesolr_date_search_date_range')) { + list($start, $end, $gap) = apachesolr_date_search_date_range($query, $facet_field); + if ($gap) { + $params['facet.date'][] = $facet_field; + $params['f.'. $facet_field .'.facet.date.start'] = $start; + $params['f.'. $facet_field .'.facet.date.end'] = $end; + $params['f.'. $facet_field .'.facet.date.gap'] = $gap; + } + } + else if ($module == 'apachesolr_search' && ($facet_field == 'created' || $facet_field == 'changed')) { list($start, $end, $gap) = apachesolr_search_date_range($query, $facet_field); if ($gap) { $params['facet.date'][] = $facet_field; @@ -698,10 +710,11 @@ function apachesolr_search_apachesolr_fa foreach ($fields as $name => $field) { // $delta can only be 32 chars, and the CCK field name may be this // long also, so we cannot add anything to it. - $facets[$field['field_name']] = array( - 'info' => t('CCK @field_type field: Filter by @field', array('@field_type' => $field['field_type'], '@field' => $field['label'])), - 'facet_field' => apachesolr_index_key($field), - 'content_types' => $field['content_types'], + $facets[$field['field_name']] = array_merge($field, array( + 'info' => t('CCK @field_type field: Filter by @field', array('@field_type' => $field['field_type'], '@field' => $field['label'])), + 'facet_field' => apachesolr_index_key($field), + 'content_types' => $field['content_types'], + ) ); } } @@ -712,7 +725,6 @@ function apachesolr_search_apachesolr_fa * Implementation of hook_block(). */ function apachesolr_search_block($op = 'list', $delta = 0, $edit = array()) { - switch ($op) { case 'list': $enabled_facets = apachesolr_get_enabled_facets('apachesolr_search'); @@ -770,12 +782,16 @@ function apachesolr_search_block($op = ' return apachesolr_date_facet_block($response, $query, 'apachesolr_search', $delta, $delta, t('Filter by post date')); default: + if ($fields = apachesolr_cck_fields()) { + foreach ($fields as $name => $field) { + if ($field['field_name'] == $delta) { $index_key = apachesolr_index_key($field); $callback = isset($field['display_callback']) ? $field['display_callback'] : FALSE; - return apachesolr_facet_block($response, $query, 'apachesolr_search', $delta, $index_key, t('Filter by @field', array('@field' => $field['label'])), $callback); + $block_function = (isset($field['facet_block_callback']) && function_exists($field['facet_block_callback'])) ? $field['facet_block_callback'] : 'apachesolr_facet_block'; + return $block_function($response, $query, 'apachesolr_search', $delta, $index_key, t('Filter by @field', array('@field' => $field['label'])), $callback); } } } @@ -889,10 +905,6 @@ function apachesolr_search_taxonomy_face $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)) { - // Get information needed by the taxonomy blocks about limits. - $initial_limits = variable_get('apachesolr_facet_query_initial_limits', array()); - $limit_default = variable_get('apachesolr_facet_query_initial_limit_default', 10); - $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)), @@ -946,10 +958,18 @@ function apachesolr_search_language_name * 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, $field['#exclude']); + $facet_definition = apachesolr_get_facet_definition_by_field($field['#name']); + if (isset($facet_definition['display_callback'])) { + $function = $facet_definition['display_callback']; + if (function_exists($function)) { + $facet_text = $function($field['#value'], $field); + } + } + if (!$facet_text) { + $facet_text = theme('apachesolr_breadcrumb_' . $field['#name'], $field, $field['#exclude']); + } if (!$facet_text) { $facet_text = $field['#value']; } @@ -1297,15 +1317,30 @@ function apachesolr_search_apachesolr_th } } +/** + * Theme function for CCK fields in breadcrumbs. + * TODO: The logic for getting here is too convoluted, and + * there are too many bizarre naming conventions in play (_cck_, _end). + * The checks for _cck_ and _end MUST get refactored. + */ function theme_apachesolr_breadcrumb_cck($field) { $matches = preg_split('/_cck_/', $field['#name']); if (isset($matches[1])) { + $match = $matches[1]; + + // TODO: If the apachesolr_date module is present we might + // have fields with the suffix '_end'. These are the end-dates + // and need the suffix removed. + if (module_exists('apachesolr_date')) { + $match = preg_replace('/_end{1}$/', '', $match); + } + $mappings = apachesolr_cck_fields(); - if (isset($mappings[$matches[1]]['display_callback'])) { - $function = $mappings[$matches[1]]['display_callback']; + if (isset($mappings[$match]['display_callback'])) { + $function = $mappings[$match]['display_callback']; if (function_exists($function)) { $facet = $field['#value']; - $options = array('delta' => $matches[1]); + $options = array_merge($mappings[$match], array('delta' => $matches[1])); return $function($facet, $options); } } @@ -1416,7 +1451,6 @@ function apacehsolr_get_parent_terms($ti 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())); Index: contrib/apachesolr_commentsearch/apachesolr_commentsearch.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/apachesolr/contrib/apachesolr_commentsearch/Attic/apachesolr_commentsearch.module,v retrieving revision 1.1.2.8 diff -u -p -r1.1.2.8 apachesolr_commentsearch.module --- contrib/apachesolr_commentsearch/apachesolr_commentsearch.module 4 Jan 2010 13:38:53 -0000 1.1.2.8 +++ contrib/apachesolr_commentsearch/apachesolr_commentsearch.module 13 Feb 2010 18:17:33 -0000 @@ -94,7 +94,14 @@ function apachesolr_commentsearch_apache } function apachesolr_commentsearch_apachesolr_theme_breadcrumb_alter(&$breadcrumb_name) { - $breadcrumb_name = 'apachesolr_commentsearch_breadcrumb_type'; + // While the goal here is to hijack nearly every breadcrumb generation, we + // can't do it if it's a ckk facet. That would step on the toes of + // date facets, etc. So reverse the logic from apachesolr_search_apachesolr_theme_breadcrumb_alter + // and only alter non-cck breadcrumbs. + $matches = preg_split('/_cck_/', $fieldname); + if (!empty($matches[1])) { + $breadcrumb_name = 'apachesolr_commentsearch_breadcrumb_type'; + } } function apachesolr_commentsearch_comment(&$a1, $op) {