diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 83d21af..c038711 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,7 +1,6 @@ - - Apache Solr Search Integration 7.x-1.0-XXX, xxxx-xx-xx ------------------------------ +#1006994 by Nick_vh, wmostrey, pwolanin | webchick: Port Apache Solr Multisite Search to Drupal 7. #1006994 by wmostrey: Initial Drupal 7 port. Apache Solr Search Integration 6.x-1.0-RC1, xxxx-xx-xx diff --git a/README.txt b/README.txt index 8b13789..e689bac 100644 --- a/README.txt +++ b/README.txt @@ -1 +1,24 @@ +This module allows facetting to happen across multiple domains. + +1. Enable the module + +2. Enabling the environment +Enable the environment you want (eg.: select multisite support in +the settings) + +3. Existing facets +All your existing facets will still work but they are indexed using an ID. +The Solr module also indexed them using their name and this module already ships +with 3 default multisite enabled facets +- Tags +- Authors +- Content Types (Bundles) +It also ships with a facet to switch between the sites (Hash/Site) + +3. Custom Facets +Create a custom module that enables extra cross-site facets. In case of a +a custom vocabulary this will be named sm_vid_NAME. You can view all the fields +in solr by going to your Drupal reports and select Solr Search Index +Copy the apachesolr_multisitesearch_facetapi_facet_info into your module and +get started. diff --git a/apachesolr_multisitesearch.admin.inc b/apachesolr_multisitesearch.admin.inc index ce130fc..1e8349e 100644 --- a/apachesolr_multisitesearch.admin.inc +++ b/apachesolr_multisitesearch.admin.inc @@ -1,96 +1,6 @@ id = apachesolr_document_id(0, 'multisite_metadata'); - $document->site = url(NULL, array('absolute' => TRUE)); - $document->hash = apachesolr_site_hash(); - $document->entity_id = 1; - $document->entity_type = 'multisite_meta'; - $document->ss_multisite_meta_sitename = variable_get('site_name', 'Drupal'); - module_load_include('inc', 'apachesolr', 'apachesolr.index'); - if (module_exists('taxonomy')) { - $vocabs = taxonomy_get_vocabularies(); - foreach ($vocabs as $vid => $vocab) { - // We index each name as a string for cross-site faceting - // using the vocab name rather than vid in field construction. - $document->setMultiValue('sm_multisite_meta_taxonomy', apachesolr_vocab_name($vid)); - } - } - drupal_alter('apachesolr_multisitesearch_metadata', $document); - return $document; -} - -function apachesolr_multisitesearch_update_metadata() { - try { - // Get the $solr object - $solr = apachesolr_get_solr(); - $metadata_doc = apachesolr_multisitesearch_metadata(); - $solr->addDocuments(array($metadata_doc)); - $solr->commit(); - watchdog('Apache Solr Multisite', 'Updated site meta data'); - return TRUE; - } - catch (Exception $e) { - watchdog('Apache Solr Multisite', 'Indexing failed for meta data
!message', - array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); - } - return FALSE; -} - -function apachesolr_multisitesearch_get_metadata() { - try { - // Get the $solr object - $solr = apachesolr_get_solr(); - $params['qt'] = 'standard'; - $params['fl'] = '*'; - $response = $solr->search('entity_type:multisite_meta', $params); - foreach ($response->response->docs as $doc) { - // Convert doc into a simple array. - if (isset($doc->hash)) { - foreach ($doc as $k => $v) { - $data[$doc->hash][$k] = $v; - } - if (empty($data[$doc->hash]['sm_multisite_meta_taxonomy'])) { - $data[$doc->hash]['sm_multisite_meta_taxonomy'] = array(); - } - } - } - watchdog('Apache Solr Multisite', 'Fetched site meta data'); - variable_set('apachesolr_multisitesearch_metadata', $data); - } - catch (Exception $e) { - watchdog('Apache Solr Multisite', 'Failed to fetch meta data
!message', - array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); - } -} - -function apachesolr_multisitesearch_get_site_hashes() { - try { - // Get the $solr object - $solr = apachesolr_get_solr(); - $params['qt'] = 'standard'; - $params['fl'] = '*'; - $params['facet'] = 'true'; - $params['facet.field'][] = 'hash'; - $params['facet.mincount'] = 1; - $params['facet.limit'] = '1000'; - $response = $solr->search('*:*', $params); - $results = (array)$response->facet_counts->facet_fields->hash; - return $results; - } - catch (Exception $e) { - watchdog('Apache Solr Multisite', 'Failed to fetch hash facet count
!message', - array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); - } -} - -/** * Creates the form that allows the user to select which facets will be enabled. * * Only enabled facets are sent to solr. Fewer enabled facets can reduce the @@ -98,6 +8,7 @@ function apachesolr_multisitesearch_get_site_hashes() { * this also reduces the clutter on the blocks admin page. */ function apachesolr_multisitesearch_settings() { + module_load_include('inc', 'apachesolr_multisitesearch', 'apachesolr_multisitesearch.index'); $form = array(); $form['#tree'] = TRUE; $form['submit_message'] = array( @@ -114,7 +25,7 @@ function apachesolr_multisitesearch_settings() { '#prefix' => '

