Index: trip_search.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/trip_search/trip_search.module,v retrieving revision 1.37 diff -u -r1.37 trip_search.module --- trip_search.module 27 Sep 2005 19:27:11 -0000 1.37 +++ trip_search.module 28 Oct 2005 22:35:59 -0000 @@ -230,7 +230,7 @@ $results_output .= form_group(t('Matching categories'), $str); unset($str); } - if ($find = trip_search_get('node', $parsed_keys)) { + if ($find = trip_search_get('node', $parsed_keys) + trip_search_get('comment', $parsed_keys)) { if (variable_get('trip_search_rank_results', 1)) { $results = trip_search_rank_results($find, $parsed_keys); } @@ -307,7 +307,7 @@ if($parsed_keys->or) { $keys[] = implode(',', $parsed_keys->or); } - return implode(',', $keys); + return empty($keys) ? '' : stripslashes(implode(',', $keys)); } /* @@ -554,6 +554,7 @@ } $keys = array_merge($keys, $ors); } + $keys = array_map('stripslashes', $keys); break; case 'mysql_full': if ($parsed_keys->require) { @@ -700,18 +701,15 @@ */ function trip_search_parse($search) { //find quoted strings - preg_match_all('!-?"(.*?)"!is', $search, $quotes); + preg_match_all('#(user:|-)?"(.*?)"#is', $search, $quotes); foreach ($quotes[0] as $index => $value){ // remove the quoted strings - $search = str_replace($quotes[0][$index], '', $search); - if (substr($quotes[0][$index], 0, 2) == '-"') { - $quotes[1][$index] = '-' . $quotes[1][$index]; - } - // remove extra spaces - $search = str_replace(' ',' ', $search); + $search = str_replace($value, '', $search); + $quotes[1][$index] .= db_escape_string($quotes[2][$index]); } - $search = trim($search); - $search = split(' ', $search); + // remove extra spaces + $search = db_escape_string(trim(str_replace(' ',' ', $search))); + $search = empty($search) ? array() : explode(' ', $search); //merge the quotes and non quotes into one array $search = array_merge($search, $quotes[1]); @@ -826,6 +824,7 @@ $query->delimiter_right = '%%'; $query->wildcard = '%%'; } + $new_wheres = array(); // Generate SQL snippet for required words. if($keys->require) { $keys->require = str_replace('*', $query->wildcard, $keys->require); @@ -833,7 +832,7 @@ foreach ($query->fields as $field) { $requires[] = $field . " " . $query->like . " '" . $query->delimiter_left . $require . $query->delimiter_right . "'"; } - $query->wheres[] = '(' . implode(' OR ', $requires) . ')'; + $new_wheres[] = '(' . implode(' OR ', $requires) . ')'; array_splice ($requires, 0); } } @@ -848,7 +847,7 @@ $wheres[] = implode(' OR ', $ors); array_splice ($ors, 0); } - $query->wheres[] = '((' . implode(') OR (', $wheres) . '))' ; + $new_wheres[] = '((' . implode(') OR (', $wheres) . '))' ; array_splice ($wheres, 0); } } @@ -860,10 +859,17 @@ $nullcheck = "(ISNULL($field) OR "; $excludes[] = $nullcheck. $field . " " . $query->not_like . " '" . $query->delimiter_left . $exclude . $query->delimiter_right . "')"; } - $query->wheres[] = '(' . implode(' AND ', $excludes) . ')'; + $new_wheres[] = '(' . implode(' AND ', $excludes) . ')'; array_splice ($excludes, 0); } } + // Add new conditions and fulltext search, if any + if ($query->match) { + $query->wheres[] = $new_wheres ? ('('. $query->match .' OR ('. implode(' AND ', $new_wheres) .'))') : $query->match; + } + else if ($new_wheres) { + $query->wheres = $query->wheres ? array_merge($query->wheres, $new_wheres) : $new_wheres; + } return $query; } @@ -964,10 +970,9 @@ function node_trip_search($keys, $op = 'nodes') { $max = variable_get('trip_search_query_max', 500); $query->selects = 'n.title,n.type,nr.body,n.sticky'; - if (variable_get('trip_search_type', 'basic') == 'mysql_full') { - if ($search_string = trip_search_translate_keys($keys, 'mysql_full')) { - $query->wheres[] = 'MATCH (n.title,nr.body) AGAINST (\'' . $search_string . '\' IN BOOLEAN MODE)'; - } + if (variable_get('trip_search_type', 'basic') == 'mysql_full' && + ($search_string = trip_search_translate_keys($keys, 'mysql_full'))) { + $query->match = 'MATCH (n.title,nr.body) AGAINST (\'' . $search_string . '\' IN BOOLEAN MODE)'; } else { $query->fields = array('n.title', 'nr.body'); @@ -979,47 +984,34 @@ $query->joins .= ' LEFT JOIN {node_revisions} nr ON n.vid = nr.vid'; - if (module_exist('comment')) { - $query->fields[] = 'c.subject'; - $query->fields[] = 'c.comment'; - $query->joins .= ' LEFT JOIN {comments} c ON n.nid = c.nid'; - } if (module_exist('statistics') && variable_get('statistics_count_content_views', 0)) { $query->selects .= ',nc.totalcount'; $query->joins .= ' INNER JOIN {node_counter} nc ON n.nid = nc.nid'; $query->order_bys[] = 'nc.totalcount DESC'; } if ($keys->uid) { - $query->joins .= ' INNER JOIN {users} u ON n.uid = u.uid '; - $query->wheres[] = 'u.uid = ' . $keys->uid; + $query->wheres[] = 'n.uid = ' . $keys->uid; } elseif ($keys->user) { if ($user = db_fetch_object(db_query("SELECT uid, name FROM {users} WHERE name = '%s'", $keys->user))) { - $query->joins .= ' INNER JOIN {users} u ON n.uid = u.uid '; - $query->wheres[] = 'u.uid = ' . $user->uid; + $query->wheres[] = 'n.uid = ' . $user->uid; } else { drupal_set_message(t('Requested user "%user" not found.', array('%user' => $keys->user)), 'error'); return array(); } } - if ($keys->after && $keys->before) { - $query->wheres[] = 'n.created BETWEEN ' . $keys->after . ' AND ' . $keys->before; + if ($keys->after && $keys->before) { + $query->wheres[] = 'n.created BETWEEN '. $keys->after .' AND '. $keys->before; } - else { - if ($keys->after) { - $query->wheres[] = 'n.created > ' . $keys->after; - } - if ($keys->before) { - $query->wheres[] = 'n.created < ' . $keys->before; - } + else if ($keys->after) { + $query->wheres[] = 'n.created > '. $keys->after; + } + else if ($keys->before) { + $query->wheres[] = 'n.created < '. $keys->before; } if ($keys->type) { - $types = array(); - foreach ($keys->type as $type) { - $types[] = '(n.type = "' . $type . '")'; - } - $query->wheres[] = '(' . implode(' OR ', $types) . ')'; + $query->wheres[] = 'n.type '. (count($keys->type) > 1 ? "IN ('". implode("','", $keys->type) ."')" : "= '". $keys->type[0] ."'"); } if ($keys->term) { $depth = 0; @@ -1046,14 +1038,17 @@ if ($query->fields) { $query = trip_search_expand_query($query, $keys); } + else if ($query->match) { + $query->wheres[] = $query->match; + } switch ($op) { case 'feed': - $sql = "SELECT n.nid, " . $query->selects . " FROM {node} n " . $query->joins . " WHERE n.status = 1 AND " . implode(" AND ", $query->wheres) . " ORDER BY " . implode(",", $query->order_bys); + $sql = 'SELECT n.nid, '. $query->selects .' FROM {node} n '. $query->joins .' WHERE n.status = 1 AND '. implode(' AND ', $query->wheres) .' ORDER BY '. implode(',', $query->order_bys); $result = db_query_range(db_rewrite_sql($sql), 0, 500); print node_feed($result, NULL); break; case 'find': - $sql = "SELECT n.nid, " . $query->selects . " FROM {node} n " . $query->joins . " WHERE n.status = 1 AND " . implode(" AND ", $query->wheres) . " ORDER BY " . implode(",", $query->order_bys); + $sql = 'SELECT n.nid, '. $query->selects .' FROM {node} n '. $query->joins .' WHERE n.status = 1 AND '. implode(' AND ', $query->wheres) .' ORDER BY '. implode(',', $query->order_bys); $result = db_query_range(db_rewrite_sql($sql), 0, 500); if ($num = db_num_rows($result)) { while ($node = db_fetch_object($result)) { @@ -1071,7 +1066,7 @@ } return $find; case 'terms': - $sql = "SELECT DISTINCT(t.tid), t.name, COUNT(n.nid) AS count FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {term_data} t ON r.tid = t.tid " . $query->joins . " WHERE n.status = 1 AND " . implode(" AND ", $query->wheres) . " GROUP BY t.name ORDER BY t.name"; + $sql = 'SELECT DISTINCT(t.tid), t.name, COUNT(n.nid) AS count FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {term_data} t ON r.tid = t.tid '. $query->joins .' WHERE n.status = 1 AND '. implode(' AND ', $query->wheres) .' GROUP BY t.name ORDER BY t.name'; $result = db_query(db_rewrite_sql($sql)); $terms = array(); while ($term = db_fetch_object($result)) { @@ -1079,7 +1074,7 @@ } return $terms; case 'types': - $sql = "SELECT DISTINCT(n.type), COUNT(n.nid) AS count, n.nid, " . $query->selects . " FROM {node} n " . $query->joins . " WHERE n.status = 1 AND " . implode(" AND ", $query->wheres) . " GROUP BY n.type ORDER BY n.type"; + $sql = 'SELECT DISTINCT(n.type), COUNT(n.nid) AS count, n.nid, '. $query->selects .' FROM {node} n '. $query->joins .' WHERE n.status = 1 AND '. implode(' AND ', $query->wheres) .' GROUP BY n.type ORDER BY n.type'; $result = db_query(db_rewrite_sql($sql)); $types = array(); while ($type = db_fetch_object($result)) { @@ -1090,6 +1085,99 @@ return; } +function comment_trip_search($keys) { + if (!module_exist('comment')) { + return; + } + $max = variable_get('trip_search_query_max', 500); //unused + $query->selects = 'n.title,n.type,nr.body,n.sticky'; + $query->joins .= ' INNER JOIN {comments} c ON n.nid = c.nid'; + if (variable_get('trip_search_type', 'basic') == 'mysql_full' && + ($search_string = trip_search_translate_keys($keys, 'mysql_full'))) { + $query->match = 'MATCH (c.subject,c.comment) AGAINST (\''. $search_string .'\' IN BOOLEAN MODE)'; + } + else { + $query->fields = array('c.subject', 'c.comment'); + } + + $query->joins .= ' LEFT JOIN {node_revisions} nr ON n.vid = nr.vid'; + + if (module_exist('statistics') && variable_get('statistics_count_content_views', 0)) { + $query->selects .= ',nc.totalcount'; + $query->joins .= ' INNER JOIN {node_counter} nc ON n.nid = nc.nid'; + $query->order_bys[] = 'nc.totalcount DESC'; + } + if ($keys->uid) { + $query->wheres[] = 'c.uid = '. $keys->uid; + } + elseif ($keys->user) { + if ($user = db_fetch_object(db_query("SELECT uid, name FROM {users} WHERE name = '%s'", $keys->user))) { + $query->wheres[] = 'c.uid = '. $user->uid; + } + else { + // node_trip_search will report this error + return array(); + } + } + if ($keys->after && $keys->before) { + $query->wheres[] = 'c.timestamp BETWEEN '. $keys->after .' AND '. $keys->before; + } + else if ($keys->after) { + $query->wheres[] = 'c.timestamp > '. $keys->after; + } + else if ($keys->before) { + $query->wheres[] = 'c.timestamp < '. $keys->before; + } + if ($keys->type) { + $query->wheres[] = 'n.type '. (count($keys->type) > 1 ? "IN ('". implode("','", $keys->type) ."')" : "= '". $keys->type[0] ."'"); + } + if ($keys->term) { + $depth = 0; + foreach ($keys->term as $index => $tid) { + $term = taxonomy_get_term($tid); + $tree = taxonomy_get_tree($term->vid, $tid, -1, $depth); + $descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree)); + } + + if ($keys->tid_operator == 'OR') { + $str_tids = implode (',', call_user_func_array('array_merge', $descendant_tids)); + $query->joins .= ' INNER JOIN {term_node} tn ON n.nid = tn.nid '; + $query->wheres[] = 'tn.tid IN ('. $str_tids .')'; + } + else { + foreach ($descendant_tids as $index => $tids) { + $query->joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid'; + $query->wheres[] = 'tn'. $index .'.tid IN ('. implode (',', $tids) .')'; + } + } + } + $query->order_bys[] = 'n.sticky DESC'; + $query->order_bys[] = 'n.created DESC'; + if ($query->fields) { + $query = trip_search_expand_query($query, $keys); + } + else if ($query->match) { + $query->wheres[] = $query->match; + } + $sql = 'SELECT n.nid, '. $query->selects .' FROM {node} n '. $query->joins .' WHERE n.status = 1 AND '. implode(' AND ', $query->wheres) .' ORDER BY '. implode(',', $query->order_bys); + $result = db_query_range(db_rewrite_sql($sql), 0, 500); + if ($num = db_num_rows($result)) { + while ($node = db_fetch_object($result)) { + if (!$find[$node->nid]) { + $find[$node->nid]['score'] = 0; + if ($node->totalcount) { + $find[$node->nid]['hits'] = $node->totalcount; + } + $find[$node->nid]['id'] = $node->nid; + $find[$node->nid]['title'] = $node->title; + $find[$node->nid]['snippet'] = $node->body; + $find[$node->nid]['promote'] = $node->sticky; + } + } + } + return $find; +} + /* TODO: this is unused, it seems