Commits

Wez Furlong committed 4e80c2b

add in search excepting and highlighting

Comments (0)

Files changed (2)

   margin: 0;
 }
 
+div.excerpt span.hl {
+  background-color: yellow;
+}
+
 /* vim:ts=2:sw=2:et:
  */
 }
 
 $idx = MTrackSearchDB::get();
-//$term = new Zend_Search_Lucene_Index_Term($q);
-//$query = new Zend_Search_Lucene_Search_Query_Fuzzy($term);
-$query = $q;
+$query = Zend_Search_Lucene_Search_QueryParser::parse($q);
 
 $hits = $idx->find($query);
 
 <table class='searchresults'>
 <?php
 
+/* the highlighter insists on using html document things,
+ * so we force in our own dummy so that we can present the
+ * same text we used initially */
+class DummyDocument {
+  public $text;
+  function __construct($text) {
+    $this->text = $text;
+  }
+  function getFieldUtf8Value($name) {
+    return $this->text;
+  }
+}
+
+class MTrackHLText 
+    implements Zend_Search_Lucene_Search_Highlighter_Interface {
+  public $doc;
+  public $context = array();
+  public $text;
+  public $matched = array();
+
+  function setDocument(Zend_Search_Lucene_Document_Html $doc)
+  {
+    /* sure, I'll get right on that... */
+  }
+
+  function getDocument() {
+    /* we just return our dummy doc instead */
+    return $this->doc;
+  }
+
+  function highlight($words) {
+    if (!is_array($words)) {
+      $words = array($words);
+    }
+    foreach ($words as $word) {
+      foreach ($this->text as $line) {
+        $x = strpos($line, $word);
+        if ($x !== false) {
+          $this->matched[$word]++;
+          $this->context[$line]++;
+        }
+      }
+    }
+  }
+
+  function __construct($text, $query)
+  {
+    $this->doc = new DummyDocument($text);
+    $text = wordwrap($text);
+    $this->text = preg_split("/\r?\n/", $text);
+    $query->highlightMatches($text, 'utf-8', $this);
+  }
+}
+
+function excerpt($text, $query)
+{
+  $hl = new MTrackHLText($text, $query);
+  $lines = array();
+  foreach ($hl->context as $line => $count) {
+    $line = htmlentities($line, ENT_QUOTES, 'utf-8');
+    foreach ($hl->matched as $word => $wcount) {
+      $line = str_replace($word, "<span class='hl'>$word</span>", $line);
+    }
+    $lines[] = $line;
+    if (count($lines) > 6) {
+      break;
+    }
+  }
+  $ex = join(" &hellip; ", $lines);
+  if (strlen($ex)) {
+    return "<div class='excerpt'>$ex</div>";
+  }
+  return '';
+}
+
 foreach ($hits_by_object as $object => $score) {
   list($item, $id) = explode(':', $object, 2);
 
         echo "<del>";
       }
       echo "</a>";
+      echo excerpt($tkt->description, $query);
+
       break;
     case 'wiki':
       $wiki = MTrackWikiItem::loadByPageName($id);
       $url = "$ABSWEB/wiki.php/$id";
       echo "<a href='$url'>",
         htmlentities($id, ENT_QUOTES, 'utf-8'),
-        "</a>";
+        "</a>" . excerpt($wiki->content, $query);
       break;
     default:
       echo $object;