summaryrefslogtreecommitdiff
path: root/modules/node/node.module
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2008-05-14 11:10:54 +0000
committerDries Buytaert <dries@buytaert.net>2008-05-14 11:10:54 +0000
commit11aeff6016e8ee586c85913d315c0a5cb0c9fe09 (patch)
tree4f5b6274b80557fc987c36f62205cef3545d3b39 /modules/node/node.module
parent658b27c9eceed3c66c9fd4c75da9d9f0cdfd839c (diff)
downloadbrdo-11aeff6016e8ee586c85913d315c0a5cb0c9fe09.tar.gz
brdo-11aeff6016e8ee586c85913d315c0a5cb0c9fe09.tar.bz2
- Patch #145242 by douggreen et al: refactor node_rank to modules can add scoring factors.
Diffstat (limited to 'modules/node/node.module')
-rw-r--r--modules/node/node.module148
1 files changed, 85 insertions, 63 deletions
diff --git a/modules/node/node.module b/modules/node/node.module
index ac006b94e..7275ab114 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1142,6 +1142,39 @@ function node_perm() {
}
/**
+ * Gather the rankings from the the hook_ranking implementations.
+ */
+function _node_rankings() {
+ $rankings = array(
+ 'total' => 0, 'join' => array(), 'score' => array(), 'args' => array(),
+ );
+ if ($ranking = module_invoke_all('ranking')) {
+ foreach ($ranking as $rank => $values) {
+ if ($node_rank = variable_get('node_rank_'. $rank, 5)) {
+ // If the table defined in the ranking isn't already joined, then add it.
+ if (isset($values['join']) && !isset($rankings['join'][$values['join']])) {
+ $rankings['join'][$values['join']] = $values['join'];
+ }
+
+ // Add the rankings weighted score multiplier value, handling NULL gracefully.
+ $rankings['score'][] = '%f * COALESCE(('. $values['score'] .'), 0)';
+
+ // Add the the administrator's weighted score multiplier value for this ranking.
+ $rankings['total'] += $node_rank;
+ $rankings['arguments'][] = $node_rank;
+
+ // Add any additional arguments used by this ranking.
+ if (isset($values['arguments'])) {
+ $rankings['arguments'] = array_merge($rankings['arguments'], $values['arguments']);
+ }
+ }
+ }
+ }
+ return $rankings;
+}
+
+
+/**
* Implementation of hook_search().
*/
function node_search($op = 'search', $keys = NULL) {
@@ -1170,23 +1203,14 @@ function node_search($op = 'search', $keys = NULL) {
'#value' => '<em>' . 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.') . '</em>'
);
- $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,
+ foreach (module_invoke_all('ranking') as $var => $values) {
+ $form['content_ranking']['factors']['node_rank_'. $var] = array(
+ '#title' => $values['title'],
'#type' => 'select',
'#options' => $options,
- '#default_value' => variable_get($var, 5),
+ '#default_value' => variable_get('node_rank_'. $var, 5),
);
}
return $form;
@@ -1228,60 +1252,22 @@ function node_search($op = 'search', $keys = NULL) {
$keys = search_query_insert($keys, 'language');
}
- // 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;
- }
+ // Get the ranking expressions.
+ $rankings = _node_rankings();
// 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';
+ // The default score is based only on keyword relevance.
+ if ($rankings['total'] == 0) {
$total = 1;
+ $arguments2 = array();
+ $join2 = '';
+ $select2 = 'i.relevance AS score';
}
else {
- $select2 = implode(' + ', $ranking) . ' AS score';
+ $total = $rankings['total'];
+ $arguments2 = $rankings['arguments'];
+ $join2 = implode(' ', $rankings['join']);
+ $select2 = '('. implode(' + ', $rankings['score']) .') AS score';
}
// Do search.
@@ -1302,6 +1288,7 @@ function node_search($op = 'search', $keys = NULL) {
$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)),
@@ -1310,7 +1297,7 @@ function node_search($op = 'search', $keys = NULL) {
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
- 'score' => $item->score / $total,
+ 'score' => $total ? ($item->score / $total) : 0,
'snippet' => search_excerpt($keys, $node->body),
);
}
@@ -1319,6 +1306,41 @@ function node_search($op = 'search', $keys = NULL) {
}
/**
+ * Implementation of hook_ranking().
+ */
+function node_ranking() {
+ // Create the ranking array and add the basic ranking options.
+ $ranking = array(
+ 'relevance' => array(
+ 'title' => t('Keyword relevance'),
+ // Average relevance values hover around 0.15
+ 'score' => 'i.relevance',
+ ),
+ 'sticky' => array(
+ 'title' => t('Content is sticky at top of lists'),
+ // The sticky flag is either 0 or 1, which is automatically normalized.
+ 'score' => 'n.sticky',
+ ),
+ 'promote' => array(
+ 'title' => t('Content is promoted to the front page'),
+ // The promote flag is either 0 or 1, which is automatically normalized.
+ 'score' => 'n.promote',
+ ),
+ );
+
+ // Add relevance based on creation or changed date.
+ if ($node_cron_last = variable_get('node_cron_last', 0)) {
+ $ranking['recent'] = array(
+ 'title' => t('Recently posted'),
+ // Exponential decay with half-life of 6 months, starting at last indexed node
+ 'score' => '(POW(2, GREATEST(n.created, n.changed) - %d) * 6.43e-8)',
+ 'arguments' => array($node_cron_last),
+ );
+ }
+ return $ranking;
+}
+
+/**
* Implementation of hook_user().
*/
function node_user($op, &$edit, &$user) {