diff options
Diffstat (limited to 'includes/SearchEngine.php')
-rw-r--r-- | includes/SearchEngine.php | 138 |
1 files changed, 92 insertions, 46 deletions
diff --git a/includes/SearchEngine.php b/includes/SearchEngine.php index edd93cce..3ea0341d 100644 --- a/includes/SearchEngine.php +++ b/includes/SearchEngine.php @@ -13,6 +13,7 @@ class SearchEngine { var $limit = 10; var $offset = 0; + var $prefix = ''; var $searchTerms = array(); var $namespaces = array( NS_MAIN ); var $showRedirects = false; @@ -43,6 +44,19 @@ class SearchEngine { return null; } + /** If this search backend can list/unlist redirects */ + function acceptListRedirects() { + return true; + } + + /** + * Transform search term in cases when parts of the query came as different GET params (when supported) + * e.g. for prefix queries: search=test&prefix=Main_Page/Archive -> test prefix:Main Page/Archive + */ + function transformSearchTerm( $term ) { + return $term; + } + /** * If an exact title match can be find, or a very slightly close match, * return the title. If no match, returns NULL. @@ -98,19 +112,6 @@ class SearchEngine { return $title; } - global $wgCapitalLinks, $wgContLang; - if( !$wgCapitalLinks ) { - // Catch differs-by-first-letter-case-only - $title = Title::newFromText( $wgContLang->ucfirst( $term ) ); - if ( $title && $title->exists() ) { - return $title; - } - $title = Title::newFromText( $wgContLang->lcfirst( $term ) ); - if ( $title && $title->exists() ) { - return $title; - } - } - // Give hooks a chance at better match variants $title = null; if( !wfRunHooks( 'SearchGetNearMatch', array( $term, &$title ) ) ) { @@ -135,7 +136,7 @@ class SearchEngine { # Go to images that exist even if there's no local page. # There may have been a funny upload, or it may be on a shared # file repository such as Wikimedia Commons. - if( $title->getNamespace() == NS_IMAGE ) { + if( $title->getNamespace() == NS_FILE ) { $image = wfFindFile( $title ); if( $image ) { return $title; @@ -158,7 +159,7 @@ class SearchEngine { } public static function legalSearchChars() { - return "A-Za-z_'0-9\\x80-\\xFF\\-"; + return "A-Za-z_'.0-9\\x80-\\xFF\\-"; } /** @@ -275,7 +276,51 @@ class SearchEngine { return array_keys($wgNamespacesToBeSearchedDefault, true); } - + + /** + * Get a list of namespace names useful for showing in tooltips + * and preferences + * + * @param unknown_type $namespaces + */ + public static function namespacesAsText( $namespaces ){ + global $wgContLang; + + $formatted = array_map( array($wgContLang,'getFormattedNsText'), $namespaces ); + foreach( $formatted as $key => $ns ){ + if ( empty($ns) ) + $formatted[$key] = wfMsg( 'blanknamespace' ); + } + return $formatted; + } + + /** + * An array of "project" namespaces indexes typically searched + * by logged-in users + * + * @return array + * @static + */ + public static function projectNamespaces() { + global $wgNamespacesToBeSearchedDefault, $wgNamespacesToBeSearchedProject; + + return array_keys( $wgNamespacesToBeSearchedProject, true ); + } + + /** + * An array of "project" namespaces indexes typically searched + * by logged-in users in addition to the default namespaces + * + * @return array + * @static + */ + public static function defaultAndProjectNamespaces() { + global $wgNamespacesToBeSearchedDefault, $wgNamespacesToBeSearchedProject; + + return array_keys( $wgNamespacesToBeSearchedDefault + + $wgNamespacesToBeSearchedProject, true); + } + /** * Return a 'cleaned up' search string * @@ -290,24 +335,17 @@ class SearchEngine { * Load up the appropriate search engine class for the currently * active database backend, and return a configured instance. * - * @fixme Ask the database class for his default search class - * instead of knowing about every backend here. * @return SearchEngine */ public static function create() { - global $wgDBtype, $wgSearchType; + global $wgSearchType; + $dbr = wfGetDB( DB_SLAVE ); if( $wgSearchType ) { $class = $wgSearchType; - } elseif( $wgDBtype == 'mysql' ) { - $class = 'SearchMySQL'; - } else if ( $wgDBtype == 'postgres' ) { - $class = 'SearchPostgres'; - } else if ( $wgDBtype == 'oracle' ) { - $class = 'SearchOracle'; } else { - $class = 'SearchEngineDummy'; + $class = $dbr->getSearchEngine(); } - $search = new $class( wfGetDB( DB_SLAVE ) ); + $search = new $class( $dbr ); $search->setLimitOffset(0,0); return $search; } @@ -345,11 +383,11 @@ class SearchEngine { */ public static function getOpenSearchTemplate() { global $wgOpenSearchTemplate, $wgServer, $wgScriptPath; - if($wgOpenSearchTemplate) + if( $wgOpenSearchTemplate ) { return $wgOpenSearchTemplate; - else{ - $ns = implode(',',SearchEngine::defaultNamespaces()); - if(!$ns) $ns = "0"; + } else { + $ns = implode( '|', SearchEngine::defaultNamespaces() ); + if( !$ns ) $ns = "0"; return $wgServer . $wgScriptPath . '/api.php?action=opensearch&search={searchTerms}&namespace='.$ns; } } @@ -432,7 +470,7 @@ class SearchResultSet { } /** - * @return string highlighted suggested query, '' if none + * @return string HTML highlighted suggested query, '' if none */ function getSuggestionSnippet(){ return ''; @@ -503,11 +541,15 @@ class SearchResultTooMany { */ class SearchResult { var $mRevision = null; + var $mImage = null; - function SearchResult( $row ) { + function __construct( $row ) { $this->mTitle = Title::makeTitle( $row->page_namespace, $row->page_title ); - if( !is_null($this->mTitle) ) + if( !is_null($this->mTitle) ){ $this->mRevision = Revision::newFromTitle( $this->mTitle ); + if( $this->mTitle->getNamespace() === NS_FILE ) + $this->mImage = wfFindFile( $this->mTitle ); + } } /** @@ -529,9 +571,7 @@ class SearchResult { * @access public */ function isMissingRevision(){ - if( !$this->mRevision ) - return true; - return false; + return !$this->mRevision && !$this->mImage; } /** @@ -554,7 +594,11 @@ class SearchResult { */ protected function initText(){ if( !isset($this->mText) ){ - $this->mText = $this->mRevision->getText(); + if($this->mRevision != null) + $this->mText = $this->mRevision->getText(); + else // TODO: can we fetch raw wikitext for commons images? + $this->mText = ''; + } } @@ -614,7 +658,11 @@ class SearchResult { * @return string timestamp */ function getTimestamp(){ - return $this->mRevision->getTimestamp(); + if( $this->mRevision ) + return $this->mRevision->getTimestamp(); + else if( $this->mImage ) + return $this->mImage->getTimestamp(); + return ''; } /** @@ -706,7 +754,7 @@ class SearchHighlighter { if($key == 2){ // see if this is an image link $ns = substr($val[0],2,-1); - if( $wgContLang->getNsIndex($ns) != NS_IMAGE ) + if( $wgContLang->getNsIndex($ns) != NS_FILE ) break; } @@ -761,13 +809,12 @@ class SearchHighlighter { // prepare regexps foreach( $terms as $index => $term ) { - $terms[$index] = preg_quote( $term, '/' ); // manually do upper/lowercase stuff for utf-8 since PHP won't do it if(preg_match('/[\x80-\xff]/', $term) ){ $terms[$index] = preg_replace_callback('/./us',array($this,'caseCallback'),$terms[$index]); + } else { + $terms[$index] = $term; } - - } $anyterm = implode( '|', $terms ); $phrase = implode("$wgSearchHighlightBoundaries+", $terms ); @@ -1077,7 +1124,7 @@ class SearchHighlighter { global $wgContLang; $ns = substr( $matches[1], 0, $colon ); $index = $wgContLang->getNsIndex($ns); - if( $index !== false && ($index == NS_IMAGE || $index == NS_CATEGORY) ) + if( $index !== false && ($index == NS_FILE || $index == NS_CATEGORY) ) return $matches[0]; // return the whole thing else return $matches[2]; @@ -1097,11 +1144,10 @@ class SearchHighlighter { public function highlightSimple( $text, $terms, $contextlines, $contextchars ) { global $wgLang, $wgContLang; $fname = __METHOD__; - + $lines = explode( "\n", $text ); $terms = implode( '|', $terms ); - $terms = str_replace( '/', "\\/", $terms); $max = intval( $contextchars ) + 1; $pat1 = "/(.*)($terms)(.{0,$max})/i"; |