/** * Prepares the search text for use in a full-text query * * @param string Raw query text with AND, OR, and NOT * @param array (Output) Array of errors * * @return string Full-text query */ function prepare_search_text($query_text, &$errors) { $old_ft_search = $this->registry->options['fulltextsearch']; $this->registry->options['fulltextsearch'] = 1; // look for entire words that consist of "Ӓ". MySQL boolean // search will tokenize them seperately. Wrap them in quotes if they're // not already to emulate search for exactly that word. $query = explode('"', $query_text); $query_part_count = count($query); $query_text = ''; for ($i = 0; $i < $query_part_count; $i++) { // exploding by " means the 0th, 2nd, 4th... entries in the array // are outside of quotes if ($i % 2 == 1) { // 1st, 3rd.. entry = in quotes $query_text .= '"' . $query["{$i}"] . '"'; } else { // look for words that are entirely Ӓ $query_text .= preg_replace('/(?<=^|\\s)((&#[0-9]+;)+)(?=\\s|$)/', '"$1"', $query["{$i}"]); } } $query_text = preg_replace('#"([^"]+)"#sie', "stripslashes(str_replace(' ' , '*', '\\0'))", $query_text); require_once DIR . '/includes/functions_search.php'; $query_text = sanitize_search_query($query_text, $errors); if (!$errors) { // a tokenizing based approach to building a search query preg_match_all('#("[^"]*"|[^\\s]+)#', $query_text, $matches, PREG_SET_ORDER); $new_query_text = ''; $token_joiner = null; foreach ($matches as $match) { if ($match[1][0] == '-') { // NOT has already been converted $new_query_text = "({$new_query_text}) {$match['1']}"; continue; } switch (strtoupper($match[1])) { case 'OR': case 'AND': case 'NOT': // this isn't a searchable word, but a joiner $token_joiner = strtoupper($match[1]); break; default: verify_word_allowed($match[1]); if ($new_query_text !== '') { switch ($token_joiner) { case 'OR': // OR is no operator $new_query_text .= " {$match['1']}"; break; case 'NOT': // NOT this, but everything before it $new_query_text = "({$new_query_text}) -{$match['1']}"; break; case 'AND': default: // if we didn't have a joiner, default to and $new_query_text = "+({$new_query_text}) +{$match['1']}"; break; } } else { $new_query_text = $match[1]; } $token_joiner = null; } } $query_text = $new_query_text; } $this->registry->options['fulltextsearch'] = $old_ft_search; return trim($query_text); }
$query_parts .= ' '; } $space_skipped = true; if (preg_match('/(&#[0-9]+;|\\.|-)/s', $query_part)) { $query_parts .= '"' . $query_part . '"'; } else { $query_parts .= $query_part; } } $vbulletin->GPC['query'] .= $query_parts; } } $vbulletin->GPC['query'] = preg_replace('#"([^"]+)"#sie', "stripslashes(str_replace(' ' , '*', '\\0'))", $vbulletin->GPC['query']); // what about replacement words?? } $vbulletin->GPC['query'] = sanitize_search_query($vbulletin->GPC['query'], $errors); } if (empty($errors)) { // ############################################################################# // get forums in which to search $forumchoice = implode(',', fetch_search_forumids($vbulletin->GPC['forumchoice'], $vbulletin->GPC['childforums'])); // get prefixes if (in_array('', $vbulletin->GPC['prefixchoice']) or empty($vbulletin->GPC['prefixchoice'])) { // any prefix $vbulletin->GPC['prefixchoice'] = array(); $prefixchoice = ''; $display_prefixes = array(); } else { $vbulletin->GPC['prefixchoice'] = array_unique($vbulletin->GPC['prefixchoice']); $prefixchoice = implode(',', $vbulletin->GPC['prefixchoice']); $display_prefixes = $vbulletin->GPC['prefixchoice'];
/** * Set the keywords * * @param string $keywords * @param bool $titleonly true if onl */ public function add_keyword_filter($keywords, $titleonly) { if (!trim($keywords)) { return; } $this->raw_keywords = $keywords; $this->titleonly = $titleonly; //this needs to be before sanitize for historical reasons. //sanitize probably needs to go away, but now is not the time. $keywords = $this->quote_problem_words($keywords); $errors = array(); require_once DIR . '/includes/functions_search.php'; $keywords = sanitize_search_query($keywords, $errors); if (count($errors)) { $this->errors = array_merge($this->errors, $errors); return; } //parse the query string into the words array. $words = $this->get_words($keywords); $this->keywords = $words; //set the keywords display $display_string = $this->format_keyword_display_string($words); $this->set_keyword_display_string($display_string); //set the words to highlight $highlights = array(); foreach ($words as $word_item) { if ($word_item['joiner'] != 'NOT') { $highlights[] = $word_item['word']; } } $this->set_highlights($highlights); $this->criteria_set = true; }