Index: modules/search/search.module =================================================================== --- modules/search/search.module (revision 9) +++ modules/search/search.module (working copy) @@ -1093,7 +1093,8 @@ function search_box_form_submit($form, & } $form_id = $form['form_id']['#value']; - $form_state['redirect'] = 'search/node/'. trim($form_state['values'][$form_id]); + $type = array_shift(module_implements('search')); + $form_state['redirect'] = "search/$type/". trim($form_state['values'][$form_id]); } /** @@ -1153,7 +1154,10 @@ function template_preprocess_search_bloc /** * Perform a standard search on the given keys, and return the formatted results. */ -function search_data($keys = NULL, $type = 'node') { +function search_data($keys = NULL, $type = NULL) { + if (is_null($type)) { + $type = array_shift(module_implements('search')); + } if (isset($keys)) { if (module_hook($type, 'search')) { Index: modules/search/search.pages.inc =================================================================== --- modules/search/search.pages.inc (revision 9) +++ modules/search/search.pages.inc (working copy) @@ -9,16 +9,23 @@ /** * Menu callback; presents the search form and/or search results. */ -function search_view($type = 'node') { +function search_view($type = '') { // Search form submits with POST but redirects to GET. This way we can keep // the search query URL clean as a whistle: // search/type/keyword+keyword if (!isset($_POST['form_id'])) { if ($type == '') { - // Note: search/node can not be a default tab because it would take on the + // Note: search/contentsearch can not be a default tab because it would take on the // path of its parent (search). It would prevent remembering keywords when // switching tabs. This is why we drupal_goto to it from the parent instead. - drupal_goto('search/node'); + $modules = module_implements('search'); + if ($default = array_shift($modules)) { + drupal_goto('search/'. $default); + } + else { + drupal_set_message(t('There are no search modules enabled.'), 'error'); + return ''; + } } $keys = search_get_keys(); @@ -124,7 +131,9 @@ function search_form_submit($form, &$for // Fall through to the drupal_goto() call. } - $type = $form_state['values']['module'] ? $form_state['values']['module'] : 'node'; + $default_type = array_shift(module_implements('search')); + $type = $form_state['values']['module'] ? $form_state['values']['module'] : $default_type; + $form_state['redirect'] = 'search/'. $type .'/'. $keys; return; } Index: modules/node/node.module =================================================================== --- modules/node/node.module (revision 9) +++ modules/node/node.module (working copy) @@ -73,9 +73,6 @@ function node_theme() { 'node_list' => array( 'arguments' => array('items' => NULL, 'title' => NULL), ), - 'node_search_admin' => array( - 'arguments' => array('form' => NULL), - ), 'node_filter_form' => array( 'arguments' => array('form' => NULL), 'file' => 'node.admin.inc', @@ -971,10 +968,6 @@ function node_delete($nid) { // Clear the page and block caches. cache_clear_all(); - // Remove this node from the search index if needed. - if (function_exists('search_wipe')) { - search_wipe($node->nid, 'node'); - } watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title)); drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title))); } @@ -1135,173 +1128,6 @@ function node_perm() { } /** - * Implementation of hook_search(). - */ -function node_search($op = 'search', $keys = NULL) { - switch ($op) { - case 'name': - return t('Content'); - - case 'reset': - db_query("UPDATE {search_dataset} SET reindex = %d WHERE type = 'node'", time()); - return; - - case 'status': - $total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1')); - $remaining = db_result(db_query("SELECT COUNT(*) FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE n.status = 1 AND (d.sid IS NULL OR d.reindex <> 0)")); - return array('remaining' => $remaining, 'total' => $total); - - case 'admin': - $form = array(); - // Output form for defining rank factor weights. - $form['content_ranking'] = array( - '#type' => 'fieldset', - '#title' => t('Content ranking'), - ); - $form['content_ranking']['#theme'] = 'node_search_admin'; - $form['content_ranking']['info'] = array( - '#value' => ''. t('The following numbers control which properties the content search should favor when ordering the results. Higher numbers mean more influence, zero means the property is ignored. Changing these numbers does not require the search index to be rebuilt. Changes take effect immediately.') .'' - ); - - $ranking = array('node_rank_relevance' => t('Keyword relevance'), - 'node_rank_recent' => t('Recently posted')); - if (module_exists('comment')) { - $ranking['node_rank_comments'] = t('Number of comments'); - } - if (module_exists('statistics') && variable_get('statistics_count_content_views', 0)) { - $ranking['node_rank_views'] = t('Number of views'); - } - - // Note: reversed to reflect that higher number = higher ranking. - $options = drupal_map_assoc(range(0, 10)); - foreach ($ranking as $var => $title) { - $form['content_ranking']['factors'][$var] = array( - '#title' => $title, - '#type' => 'select', - '#options' => $options, - '#default_value' => variable_get($var, 5), - ); - } - return $form; - - case 'search': - // Build matching conditions - list($join1, $where1) = _db_rewrite_sql(); - $arguments1 = array(); - $conditions1 = 'n.status = 1'; - - if ($type = search_query_extract($keys, 'type')) { - $types = array(); - foreach (explode(',', $type) as $t) { - $types[] = "n.type = '%s'"; - $arguments1[] = $t; - } - $conditions1 .= ' AND ('. implode(' OR ', $types) .')'; - $keys = search_query_insert($keys, 'type'); - } - - if ($category = search_query_extract($keys, 'category')) { - $categories = array(); - foreach (explode(',', $category) as $c) { - $categories[] = "tn.tid = %d"; - $arguments1[] = $c; - } - $conditions1 .= ' AND ('. implode(' OR ', $categories) .')'; - $join1 .= ' INNER JOIN {term_node} tn ON n.vid = tn.vid'; - $keys = search_query_insert($keys, 'category'); - } - - // Build ranking expression (we try to map each parameter to a - // uniform distribution in the range 0..1). - $ranking = array(); - $arguments2 = array(); - $join2 = ''; - // Used to avoid joining on node_comment_statistics twice - $stats_join = FALSE; - $total = 0; - if ($weight = (int)variable_get('node_rank_relevance', 5)) { - // Average relevance values hover around 0.15 - $ranking[] = '%d * i.relevance'; - $arguments2[] = $weight; - $total += $weight; - } - if ($weight = (int)variable_get('node_rank_recent', 5)) { - // Exponential decay with half-life of 6 months, starting at last indexed node - $ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp)) - %d) * 6.43e-8)'; - $arguments2[] = $weight; - $arguments2[] = (int)variable_get('node_cron_last', 0); - $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; - $stats_join = TRUE; - $total += $weight; - } - if (module_exists('comment') && $weight = (int)variable_get('node_rank_comments', 5)) { - // Inverse law that maps the highest reply count on the site to 1 and 0 to 0. - $scale = variable_get('node_cron_comments_scale', 0.0); - $ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(c.comment_count) * %f))'; - $arguments2[] = $weight; - $arguments2[] = $scale; - if (!$stats_join) { - $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; - } - $total += $weight; - } - if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) && - $weight = (int)variable_get('node_rank_views', 5)) { - // Inverse law that maps the highest view count on the site to 1 and 0 to 0. - $scale = variable_get('node_cron_views_scale', 0.0); - $ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(nc.totalcount) * %f))'; - $arguments2[] = $weight; - $arguments2[] = $scale; - $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid'; - $total += $weight; - } - - // When all search factors are disabled (ie they have a weight of zero), - // the default score is based only on keyword relevance and there is no need to - // adjust the score of each item. - if ($total == 0) { - $select2 = 'i.relevance AS score'; - $total = 1; - } - else { - $select2 = implode(' + ', $ranking) . ' AS score'; - } - - // Do search. - $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. $join1, $conditions1 . (empty($where1) ? '' : ' AND '. $where1), $arguments1, $select2, $join2, $arguments2); - - // Load results. - $results = array(); - foreach ($find as $item) { - // Build the node body. - $node = node_load($item->sid); - $node->build_mode = NODE_BUILD_SEARCH_RESULT; - $node = node_build_content($node, FALSE, FALSE); - $node->body = drupal_render($node->content); - - // Fetch comments for snippet. - $node->body .= module_invoke('comment', 'nodeapi', $node, 'update index'); - // Fetch terms for snippet. - $node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index'); - - $extra = node_invoke_nodeapi($node, 'search result'); - $results[] = array( - 'link' => url('node/'. $item->sid, array('absolute' => TRUE)), - 'type' => check_plain(node_get_types('name', $node)), - 'title' => $node->title, - 'user' => theme('username', $node), - 'date' => $node->changed, - 'node' => $node, - 'extra' => $extra, - 'score' => $item->score / $total, - 'snippet' => search_excerpt($keys, $node->body), - ); - } - return $results; - } -} - -/** * Implementation of hook_user(). */ function node_user($op, &$edit, &$user) { @@ -1312,28 +1138,6 @@ function node_user($op, &$edit, &$user) } /** - * Theme the content ranking part of the search settings admin page. - * - * @ingroup themeable - */ -function theme_node_search_admin($form) { - $output = drupal_render($form['info']); - - $header = array(t('Factor'), t('Weight')); - foreach (element_children($form['factors']) as $key) { - $row = array(); - $row[] = $form['factors'][$key]['#title']; - unset($form['factors'][$key]['#title']); - $row[] = drupal_render($form['factors'][$key]); - $rows[] = $row; - } - $output .= theme('table', $header, $rows); - - $output .= drupal_render($form); - return $output; -} - -/** * Retrieve the comment mode for the given node ID (none, read, or read/write). */ function node_comment_mode($nid) { @@ -1786,159 +1590,6 @@ function node_page_view($node, $cid = NU } /** - * Implementation of hook_update_index(). - */ -function node_update_index() { - $limit = (int)variable_get('search_cron_limit', 100); - - // Store the maximum possible comments per thread (used for ranking by reply count) - variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}')))); - variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}')))); - - $result = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {search_dataset} d ON d.type = 'node' AND d.sid = n.nid WHERE d.sid IS NULL OR d.reindex <> 0 ORDER BY d.reindex ASC, n.nid ASC", 0, $limit); - - while ($node = db_fetch_object($result)) { - _node_index_node($node); - } -} - -/** - * Index a single node. - * - * @param $node - * The node to index. - */ -function _node_index_node($node) { - $node = node_load($node->nid); - - // save the changed time of the most recent indexed node, for the search results half-life calculation - variable_set('node_cron_last', $node->changed); - - // Build the node body. - $node->build_mode = NODE_BUILD_SEARCH_INDEX; - $node = node_build_content($node, FALSE, FALSE); - $node->body = drupal_render($node->content); - - $text = '