Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.582 diff -u -u -p -r1.582 comment.module --- modules/comment/comment.module 6 Sep 2007 12:21:39 -0000 1.582 +++ modules/comment/comment.module 11 Sep 2007 06:22:32 -0000 @@ -2239,3 +2239,17 @@ function comment_unpublish_by_keyword_ac } } } + +/** + * Implementation of hook_node_rank + */ +function comment_node_rank() { + return array( + 'node_rank_comments' => array( + 'title' => t('Number of comments'), + 'join' => 'LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid', + 'score' => '2.0 - 2.0 / (1.0 + c.comment_count * %f)', + 'terms' => array(variable_get('node_cron_comments_scale', 0)), + ), + ); +} Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.880 diff -u -u -p -r1.880 node.module --- modules/node/node.module 9 Sep 2007 20:16:09 -0000 1.880 +++ modules/node/node.module 11 Sep 2007 06:22:33 -0000 @@ -1049,6 +1049,34 @@ function node_perm() { return $perms; } +function _node_rankings() { + $rankings = array( + 'total' => 0, 'join' => array(), 'score' => array(), 'terms' => array(), + ); + if ($ranking = module_invoke_all('node_rank')) { + foreach ($ranking as $rank => $values) { + // if the join doesn't already exist, add it + if (isset($values['join']) && !isset($rankings['join'][$values['join']])) { + $rankings['join'][$values['join']] = $values['join']; + } + + // add the weighted score multiplier value, handle NULL gracefully + $rankings['score'][] = '%f * COALESCE(('. $values['score'] .'), 0)'; + + // add the the weighted score multiplier value + $node_rank = variable_get($rank, 5); + $rankings['total'] += $node_rank; + $rankings['terms'][] = $node_rank; + + // add the other terms + if (isset($values['terms'])) { + $rankings['terms'] = array_merge($rankings['terms'], $values['terms']); + } + } + } + return $rankings; +} + /** * Implementation of hook_search(). */ @@ -1076,19 +1104,10 @@ function node_search($op = 'search', $ke $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)); + foreach (module_invoke_all('node_rank') as $var => $values) { + $form['content_ranking']['factors'][$var] = array('#title' => $values['title'], '#type' => 'select', '#options' => $options, '#default_value' => variable_get($var, 5)); } return $form; @@ -1119,51 +1138,12 @@ function node_search($op = 'search', $ke $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(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)'; - $arguments2[] = $weight; - $arguments2[] = (int)variable_get('node_cron_last', 0); - $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid 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 + 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 + nc.totalcount * %f))'; - $arguments2[] = $weight; - $arguments2[] = $scale; - $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid'; - $total += $weight; - } - $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') .' AS score'; + // Build ranking expression + $rankings = _node_rankings(); + $arguments2 = $rankings['terms']; + $join2 = implode(' ', $rankings['join']); + $select2 = '('. implode(' + ', $rankings['score']) .') AS score'; + $total = $rankings['total']; // Do search $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. $join1 .' INNER JOIN {users} u ON n.uid = u.uid', $conditions1 . (empty($where1) ? '' : ' AND '. $where1), $arguments1, $select2, $join2, $arguments2); @@ -2574,3 +2554,26 @@ function node_unpublish_by_keyword_actio } } } + +/** + * Implementation of hook_node_rank + */ +function node_node_rank() { + // create the ranking array and add the keyword relevance scoring + $ranking = array( + 'node_rank_relevance' => array( + 'title' => t('Keyword relevance'), + 'score' => 'i.relevance', + ), + ); + + // if the statistics module is not enabled, score based on node dates only + if (!module_exists('statistics') && $node_cron_last = variable_get('node_cron_last', 0)) { + $ranking['node_rank_recent'] = array( + 'title' => t('Recently posted'), + 'score' => 'POW(2, GREATEST(n.created, n.changed) - %d) * 6.43e-8)', + 'terms' => array($node_cron_last), + ); + } + return $ranking; +} Index: modules/statistics/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v retrieving revision 1.266 diff -u -u -p -r1.266 statistics.module --- modules/statistics/statistics.module 23 Aug 2007 16:34:44 -0000 1.266 +++ modules/statistics/statistics.module 11 Sep 2007 06:22:33 -0000 @@ -323,3 +323,19 @@ function statistics_nodeapi(&$node, $op, db_query('DELETE FROM {node_counter} WHERE nid = %d', $node->nid); } } + +/** + * Implementation of hook_node_rank + */ +function statistics_node_rank() { + if (variable_get('statistics_count_content_views', 0)) { + return array( + 'node_rank_views' => array( + 'title' => t('Number of views'), + 'join' => 'LEFT JOIN {node_counter} nc ON nc.nid = i.sid', + 'score' => '2.0 - 2.0 / (1.0 + nc.totalcount * %f)', + 'terms' => array(variable_get('node_cron_views_scale', 0)), + ), + ); + } +}