Fix highlighting of results when the search result does not return termMatches
authorStephan Gambke <s7eph4n@gmail.com>
Mon, 18 Aug 2014 15:55:51 +0000 (15:55 +0000)
committer[[mw:User:F.trott]] <gerritpatchuploader@gmail.com>
Mon, 18 Aug 2014 15:55:51 +0000 (15:55 +0000)
If the search engine does not know the concept of serch terms the search
result object will just return an empty array as defined in class
SearchResultSet.

In this case SearchHighlighter::highlightSimple will place a span between
each and every byte (yes, byte, not character, it will break multibyte
chars).

This patch will just output the first few lines of a page if no search
terms are available for highlighting.

Note: Highlighting the page name in the case of title matches is
questionable, IMHO. It might make more sense for this case as well to
just return the first few lines of the page.

Change-Id: I276418f271855fb99443188f51cc076289c6ba0d

includes/search/SearchHighlighter.php
includes/search/SearchResult.php

index 6953462..7e5f685 100644 (file)
@@ -554,4 +554,21 @@ class SearchHighlighter {
 
                return $extract;
        }
+
+       /**
+        * Returns the first few lines of the text
+        *
+        * @param string $text
+        * @param int $contextlines max number of returned lines
+        * @param int $contextchars average number of characters per line
+        * @return string
+        */
+       public function highlightNone( $text, $contextlines, $contextchars) {
+               $match = array();
+               $text = ltrim( $text ) . "\n"; // make sure the preg_match may find the last line
+               $text = str_replace( "\n\n", "\n", $text); // remove empty lines
+               preg_match( "/^(.*\n){0,$contextlines}/", $text , $match);
+               $text = htmlspecialchars( substr( trim( $match[0] ), 0, $contextlines * $contextchars ) ); // trim and limit to max number of chars
+               return str_replace( "\n", '<br>', $text );
+       }
 }
index d51bff7..1d28691 100644 (file)
@@ -166,11 +166,16 @@ class SearchResult {
 
                // TODO: make highliter take a content object. Make ContentHandler a factory for SearchHighliter.
                list( $contextlines, $contextchars ) = SearchEngine::userHighlightPrefs();
+
                $h = new SearchHighlighter();
-               if ( $wgAdvancedSearchHighlighting ) {
-                       return $h->highlightText( $this->mText, $terms, $contextlines, $contextchars );
+               if ( count( $terms ) > 0 ) {
+                       if ( $wgAdvancedSearchHighlighting ) {
+                               return $h->highlightText( $this->mText, $terms, $contextlines, $contextchars );
+                       } else {
+                               return $h->highlightSimple( $this->mText, $terms, $contextlines, $contextchars );
+                       }
                } else {
-                       return $h->highlightSimple( $this->mText, $terms, $contextlines, $contextchars );
+                       return $h->highlightNone( $this->mText, $contextlines, $contextchars );
                }
        }