summaryrefslogtreecommitdiff
path: root/modules/node/node.module
diff options
context:
space:
mode:
Diffstat (limited to 'modules/node/node.module')
-rw-r--r--modules/node/node.module121
1 files changed, 42 insertions, 79 deletions
diff --git a/modules/node/node.module b/modules/node/node.module
index 34b1c8193..ac5d3efaa 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1228,37 +1228,26 @@ function node_permission() {
/**
* Gather the rankings from the the hook_ranking implementations.
+ *
+ * @param $query
+ * A query object that has been extended with the Search DB Extender.
*/
-function _node_rankings() {
- $rankings = array(
- 'total' => 0, 'join' => array(), 'score' => array(), 'args' => array(),
- );
+function _node_rankings(SelectQueryExtender $query) {
if ($ranking = module_invoke_all('ranking')) {
+ $tables = &$query->getTables();
foreach ($ranking as $rank => $values) {
if ($node_rank = variable_get('node_rank_' . $rank, 0)) {
// 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'][] = 'CAST(%f AS DECIMAL) * 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']);
+ if (isset($values['join']) && !isset($tables[$values['join']['alias']])) {
+ $query->addJoin($values['join']['type'], $values['join']['table'], $values['join']['alias'], $values['join']['on']);
}
+ $arguments = isset($values['arguments']) ? $values['arguments'] : array();
+ $query->addScore($values['score'], $arguments, $node_rank);
}
}
}
- return $rankings;
}
-
/**
* Implement hook_search().
*/
@@ -1305,61 +1294,35 @@ function node_search($op = 'search', $keys = NULL) {
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 ($term = search_query_extract($keys, 'term')) {
- $terms = array();
- foreach (explode(',', $term) as $c) {
- $terms[] = "tn.tid = %d";
- $arguments1[] = $c;
- }
- $conditions1 .= ' AND (' . implode(' OR ', $terms) . ')';
- $join1 .= ' INNER JOIN {taxonomy_term_node} tn ON n.vid = tn.vid';
- $keys = search_query_insert($keys, 'term');
+ $query = db_select('search_index', 'i')->extend('SearchQuery')->extend('PagerDefault');
+ $query->join('node', 'n', 'n.nid = i.sid');
+ $query
+ ->condition('n.status', 1)
+ ->addTag('node_access')
+ ->searchExpression($keys, 'node');
+
+ // Insert special keywords.
+ $query->setOption('type', 'n.type');
+ $query->setOption('language', 'n.language');
+ if ($query->setOption('term', 'tn.nid')) {
+ $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid');
}
-
- if ($languages = search_query_extract($keys, 'language')) {
- $terms = array();
- foreach (explode(',', $languages) as $l) {
- $terms[] = "n.language = '%s'";
- $arguments1[] = $l;
- }
- $conditions1 .= ' AND (' . implode(' OR ', $terms) . ')';
- $keys = search_query_insert($keys, 'language');
+ // Only continue if the first pass query matches.
+ if (!$query->executeFirstPass()) {
+ return array();
}
- // Get the ranking expressions.
- $rankings = _node_rankings();
+ // Add the ranking expressions.
+ _node_rankings($query);
- // When all search factors are disabled (ie they have a weight of zero),
- // The default score is based only on keyword relevance.
- if ($rankings['total'] == 0) {
- $total = 1;
- $arguments2 = array();
- $join2 = '';
- $select2 = 'SUM(i.relevance) AS calculated_score';
- }
- else {
- $total = $rankings['total'];
- $arguments2 = $rankings['arguments'];
- $join2 = implode(' ', $rankings['join']);
- $select2 = 'SUM(' . implode(' + ', $rankings['score']) . ') AS calculated_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);
+ // Add a count query.
+ $inner_query = clone $query;
+ $count_query = db_select($inner_query->fields('i', array('sid')));
+ $count_query->addExpression('COUNT(*)');
+ $query->setCountQuery($count_query);
+ $find = $query
+ ->limit(10)
+ ->execute();
// Load results.
$results = array();
@@ -1370,9 +1333,9 @@ function node_search($op = 'search', $keys = NULL) {
$node->rendered = drupal_render($node->content);
// Fetch comments for snippet.
- $node->rendered .= module_invoke('comment', 'node_update_index', $node);
+ $node->rendered .= ' ' . module_invoke('comment', 'node_update_index', $node);
// Fetch terms for snippet.
- $node->rendered .= module_invoke('taxonomy', 'node_update_index', $node);
+ $node->rendered .= ' ' . module_invoke('taxonomy', 'node_update_index', $node);
$extra = module_invoke_all('node_search_result', $node);
@@ -1384,7 +1347,7 @@ function node_search($op = 'search', $keys = NULL) {
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
- 'score' => $total ? ($item->calculated_score / $total) : 0,
+ 'score' => $item->calculated_score,
'snippet' => search_excerpt($keys, $node->rendered),
);
}
@@ -1420,8 +1383,8 @@ function node_ranking() {
$ranking['recent'] = array(
'title' => t('Recently posted'),
// Exponential decay with half-life of 6 months, starting at last indexed node
- 'score' => 'POW(2.0, (GREATEST(n.created, n.changed) - %d) * 6.43e-8)',
- 'arguments' => array($node_cron_last),
+ 'score' => 'POW(2.0, (GREATEST(n.created, n.changed) - :node_cron_last) * 6.43e-8)',
+ 'arguments' => array(':node_cron_last' => $node_cron_last),
);
}
return $ranking;
@@ -2082,15 +2045,15 @@ function node_search_validate($form, &$form_state) {
// checkboxes to 0.
$form_state['values']['type'] = array_filter($form_state['values']['type']);
if (count($form_state['values']['type'])) {
- $keys = search_query_insert($keys, 'type', implode(',', array_keys($form_state['values']['type'])));
+ $keys = search_expression_insert($keys, 'type', implode(',', array_keys($form_state['values']['type'])));
}
}
if (isset($form_state['values']['term']) && is_array($form_state['values']['term'])) {
- $keys = search_query_insert($keys, 'term', implode(',', $form_state['values']['term']));
+ $keys = search_expression_insert($keys, 'term', implode(',', $form_state['values']['term']));
}
if (isset($form_state['values']['language']) && is_array($form_state['values']['language'])) {
- $keys = search_query_insert($keys, 'language', implode(',', array_filter($form_state['values']['language'])));
+ $keys = search_expression_insert($keys, 'language', implode(',', array_filter($form_state['values']['language'])));
}
if ($form_state['values']['or'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_state['values']['or'], $matches)) {