Prechádzať zdrojové kódy

! fix for certain search terms not being correctly highlighted in the returned results
! fix to allow like/rlike search terms during fulltext searches. Stops the sending of some search words that would be excluded by the fulltext search engine (<min_word_length and a limited set of special characters)

Spuds 12 rokov pred
rodič
commit
2fc9c74037
2 zmenil súbory, kde vykonal 27 pridanie a 8 odobranie
  1. 8 5
      Sources/Search.php
  2. 19 3
      Sources/SearchAPI-Fulltext.php

+ 8 - 5
Sources/Search.php

@@ -708,6 +708,7 @@ function PlushSearch2()
 			'words' => array(),
 			'subject_words' => array(),
 			'all_words' => array(),
+			'complex_words' => array(),
 		);
 
 		// Sort the indexed words (large words -> small words -> excluded words).
@@ -752,6 +753,7 @@ function PlushSearch2()
 		{
 			$searchWords[$orIndex]['indexed_words'] = array_slice($searchWords[$orIndex]['indexed_words'], 0, 7);
 			$searchWords[$orIndex]['subject_words'] = array_slice($searchWords[$orIndex]['subject_words'], 0, 7);
+			$searchWords[$orIndex]['words'] = array_slice($searchWords[$orIndex]['words'], 0, 4);
 		}
 	}
 
@@ -1821,7 +1823,7 @@ function PlushSearch2()
  *
  * What it does:
  * - callback function for the results sub template.
-		- loads the necessary contextual data to show a search result.
+ * - loads the necessary contextual data to show a search result.
  *
  * @param $reset = false
  * @return array
@@ -2055,6 +2057,7 @@ function prepareSearchContext($reset = false)
 	{
 		// Fix the international characters in the keyword too.
 		$query = un_htmlspecialchars($query);
+		$query = trim($query, "\*+");
 		$query = strtr($smcFunc['htmlspecialchars']($query), array('\\\'' => '\''));
 
 		$body_highlighted = preg_replace('/((<[^>]*)|' . preg_quote(strtr($query, array('\'' => '&#039;')), '/') . ')/ie' . ($context['utf8'] ? 'u' : ''), "'\$2' == '\$1' ? stripslashes('\$1') : '<strong class=\"highlight\">\$1</strong>'", $body_highlighted);
@@ -2087,10 +2090,10 @@ function prepareSearchContext($reset = false)
 	return $output;
 }
 
-/*
+/**
  * Creates a search API and returns the object.
  *
-*/
+ */
 function findSearchAPI()
 {
 	global $sourcedir, $modSettings, $search_versions, $searchAPI, $txt;
@@ -2127,8 +2130,8 @@ function findSearchAPI()
 /**
  * This function compares the length of two strings plus a little.
  * What it does:
-		- callback function for usort used to sort the fulltext results.
-		- passes sorting duty to the current API.
+ * - callback function for usort used to sort the fulltext results.
+ * - passes sorting duty to the current API.
  *
  * @param string $a
  * @param string $b

+ 19 - 3
Sources/SearchAPI-Fulltext.php

@@ -114,13 +114,23 @@ class fulltext_search
 	// Do we have to do some work with the words we are searching for to prepare them?
 	public function prepareIndexes($word, &$wordsSearch, &$wordsExclude, $isExcluded)
 	{
-		global $modSettings;
+		global $modSettings, $smcFunc;
 
 		$subwords = text2words($word, null, false);
 
 		if (!$this->canDoBooleanSearch && count($subwords) > 1 && empty($modSettings['search_force_index']))
 			$wordsSearch['words'][] = $word;
-
+		// boolean capable search engine but perhaps using special characters or a short word and not forced to only use an index, Regex it is then
+		elseif (empty($modSettings['search_force_index']) && $this->canDoBooleanSearch)
+		{
+			if ((count($subwords) > 1 && preg_match('~[.:@]~', $word)) || ($smcFunc['strlen'](trim($word, "/*- ")) < $this->min_word_length))
+			{
+				// this will be used in a LIKE or RLIKE term, we will remove it (later) from our indexed_words array
+				$wordsSearch['words'][] = trim($word, "/*- ");
+				$wordsSearch['complex_words'][] = count($subwords) === 1 ? $word : '"' . $word . '"';
+			}
+		}
+		
 		if ($this->canDoBooleanSearch)
 		{
 			$fulltextWord = count($subwords) === 1 ? $word : '"' . $word . '"';
@@ -208,11 +218,17 @@ class fulltext_search
 		elseif ($this->canDoBooleanSearch)
 		{
 			$query_params['boolean_match'] = '';
+
+			// remove any indexed words that are used in the complex body search terms
+			$words['indexed_words'] = array_diff($words['indexed_words'], $words['complex_words']);
+
 			foreach ($words['indexed_words'] as $fulltextWord)
 				$query_params['boolean_match'] .= (in_array($fulltextWord, $query_params['excluded_index_words']) ? '-' : '+') . $fulltextWord . ' ';
 			$query_params['boolean_match'] = substr($query_params['boolean_match'], 0, -1);
 
-			$query_where[] = 'MATCH (body) AGAINST ({string:boolean_match} IN BOOLEAN MODE)';
+			// if we have bool terms to search, add them in
+			if ($query_params['boolean_match'])
+				$query_where[] = 'MATCH (body) AGAINST ({string:boolean_match} IN BOOLEAN MODE)';
 		}
 		else
 		{