Extension:RigorousSearch/1.0

''' \n";

// Perform the search, and get the match count and results list. $matches = 0; foreach ($spaces as $ns => $nsname) { $hits = $this->doSearch($db, $ns, $nsname, $pattern); $count = count($hits);

// Output the results for this namespace, if any. if ($count != 0) { // Output the namespace header. if ($ns == 0) $head = "Article Namespace"; else $head = $nsname. " Namespace"; $out .= " '''". $head. ":''' ";               $out .= $this->matchCount($count). ".\n";

// Output the hit list. foreach ($hits as $hit) $out .= "* " . $hit . "\n";

$out .= "\n\n\n"; $matches += $count; }       }

// If we got no hits at all, say so. if ($matches == 0) { $out .= $this->matchCount($matches). ".\n"; $out .= "\n\n\n"; }

// Let's not bother with the TOC. $out .= "\n";

return $out; }

/*    * Perform a search for the given pattern in a specified namespace. *    $db           Database handle *    $ns           Namespace ID to search *    $nsname       Name of the namespace (null for Main) *    $pattern      Pattern to search for *    * Returns a list of the page titles which match. */   function doSearch(&$db, $ns, $nsname, $pattern) { $matchingPages = array;

// Escape the pattern string. escapeLike does normal MySQL escaping, // plus additional processing necessary for LIKE. $pattern = $db->escapeLike($pattern);

// Select every page in the given namespace. If we fail, return an       // empty result. $pageCond = array('page_namespace' => $ns); $pageResult = $db->select('page', '*', $pageCond); if (!$pageResult) return array(0, null);

// Process each page we found. while ($pageRow = $db->fetchObject($pageResult)) { // Now select the revision data for the page's latest rev. // If we can't, pass on this page. $revCond = array('rev_id' => $pageRow->page_latest); $revRow = $db->selectRow('revision', 'rev_text_id', $revCond); if (!$revRow) continue; $text_id = $revRow->rev_text_id;

// Now select the text for the revision, if it matches the pattern. $queryTxt = "SELECT old_text FROM ". $db->tableName('text'). " WHERE old_id = ". $text_id. " AND old_text LIKE '%". $pattern. "%'";           $textResult = $db->query($queryTxt); if (!$textResult) continue;

// If it matches, list and count it. if ($db->numRows($textResult) > 0) { // Get the page title. $title = Title::makeTitle($ns, $pageRow->page_title); $link = $title->getFullText;

// Add to the results. $matchingPages[] = $link; }

$db->freeResult($textResult); }

$db->freeResult($pageResult);

return $matchingPages; }

/*    * Create and return the HTML markup for the search form. *    $pattern          the default value for the pattern field *    $nameSpaces       the list of searchable namespaces *    $searchSpaces     the list of namespaces currently selected */   function searchForm($pattern, &$nameSpaces, &$searchSpaces) { $out = '';

// The form header, which links back to this page. $title = Title::makeTitle(NS_SPECIAL,'RigorousSearch'); $action = $title->escapeLocalURL; $out .= "\n";

// The search text field. $pattern = htmlspecialchars($pattern); $out .= " Search for \n";

// The search button. $out .= " \n";

// The table of namespace checkboxes. $out .= " \n";

$out .= " \n";

return $out; }

/*    * Make a message describing a match count. */   function matchCount($num) { if ($num == 0) return "No matches"; return $num. ($num == 1 ? " match" : " matches"); }

}