' . t('Multisite metadata is used to communicate between all of the sites in a multisite setup. If site names are not showing properly in the search results and facet blocks try refreshing the metadata. Metadata is also refreshed periodically on cron runs.') . '

', '#submit' => array('apachesolr_multisitesearch_refresh_metadata_now'), ); - + // Use the metadata and a list of all the hashes in the index // to build up checkboxes for deleting site indexes. // This is only necessary because sometimes hashes get @@ -134,7 +45,7 @@ function apachesolr_multisitesearch_settings() { $options[$hash] = $hash . ' ' . t('(!count documents)', array('!count' => $count)); } } - + if (count($options) > 0) { $form['admin']['delete']['hashes'] = array( '#type' => 'checkboxes', @@ -155,28 +66,31 @@ function apachesolr_multisitesearch_settings() { * Submit handler for the "Delete selected indexes" button. */ function apachesolr_multisitesearch_delete_indexes($form, &$form_state) { + module_load_include('inc', 'apachesolr_multisitesearch', 'apachesolr_multisitesearch.index'); // Instantiate a new Solr object. $solr = apachesolr_get_solr(); + $env_id = apachesolr_default_environment(); foreach ($form_state['values']['admin']['delete']['hashes'] as $hash) { if ($hash) { $query = "hash:$hash"; $solr->deleteByQuery($query); drupal_set_message(t('The index for !hash has been deleted.', array('!hash' => $hash))); if (apachesolr_site_hash() == $hash) { - // Rebuild our node-tracking table. - apachesolr_rebuild_index_table(); - apachesolr_index_set_last_updated(time()); + //Todo : we might want to execute apachesolr_node_check_index_table(); + apachesolr_set_last_index_updated($env_id, time()); } } } $solr->commit(); - apachesolr_multisitesearch_get_metadata(); + apachesolr_multisitesearch_retrieve_metadata(); } /** * Submit handler for the "Refresh metadata now" button. */ function apachesolr_multisitesearch_refresh_metadata_now() { + module_load_include('inc', 'apachesolr_multisitesearch', 'apachesolr_multisitesearch.index'); + // Delete all current variables and refresh them variable_del('apachesolr_multisitesearch_last_metadata_update'); variable_del('apachesolr_multisitesearch_last_metadata_fetch'); apachesolr_multisitesearch_refresh_metadata(); diff --git a/apachesolr_multisitesearch.index.inc b/apachesolr_multisitesearch.index.inc new file mode 100644 index 0000000..d4ad666 --- /dev/null +++ b/apachesolr_multisitesearch.index.inc @@ -0,0 +1,154 @@ + 60*60) { + if (apachesolr_multisitesearch_update_metadata()) { + variable_set('apachesolr_multisitesearch_last_metadata_update', $time); + } + } + if ($time - $last_fetch > 60*5) { + apachesolr_multisitesearch_retrieve_metadata(); + } + $env_id = apachesolr_default_environment(); + apachesolr_set_last_index_updated($env_id, $time); +} + +/** + * Create a document to send to the index that contains useful information + * regarding the website. + * @return ApacheSolrDocument + */ +function apachesolr_multisitesearch_generate_metadata() { + $document = new ApacheSolrDocument(); + $document->id = apachesolr_document_id(1, 'multisite.metadata'); + $document->site = url(NULL, array('absolute' => TRUE)); + $document->hash = apachesolr_site_hash(); + $document->entity_id = 1; + $document->entity_type = 'multisite.meta'; + $document->ss_multisite_meta_sitename = variable_get('site_name', 'Drupal'); + + // Only refresh for the default environment + $env_id = apachesolr_default_environment(); + + // Add bundle information to our metadata + foreach (entity_get_info() as $entity_type => $info) { + // We index each name as a string for cross-site faceting + foreach ($info['bundles'] as $bundle => $bundle_info) { + if (!empty($bundle_info['apachesolr']['index'])) { + $document->setMultiValue('sm_multisite_meta_bundles', $bundle_info['label']); + } + } + } + + // Add taxonomy to our metadata + if (module_exists('taxonomy')) { + module_load_include('inc', 'apachesolr', 'apachesolr.index'); + $vocabs = taxonomy_get_vocabularies(); + foreach ($vocabs as $vid => $vocab) { + // We index each name as a string for cross-site faceting + // using the vocab name rather than vid in field construction. + $document->setMultiValue('sm_multisite_meta_taxonomy', apachesolr_vocab_name($vid)); + } + } + // Allow alterations to this meta data + drupal_alter('apachesolr_multisitesearch_metadata', $document); + return $document; +} + +function apachesolr_multisitesearch_retrieve_metadata() { + try { + // Get the $solr object + $solr = apachesolr_get_solr(); + $params['qt'] = 'standard'; + $params['fl'] = '*'; + $response = $solr->search('entity_type:multisite.meta', $params); + foreach ($response->response->docs as $doc) { + // Convert doc into a simple array. + if (isset($doc->hash)) { + foreach ($doc as $k => $v) { + $data[$doc->hash][$k] = $v; + } + if (empty($data[$doc->hash]['sm_multisite_meta_taxonomy'])) { + $data[$doc->hash]['sm_multisite_meta_taxonomy'] = array(); + } + if (empty($data[$doc->hash]['sm_multisite_meta_bundles'])) { + $data[$doc->hash]['sm_multisite_meta_bundles'] = array(); + } + } + } + watchdog('Apache Solr Multisite', 'Fetched site meta data'); + variable_set('apachesolr_multisitesearch_metadata', $data); + } + catch (Exception $e) { + watchdog('Apache Solr Multisite', 'Failed to fetch meta data
!message', + array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); + } +} + +/** + * Creation of update of the metadata + * @return type + */ +function apachesolr_multisitesearch_update_metadata() { + try { + // Get the $solr object + $solr = apachesolr_get_solr(); + $metadata_doc = apachesolr_multisitesearch_generate_metadata(); + $solr->addDocuments(array($metadata_doc)); + $solr->commit(); + watchdog('Apache Solr Multisite', 'Updated site meta data'); + return TRUE; + } + catch (Exception $e) { + watchdog('Apache Solr Multisite', 'Indexing failed for meta data
!message', + array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); + } + return FALSE; +} + +function apachesolr_multisitesearch_delete_metadata($hash = NULL) { + try { + // Get the $solr object + $solr = apachesolr_get_solr(); + if (empty($hash)) { + $query = "entity_type:multisite.meta"; + } + else { + $query = "hash:$hash AND entity_type:multisite.meta"; + } + $solr->deleteByQuery($query); + watchdog('Apache Solr Multisite', 'Removed meta data from the index'); + return TRUE; + } + catch (Exception $e) { + watchdog('Apache Solr Multisite', 'Removing meta data failed.
!message', + array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); + } + return FALSE; +} + +function apachesolr_multisitesearch_get_site_hashes() { + try { + // Get the $solr object + $solr = apachesolr_get_solr(); + $params['qt'] = 'standard'; + $params['fl'] = '*'; + $params['facet'] = 'true'; + $params['facet.field'][] = 'hash'; + $params['facet.mincount'] = 1; + $params['facet.limit'] = '1000'; + $response = $solr->search('*:*', $params); + $results = (array)$response->facet_counts->facet_fields->hash; + return $results; + } + catch (Exception $e) { + watchdog('Apache Solr Multisite', 'Failed to fetch hash facet count
!message', + array('!message' => nl2br(strip_tags($e->getMessage()))), WATCHDOG_ERROR); + } +} diff --git a/apachesolr_multisitesearch.info b/apachesolr_multisitesearch.info index ab9632e..12d9cdd 100644 --- a/apachesolr_multisitesearch.info +++ b/apachesolr_multisitesearch.info @@ -2,5 +2,11 @@ name = Apache Solr Multisite Search description = Search across multiple sites with Solr dependencies[] = apachesolr dependencies[] = apachesolr_search -package = Apache Solr -core = "7.x" \ No newline at end of file +package = Search Toolkit +core = "7.x" +; Information added by drupal.org packaging script on 2012-03-16 +version = "7.x-1.x-dev" +core = "7.x" +project = "apachesolr_multisitesearch" +datestamp = "1331900062" + diff --git a/apachesolr_multisitesearch.module b/apachesolr_multisitesearch.module index 3b5129b..83588e4 100644 --- a/apachesolr_multisitesearch.module +++ b/apachesolr_multisitesearch.module @@ -11,7 +11,7 @@ function apachesolr_multisitesearch_menu() { $items = array(); $items['admin/config/search/apachesolr/multisite-filters'] = array( - 'title' => 'Multisite settings', + 'title' => 'Multisite', 'page callback' => 'drupal_get_form', 'page arguments' => array('apachesolr_multisitesearch_settings'), 'weight' => -8, @@ -23,264 +23,135 @@ function apachesolr_multisitesearch_menu() { } /** - * Implementation of hook_search_info(). + * Implements hook_facetapi_facet_info(). + * + * Maps the hash label in Apache Solr to a facet + * @param type $searcher_info + * @return type */ -function apachesolr_multisitesearch_search_info() { - return array( - 'title' => 'Multisite', - 'path' => 'multisite', - 'conditions_callback' => 'apachesolr_search_conditions', +function apachesolr_multisitesearch_facetapi_facet_info($searcher_info) { + $facets = array(); + $facets['hash'] = array( + 'label' => t('Site'), + 'description' => t('Filter by Site (Multisite).'), + 'field' => 'hash', + 'map callback' => 'apachesolr_multisitesearch_map_hash', + ); + // Create a multisite bundle name field + $facets['bundle_name'] = array( + 'label' => t('Content Type'), + 'description' => t('Filter by content type (Multisite).'), + 'field' => 'bundle_name', ); -} -/** - * Implements hook_search_execute(). - */ -function apachesolr_multisitesearch_search_execute($keys = NULL, $conditions = NULL) { - $filters = isset($conditions['fq']) ? $conditions['fq'] : array(); - $solrsort = isset($_GET['solrsort']) ? $_GET['solrsort'] : ''; - $empty_search_behavior = isset($conditions['apachesolr_search_browse']) ? $conditions['apachesolr_search_browse'] : ''; - unset($conditions['apachesolr_search_browse']); - try { - if (!$keys && !$conditions && ($empty_search_behavior == 'browse' || $empty_search_behavior == 'blocks')) { - // Pass empty search behavior as string on to apachesolr_search_search_page() - apachesolr_search_run_empty('apachesolr', 'search/' . arg(1)); - $results['apachesolr_search_browse'] = $empty_search_behavior; - if ($empty_search_behavior == 'browse') { - // Hide sidebar blocks for content-area browsing instead. - apachesolr_suppress_blocks(TRUE); - } - } - else { - $results = apachesolr_multisitesearch_run('apachesolr', array('q' => $keys, 'fq' => $filters), $solrsort, 'search/' . arg(1), pager_find_page()); - } - return $results; - } - catch (Exception $e) { - watchdog('Apache Solr', nl2br(check_plain($e->getMessage())), NULL, WATCHDOG_ERROR); - apachesolr_failure(t('Solr search'), $keys); - } + // Create a multisite facet field + $facets['sm_vid_tags'] = array( + 'label' => t('Tags'), + 'description' => t('Filter by Tags (Multisite).'), + 'field' => 'sm_vid_Tags', + ); + return $facets; } /** - * Execute a search results based on keyword, filter, and sort strings. - * - * @param $name - * @param $params - * Array - 'q' is the keywords to search. - * @param $solrsort - * @param $base_path - * For constructing filter and sort links. Leave empty unless the links need to point somewhere - * other than the base path of the current request. - * @param integer $page - * For pagination. - * @param $caller - * - * @return stdClass $response + * Implements hook_form_FORM_ID_alter(). * - * @throws Exception + * Adds a "make multisite" option in the settings of any environment */ -function apachesolr_multisitesearch_run($name, array $params = array(), $solrsort = '', $base_path = '', $page = 0, $solr = NULL) { - // This is the object that knows about the query coming from the user. - $query = apachesolr_drupal_query($name, $params, $solrsort, $base_path, $solr); - $query->multisite = TRUE; - apachesolr_multisitesearch_basic_params($query); - apachesolr_search_add_boost_params($query); - if ($query->getParam('q')) { - apachesolr_search_highlighting_params($query); - if (!$query->getParam('hl.fl')) { - $qf = array(); - foreach ($query->getParam('qf') as $field) { - // Truncate off any boost so we get the simple field name. - $parts = explode('^', $field, 2); - $qf[$parts[0]] = TRUE; - } - foreach (array('content', 'ts_comments') as $field) { - if (isset($qf[$field])) { - $query->addParam('hl.fl', $field); - } - } - } - apachesolr_search_add_spellcheck_params($query); - } - else { - // No highlighting, use the teaser as a snippet. - $query->addParam('fl', 'teaser'); - } - list($final_query, $response) = apachesolr_do_query($query, $page); - apachesolr_has_searched(TRUE); - return apachesolr_multisitesearch_process_response($response, $final_query); +function apachesolr_multisitesearch_form_apachesolr_environment_edit_form_alter(&$form, &$form_state, $form_id) { + $environment = reset($form_state['build_info']['args']); + $is_multisite = apachesolr_environment_variable_get($environment['env_id'], 'multisitesearch'); + $form['make_multisite'] = array( + '#type' => 'checkbox', + '#title' => t('Make this Solr search environment multisite capable'), + '#default_value' => $is_multisite, + ); + $form['actions']['save']['#submit'][] = 'apachesolr_multisitesearch_environment_edit_submit'; } /** - * Implements hook_search_page(). + * Submit callback for saving an environment to make it multisite capabe */ -function apachesolr_multisitesearch_search_page($results) { - if (!empty($results['apachesolr_search_browse'])) { - // Show facet browsing blocks. - $output = apachesolr_search_page_browse($results['apachesolr_search_browse']); - } - elseif ($results) { - $output = array( - '#theme' => 'search_results', - '#results' => $results, - '#module' => 'apachesolr_search', - ); - } - else { - // No suggestions found, give the user some custom help text. - $output = isset($output) ? $output : array('#markup' => theme('apachesolr_search_noresults')); - } - return $output; +function apachesolr_multisitesearch_environment_edit_submit($form, &$form_state) { + // Enable or disable multisite + apachesolr_environment_variable_set($form_state['values']['env_id'], 'multisitesearch', $form_state['values']['make_multisite']); } /** - * Implements hook_apachesolr_process_results(). + * callback for mapping hashes to sites + * @return array $data */ -function apachesolr_multisitesearch_apachesolr_process_results(&$results, $namespace = FALSE) { - if ($namespace == 'apachesolr_multisitesearch') { - foreach ($results as $key => $result) { - $results[$key]['extra']['hash'] = theme('apachesolr_multisitesearch_breadcrumb_hash', array('hash' => $result['fields']['hash'])); - } +function apachesolr_multisitesearch_map_hash() { + $data = variable_get('apachesolr_multisitesearch_metadata', array()); + foreach ($data as $key => $value) { + $data[$key] = $value['ss_multisite_meta_sitename']; } + return $data; } /** - * Implements hook_cron(). + * Implements hook_apachesolr_process_results(). + * + * Changes the links from results that come out of another index + * @param array $results + * @param DrupalSolrQueryInterface $query */ -function apachesolr_multisitesearch_cron() { - apachesolr_multisitesearch_refresh_metadata(); -} - -function apachesolr_multisitesearch_refresh_metadata() { - // Update meta data 1x per hour max. - // Fetch meta data 1x per 5 minutes max. - // TODO - make these intervals controllable. - $last_update = variable_get('apachesolr_multisitesearch_last_metadata_update', 0); - $last_fetch = variable_get('apachesolr_multisitesearch_last_metadata_fetch', 0); - $time = time(); - module_load_include('inc', 'apachesolr_multisitesearch', 'apachesolr_multisitesearch.admin'); - if ($time - $last_update > 60*60) { - if (apachesolr_multisitesearch_update_metadata()) { - variable_set('apachesolr_multisitesearch_last_metadata_update', $time); +function apachesolr_multisitesearch_apachesolr_process_results(&$results, DrupalSolrQueryInterface $query) { + $env_id = $query->solr('getId'); + $multisite = apachesolr_environment_variable_get($env_id, 'multisitesearch'); + if (!empty($multisite)) { + foreach ($results as $id => $result) { + $results[$id]['extra']['hash'] = theme('apachesolr_multisitesearch_breadcrumb_hash', array('hash' => $results[$id]['fields']['hash'])); + $results[$id]['link'] = $results[$id]['fields']['url']; } } - if ($time - $last_fetch > 60*5) { - apachesolr_multisitesearch_get_metadata(); - } - apachesolr_index_set_last_updated($time); } /** * Implements hook_apachesolr_query_alter(). + * + * Verifies if the environment is multisite enabled, and if so, returns + * results from the while index. Otherwise it only returns results from + * the current site. + * @param DrupalSolrQueryInterface $query */ function apachesolr_multisitesearch_apachesolr_query_alter(DrupalSolrQueryInterface $query) { if (empty($query->multisite)) { - // Limit single site searchs via the site hash. - // @TODO: This is currently stopping apachesolr_autocomplete from working correctly - // $query->addFilter('hash', apachesolr_site_hash()); + $env_id = $query->solr('getId'); + $multisite = apachesolr_environment_variable_get($env_id, 'multisitesearch'); + // Add hash and site to our fields to retrieve + $query->addParam('fl', 'hash'); + $query->addParam('fl', 'site'); + if (empty($multisite)) { + // Limit single site searchs via the site hash. + $query->addFilter('hash', apachesolr_site_hash()); + } } } -function apachesolr_multisitesearch_basic_params(DrupalSolrQueryInterface $query = NULL) { - $params = array( - 'fl' => array('id', 'entity_id', 'entity_type', 'bundle', 'bundle_name', 'label', 'is_comment_count', 'ds_created', 'ds_changed', 'score', 'path', 'url', 'is_uid', 'tos_name', 'site', 'hash'), - 'rows' => variable_get('apachesolr_rows', 10), - ); - if ($query) { - $query->addParams($params); +/** + * Implements hook_apachesolr_delete_by_query_alter(). + * + * Allows a module to modify the delete query. + * @param string $query + * Defaults to *:* + */ +function apachesolr_multisitesearch_apachesolr_delete_by_query_alter($query) { + // use the site hash so that you only delete this site's content + if ($query == '*:*') { + $query = 'hash:' . apachesolr_site_hash(); } - return $params; -} - -function apachesolr_multisitesearch_process_response($response, DrupalSolrQueryInterface $query) { - $results = array(); - // We default to getting snippets from the body content and comments. - $hl_fl = $query->getParam('hl.fl'); - if (!$hl_fl) { - $hl_fl = array('content', 'ts_comments'); + else { + $query = "($query) AND hash:" . apachesolr_site_hash(); } - $total = $response->response->numFound; - pager_default_initialize($total, $query->getParam('rows')); - if ($total > 0) { - foreach ($response->response->docs as $doc) { - $extra = array(); - - // Start with an empty snippets array. - $snippets = array(); - - // Find the nicest available snippet. - foreach ($hl_fl as $hl_param) { - if (isset($response->highlighting->{$doc->id}->$hl_param)) { - // Merge arrays preserving keys. - foreach ($response->highlighting->{$doc->id}->$hl_param as $values) { - $snippets[$hl_param] = $values; - } - } - } - // If there's no snippet at this point, add the teaser. - if (!$snippets) { - if (isset($doc->teaser)) { - $snippets[] = truncate_utf8($doc->teaser, 256, TRUE); - } - } - $hook = 'apachesolr_search_snippets__' . $doc->entity_type; - if (!empty($doc->bundle)) { - $hook .= '__' . $doc->bundle; - } - $snippet = theme($hook, array('doc' => $doc, 'snippets' => $snippets)); +} - if (!isset($doc->content)) { - $doc->content = $snippet; - } - // Normalize common dates so that we can use Drupal's normal date and - // time handling. - if (isset($doc->ds_created)) { - $doc->created = strtotime($doc->ds_created); - } - if (isset($doc->ds_changed)) { - $doc->changed = strtotime($doc->ds_changed); - } - if (isset($doc->tos_name)) { - $doc->name = $doc->tos_name; - } - $extra = array(); - // Allow modules to alter each document and its extra information. - drupal_alter('apachesolr_search_result', $doc, $extra); - $fields = (array) $doc; - $result = array( - // link is a required field, so handle it centrally. - 'link' => url($doc->url, array('absolute' => TRUE)), - // template_preprocess_search_result() runs check_plain() on the title - // again. Decode to correct the display. - 'title' => htmlspecialchars_decode($doc->label, ENT_QUOTES), - // These values are not required by the search module but are provided - // to give entity callbacks and themers more flexibility. - 'score' => $doc->score, - 'snippets' => $snippets, - 'snippet' => $snippet, - 'fields' => $fields, - 'entity_type' => $doc->entity_type, - 'user' => theme('apachesolr_multisitesearch_username', array('doc' => $doc)), - ); - if (isset($doc->bundle) && !empty($doc->bundle)) { - $result['bundle'] = $doc->bundle; - } - // Call entity-type-specific callbacks for extra handling. - $function = apachesolr_entity_get_callback($doc->entity_type, 'result callback'); - if (is_callable($function)) { - $function($doc, $result, $extra); - } - $result['extra'] = $extra; - $results[] = $result; - } - // Hook to allow modifications of the retrieved results - foreach (module_implements('apachesolr_process_results') as $module) { - $function = $module . '_apachesolr_process_results'; - $function($results, 'apachesolr_multisitesearch'); - } - } - return $results; +/** + * Implements hook_cron(). + */ +function apachesolr_multisitesearch_cron() { + module_load_include('inc', 'apachesolr_multisitesearch', 'apachesolr_multisitesearch.index'); + apachesolr_multisitesearch_refresh_metadata(); } /** @@ -288,9 +159,6 @@ function apachesolr_multisitesearch_process_response($response, DrupalSolrQueryI */ function apachesolr_multisitesearch_theme() { return array( - 'apachesolr_multisitesearch_username' => array( - 'variables' => array('doc' => NULL), - ), 'apachesolr_multisitesearch_breadcrumb_hash' => array( 'variables' => array('hash' => NULL, 'exclude' => FALSE), ), @@ -311,123 +179,3 @@ function theme_apachesolr_multisitesearch_breadcrumb_hash($variables) { } return $hash; } - -/** - * Modified username theme function. - * - * @see theme_username() - */ -function theme_apachesolr_multisitesearch_username($variables) { - $doc = $variables['doc']; - if ($doc->name) { - // Shorten the name when it is too long or it will break many tables. - if (drupal_strlen($doc->name) > 20) { - $name = drupal_substr($doc->name, 0, 15) .'...'; - } - else { - $name = $doc->name; - } - // Only make links for local users. - if ($doc->is_uid && apachesolr_site_hash() == $doc->hash && user_access('access user profiles')) { - $output = l($name, 'user/'. $doc->is_uid, array('attributes' => array('title' => t('View user profile.')))); - } - else { - $output = check_plain($name); - } - } - else { - $output = check_plain(variable_get('anonymous', t('Anonymous'))); - } - return $output; -} - -/** - * Implements hook_apachesolr_delete_index_alter() - */ -function apachesolr_multisitesearch_apachesolr_delete_index_alter(&$query) { - // Limit to the current site. - $query = "($query) AND hash:" . apachesolr_site_hash(); -} - -/** - * Implements hook_form_[form_id]_alter(). - * - * This adds spelling suggestions, retain filters to the search form. - */ -function apachesolr_multisitesearch_form_search_form_alter(&$form, $form_state) { - if ($form['module']['#value'] == 'apachesolr_multisitesearch') { - $form['#submit'][] = 'apachesolr_search_form_search_submit'; - // No other modification make sense unless a query is active. - // Note - this means that the query must always be run before - // calling drupal_get_form('search_form'). - $apachesolr_has_searched = apachesolr_has_searched(); - - $searcher = NULL; - $fq = NULL; - if ($apachesolr_has_searched) { - $query = apachesolr_current_query(); - $searcher = $query->getSearcher(); - // We use the presence of filter query params as a flag for the retain filters checkbox. - $fq = $query->getParam('fq'); - } - - $form['basic']['apachesolr_search']['#tree'] = TRUE; - $form['basic']['apachesolr_search']['get'] = array( - '#type' => 'hidden', - '#default_value' => json_encode(array_diff_key($_GET, array('q' => 1, 'page' => 1, 'solrsort' => 1, 'retain-filters' => 1))), - ); - - if ($fq || isset($form_state['input']['apachesolr_search']['retain-filters'])) { - $form['basic']['apachesolr_search']['retain-filters'] = array( - '#type' => 'checkbox', - '#title' => t('Retain current filters'), - '#default_value' => (int) isset($_GET['retain-filters']), - ); - } - - if (variable_get('apachesolr_search_spellcheck', TRUE) && $apachesolr_has_searched && ($response = apachesolr_static_response_cache($searcher))) { - // Get spellchecker suggestions into an array. - if (isset($response->spellcheck->suggestions) && $response->spellcheck->suggestions) { - $suggestions = get_object_vars($response->spellcheck->suggestions); - if ($suggestions) { - // Get the original query and replace words. - - foreach ($suggestions as $word => $value) { - $replacements[$word] = $value->suggestion[0]; - } - $new_keywords = strtr($query->getParam('q'), $replacements); - - // Show only if suggestion is different than current query. - if ($query->getParam('q') != $new_keywords) { - $form['apachesolr_search']['suggestion'] = array( - '#theme' => 'apachesolr_search_suggestions', - '#links' => array(l($new_keywords, $query->getPath($new_keywords))), - ); - } - } - } - } - } -} - -/** - * Implements hook_facetapi_facet_info(). - */ -function apachesolr_multisitesearch_facetapi_facet_info($searcher_info) { - $facets = array(); - $facets['hash'] = array( - 'label' => t('Site'), - 'description' => t('Filter by site.'), - 'field' => 'hash', - 'map callback' => 'apachesolr_multisitesearch_map_hash', - ); - return $facets; -} - -function apachesolr_multisitesearch_map_hash() { - $data = variable_get('apachesolr_multisitesearch_metadata', array()); - foreach ($data as $key => $value) { - $data[$key] = $value['ss_multisite_meta_sitename']; - } - return $data; -}