diff options
Diffstat (limited to 'includes/specials/SpecialSearch.php')
-rw-r--r-- | includes/specials/SpecialSearch.php | 198 |
1 files changed, 116 insertions, 82 deletions
diff --git a/includes/specials/SpecialSearch.php b/includes/specials/SpecialSearch.php index 6c401486..8609c740 100644 --- a/includes/specials/SpecialSearch.php +++ b/includes/specials/SpecialSearch.php @@ -42,6 +42,9 @@ class SpecialSearch extends SpecialPage { /// Search engine protected $searchEngine; + /// Search engine type, if not default + protected $searchEngineType; + /// For links protected $extraParams = array(); @@ -98,6 +101,8 @@ class SpecialSearch extends SpecialPage { $this->load(); + $this->searchEngineType = $request->getVal( 'srbackend' ); + if ( $request->getVal( 'fulltext' ) || !is_null( $request->getVal( 'offset' ) ) || !is_null( $request->getVal( 'searchx' ) ) ) @@ -137,7 +142,7 @@ class SpecialSearch extends SpecialPage { if ( $profile === null ) { // BC with old request format $profile = 'advanced'; - foreach( $profiles as $key => $data ) { + foreach ( $profiles as $key => $data ) { if ( $nslist === $data['namespaces'] && $key !== 'advanced' ) { $profile = $key; } @@ -173,7 +178,7 @@ class SpecialSearch extends SpecialPage { # Try to go to page as entered. $t = Title::newFromText( $term ); # If the string cannot be used to create a title - if( is_null( $t ) ) { + if ( is_null( $t ) ) { $this->showResults( $term ); return; } @@ -185,19 +190,19 @@ class SpecialSearch extends SpecialPage { return; } - if( !is_null( $t ) ) { + if ( !is_null( $t ) ) { $this->getOutput()->redirect( $t->getFullURL() ); return; } # No match, generate an edit URL $t = Title::newFromText( $term ); - if( !is_null( $t ) ) { + if ( !is_null( $t ) ) { global $wgGoToEdit; wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) ); wfDebugLog( 'nogomatch', $t->getText(), false ); # If the feature is enabled, go straight to the edit page - if( $wgGoToEdit ) { + if ( $wgGoToEdit ) { $this->getOutput()->redirect( $t->getFullURL( array( 'action' => 'edit' ) ) ); return; } @@ -253,18 +258,24 @@ class SpecialSearch extends SpecialPage { $rewritten = $search->replacePrefixes( $term ); $titleMatches = $search->searchTitle( $rewritten ); - if( !( $titleMatches instanceof SearchResultTooMany ) ) { + if ( !( $titleMatches instanceof SearchResultTooMany ) ) { $textMatches = $search->searchText( $rewritten ); } + $textStatus = null; + if ( $textMatches instanceof Status ) { + $textStatus = $textMatches; + $textMatches = null; + } + // did you mean... suggestions - if( $textMatches && $textMatches->hasSuggestion() ) { + if ( $textMatches && !$textStatus && $textMatches->hasSuggestion() ) { $st = SpecialPage::getTitleFor( 'Search' ); # mirror Go/Search behavior of original request .. $didYouMeanParams = array( 'search' => $textMatches->getSuggestionQuery() ); - if( $this->fulltext != null ) { + if ( $this->fulltext != null ) { $didYouMeanParams['fulltext'] = $this->fulltext; } @@ -275,7 +286,7 @@ class SpecialSearch extends SpecialPage { $suggestionSnippet = $textMatches->getSuggestionSnippet(); - if( $suggestionSnippet == '' ) { + if ( $suggestionSnippet == '' ) { $suggestionSnippet = null; } @@ -317,14 +328,14 @@ class SpecialSearch extends SpecialPage { ); // Sometimes the search engine knows there are too many hits - if( $titleMatches instanceof SearchResultTooMany ) { + if ( $titleMatches instanceof SearchResultTooMany ) { $out->wrapWikiMsg( "==$1==\n", 'toomanymatches' ); wfProfileOut( __METHOD__ ); return; } $filePrefix = $wgContLang->getFormattedNsText( NS_FILE ) . ':'; - if( trim( $term ) === '' || $filePrefix === trim( $term ) ) { + if ( trim( $term ) === '' || $filePrefix === trim( $term ) ) { $out->addHTML( $this->formHeader( $term, 0, 0 ) ); $out->addHtml( $this->getProfileForm( $this->profile, $term ) ); $out->addHTML( '</form>' ); @@ -347,10 +358,12 @@ class SpecialSearch extends SpecialPage { // get total number of results if backend can calculate it $totalRes = 0; - if( $titleMatches && !is_null( $titleMatches->getTotalHits() ) ) + if ( $titleMatches && !is_null( $titleMatches->getTotalHits() ) ) { $totalRes += $titleMatches->getTotalHits(); - if( $textMatches && !is_null( $textMatches->getTotalHits() ) ) + } + if ( $textMatches && !is_null( $textMatches->getTotalHits() ) ) { $totalRes += $textMatches->getTotalHits(); + } // show number of results and current offset $out->addHTML( $this->formHeader( $term, $num, $totalRes ) ); @@ -360,7 +373,7 @@ class SpecialSearch extends SpecialPage { $out->addHtml( "<div class='searchresults'>" ); // prev/next links - if( $num || $this->offset ) { + if ( $num || $this->offset ) { // Show the create link ahead $this->showCreateLink( $t ); $prevnext = $this->getLanguage()->viewPrevNext( $this->getTitle(), $this->offset, $this->limit, @@ -374,40 +387,46 @@ class SpecialSearch extends SpecialPage { } $out->parserOptions()->setEditSection( false ); - if( $titleMatches ) { - if( $numTitleMatches > 0 ) { + if ( $titleMatches ) { + if ( $numTitleMatches > 0 ) { $out->wrapWikiMsg( "==$1==\n", 'titlematches' ); $out->addHTML( $this->showMatches( $titleMatches ) ); } $titleMatches->free(); } - if( $textMatches ) { + if ( $textMatches && !$textStatus ) { // output appropriate heading - if( $numTextMatches > 0 && $numTitleMatches > 0 ) { + if ( $numTextMatches > 0 && $numTitleMatches > 0 ) { // if no title matches the heading is redundant $out->wrapWikiMsg( "==$1==\n", 'textmatches' ); - } elseif( $totalRes == 0 ) { + } elseif ( $totalRes == 0 ) { # Don't show the 'no text matches' if we received title matches # $out->wrapWikiMsg( "==$1==\n", 'notextmatches' ); } // show interwiki results if any - if( $textMatches->hasInterwikiResults() ) { + if ( $textMatches->hasInterwikiResults() ) { $out->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(), $term ) ); } // show results - if( $numTextMatches > 0 ) { + if ( $numTextMatches > 0 ) { $out->addHTML( $this->showMatches( $textMatches ) ); } $textMatches->free(); } - if( $num === 0 ) { - $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>", array( 'search-nonefound', wfEscapeWikiText( $term ) ) ); - $this->showCreateLink( $t ); + if ( $num === 0 ) { + if ( $textStatus ) { + $out->addHTML( '<div class="error">' . + htmlspecialchars( $textStatus->getWikiText( 'search-error' ) ) . '</div>' ); + } else { + $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>", + array( 'search-nonefound', wfEscapeWikiText( $term ) ) ); + $this->showCreateLink( $t ); + } } $out->addHtml( "</div>" ); - if( $num || $this->offset ) { + if ( $num || $this->offset ) { $out->addHTML( "<p class='mw-search-pager-bottom'>{$prevnext}</p>\n" ); } wfRunHooks( 'SpecialSearchResultsAppend', array( $this, $out, $term ) ); @@ -421,16 +440,16 @@ class SpecialSearch extends SpecialPage { // show direct page/create link if applicable // Check DBkey !== '' in case of fragment link only. - if( is_null( $t ) || $t->getDBkey() === '' ) { + if ( is_null( $t ) || $t->getDBkey() === '' ) { // invalid title // preserve the paragraph for margins etc... $this->getOutput()->addHtml( '<p></p>' ); return; } - if( $t->isKnown() ) { + if ( $t->isKnown() ) { $messageName = 'searchmenu-exists'; - } elseif( $t->userCan( 'create', $this->getUser() ) ) { + } elseif ( $t->userCan( 'create', $this->getUser() ) ) { $messageName = 'searchmenu-new'; } else { $messageName = 'searchmenu-new-nocreate'; @@ -439,7 +458,7 @@ class SpecialSearch extends SpecialPage { wfRunHooks( 'SpecialSearchCreateLink', array( $t, &$params ) ); // Extensions using the hook might still return an empty $messageName - if( $messageName ) { + if ( $messageName ) { $this->getOutput()->wrapWikiMsg( "<p class=\"mw-search-createlink\">\n$1</p>", $params ); } else { // preserve the paragraph for margins etc... @@ -452,9 +471,9 @@ class SpecialSearch extends SpecialPage { */ protected function setupPage( $term ) { # Should advanced UI be used? - $this->searchAdvanced = ($this->profile === 'advanced'); + $this->searchAdvanced = ( $this->profile === 'advanced' ); $out = $this->getOutput(); - if( strval( $term ) !== '' ) { + if ( strval( $term ) !== '' ) { $out->setPageTitle( $this->msg( 'searchresults' ) ); $out->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams( $this->msg( 'searchresults-title' )->rawParams( $term )->text() @@ -473,8 +492,8 @@ class SpecialSearch extends SpecialPage { */ protected function powerSearch( &$request ) { $arr = array(); - foreach( SearchEngine::searchableNamespaces() as $ns => $name ) { - if( $request->getCheck( 'ns' . $ns ) ) { + foreach ( SearchEngine::searchableNamespaces() as $ns => $name ) { + if ( $request->getCheck( 'ns' . $ns ) ) { $arr[] = $ns; } } @@ -490,10 +509,10 @@ class SpecialSearch extends SpecialPage { protected function powerSearchOptions() { $opt = array(); $opt['redirs'] = $this->searchRedirects ? 1 : 0; - if( $this->profile !== 'advanced' ) { + if ( $this->profile !== 'advanced' ) { $opt['profile'] = $this->profile; } else { - foreach( $this->namespaces as $n ) { + foreach ( $this->namespaces as $n ) { $opt['ns' . $n] = 1; } } @@ -515,12 +534,12 @@ class SpecialSearch extends SpecialPage { $out = ""; $infoLine = $matches->getInfo(); - if( !is_null( $infoLine ) ) { + if ( !is_null( $infoLine ) ) { $out .= "\n<!-- {$infoLine} -->\n"; } $out .= "<ul class='mw-search-results'>\n"; $result = $matches->next(); - while( $result ) { + while ( $result ) { $out .= $this->showHit( $result, $terms ); $result = $matches->next(); } @@ -543,7 +562,7 @@ class SpecialSearch extends SpecialPage { protected function showHit( $result, $terms ) { wfProfileIn( __METHOD__ ); - if( $result->isBrokenTitle() ) { + if ( $result->isBrokenTitle() ) { wfProfileOut( __METHOD__ ); return "<!-- Broken link in search result -->\n"; } @@ -552,8 +571,9 @@ class SpecialSearch extends SpecialPage { $titleSnippet = $result->getTitleSnippet( $terms ); - if( $titleSnippet == '' ) + if ( $titleSnippet == '' ) { $titleSnippet = null; + } $link_t = clone $t; @@ -568,7 +588,7 @@ class SpecialSearch extends SpecialPage { //If page content is not readable, just return the title. //This is not quite safe, but better than showing excerpts from non-readable pages //Note that hiding the entry entirely would screw up paging. - if( !$t->userCan( 'read', $this->getUser() ) ) { + if ( !$t->userCan( 'read', $this->getUser() ) ) { wfProfileOut( __METHOD__ ); return "<li>{$link}</li>\n"; } @@ -576,7 +596,7 @@ class SpecialSearch extends SpecialPage { // If the page doesn't *exist*... our search index is out of date. // The least confusing at this point is to drop the result. // You may get less results, but... oh well. :P - if( $result->isMissingRevision() ) { + if ( $result->isMissingRevision() ) { wfProfileOut( __METHOD__ ); return "<!-- missing page " . htmlspecialchars( $t->getPrefixedText() ) . "-->\n"; } @@ -588,9 +608,10 @@ class SpecialSearch extends SpecialPage { $sectionText = $result->getSectionSnippet( $terms ); $redirect = ''; - if( !is_null( $redirectTitle ) ) { - if( $redirectText == '' ) + if ( !is_null( $redirectTitle ) ) { + if ( $redirectText == '' ) { $redirectText = null; + } $redirect = "<span class='searchalttitle'>" . $this->msg( 'search-redirect' )->rawParams( @@ -600,9 +621,10 @@ class SpecialSearch extends SpecialPage { $section = ''; - if( !is_null( $sectionTitle ) ) { - if( $sectionText == '' ) + if ( !is_null( $sectionTitle ) ) { + if ( $sectionText == '' ) { $sectionText = null; + } $section = "<span class='searchalttitle'>" . $this->msg( 'search-section' )->rawParams( @@ -616,7 +638,7 @@ class SpecialSearch extends SpecialPage { $lang = $this->getLanguage(); // format score - if( is_null( $result->getScore() ) ) { + if ( is_null( $result->getScore() ) ) { // Search engine doesn't report scoring info $score = ''; } else { @@ -632,7 +654,7 @@ class SpecialSearch extends SpecialPage { $size = $this->msg( 'search-result-size', $lang->formatSize( $byteSize ) ) ->numParams( $wordCount )->escaped(); - if( $t->getNamespace() == NS_CATEGORY ) { + if ( $t->getNamespace() == NS_CATEGORY ) { $cat = Category::newFromTitle( $t ); $size = $this->msg( 'search-result-category-size' ) ->numParams( $cat->getPageCount(), $cat->getSubcatCount(), $cat->getFileCount() ) @@ -643,7 +665,7 @@ class SpecialSearch extends SpecialPage { // link to related articles if supported $related = ''; - if( $result->hasRelated() ) { + if ( $result->hasRelated() ) { $st = SpecialPage::getTitleFor( 'Search' ); $stParams = array_merge( $this->powerSearchOptions(), @@ -663,11 +685,11 @@ class SpecialSearch extends SpecialPage { } // Include a thumbnail for media files... - if( $t->getNamespace() == NS_FILE ) { + if ( $t->getNamespace() == NS_FILE ) { $img = wfFindFile( $t ); - if( $img ) { + if ( $img ) { $thumb = $img->transform( array( 'width' => 120, 'height' => 120 ) ); - if( $thumb ) { + if ( $thumb ) { $desc = $this->msg( 'parentheses' )->rawParams( $img->getShortDesc() )->escaped(); wfProfileOut( __METHOD__ ); // Float doesn't seem to interact well with the bullets. @@ -693,7 +715,7 @@ class SpecialSearch extends SpecialPage { $html = null; - if ( wfRunHooks( 'ShowSearchHit', array ( + if ( wfRunHooks( 'ShowSearchHit', array( $this, $result, $terms, &$link, &$redirect, &$section, &$extract, &$score, &$size, &$date, &$related, @@ -721,23 +743,23 @@ class SpecialSearch extends SpecialPage { wfProfileIn( __METHOD__ ); $terms = $wgContLang->convertForSearchResult( $matches->termMatches() ); - $out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>". + $out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>" . $this->msg( 'search-interwiki-caption' )->text() . "</div>\n"; $out .= "<ul class='mw-search-iwresults'>\n"; // work out custom project captions $customCaptions = array(); $customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() ); // format per line <iwprefix>:<caption> - foreach( $customLines as $line ) { + foreach ( $customLines as $line ) { $parts = explode( ":", $line, 2 ); - if( count( $parts ) == 2 ) { // validate line + if ( count( $parts ) == 2 ) { // validate line $customCaptions[$parts[0]] = $parts[1]; } } $prev = null; $result = $matches->next(); - while( $result ) { + while ( $result ) { $out .= $this->showInterwikiHit( $result, $prev, $terms, $query, $customCaptions ); $prev = $result->getInterwikiPrefix(); $result = $matches->next(); @@ -762,10 +784,10 @@ class SpecialSearch extends SpecialPage { * * @return string */ - protected function showInterwikiHit( $result, $lastInterwiki, $terms, $query, $customCaptions) { + protected function showInterwikiHit( $result, $lastInterwiki, $terms, $query, $customCaptions ) { wfProfileIn( __METHOD__ ); - if( $result->isBrokenTitle() ) { + if ( $result->isBrokenTitle() ) { wfProfileOut( __METHOD__ ); return "<!-- Broken link in search result -->\n"; } @@ -774,8 +796,9 @@ class SpecialSearch extends SpecialPage { $titleSnippet = $result->getTitleSnippet( $terms ); - if( $titleSnippet == '' ) + if ( $titleSnippet == '' ) { $titleSnippet = null; + } $link = Linker::linkKnown( $t, @@ -786,9 +809,10 @@ class SpecialSearch extends SpecialPage { $redirectTitle = $result->getRedirectTitle(); $redirectText = $result->getRedirectSnippet( $terms ); $redirect = ''; - if( !is_null( $redirectTitle ) ) { - if( $redirectText == '' ) + if ( !is_null( $redirectTitle ) ) { + if ( $redirectText == '' ) { $redirectText = null; + } $redirect = "<span class='searchalttitle'>" . $this->msg( 'search-redirect' )->rawParams( @@ -798,8 +822,8 @@ class SpecialSearch extends SpecialPage { $out = ""; // display project name - if( is_null( $lastInterwiki ) || $lastInterwiki != $t->getInterwiki() ) { - if( array_key_exists( $t->getInterwiki(), $customCaptions ) ) { + if ( is_null( $lastInterwiki ) || $lastInterwiki != $t->getInterwiki() ) { + if ( array_key_exists( $t->getInterwiki(), $customCaptions ) ) { // captions from 'search-interwiki-custom' $caption = $customCaptions[$t->getInterwiki()]; } else { @@ -856,17 +880,21 @@ class SpecialSearch extends SpecialPage { * @return String: HTML form */ protected function powerSearchBox( $term, $opts ) { + global $wgContLang; + // Groups namespaces into rows according to subject $rows = array(); - foreach( SearchEngine::searchableNamespaces() as $namespace => $name ) { + foreach ( SearchEngine::searchableNamespaces() as $namespace => $name ) { $subject = MWNamespace::getSubject( $namespace ); - if( !array_key_exists( $subject, $rows ) ) { + if ( !array_key_exists( $subject, $rows ) ) { $rows[$subject] = ""; } - $name = str_replace( '_', ' ', $name ); - if( $name == '' ) { + + $name = $wgContLang->getConverter()->convertNamespace( $namespace ); + if ( $name == '' ) { $name = $this->msg( 'blanknamespace' )->text(); } + $rows[$subject] .= Xml::openElement( 'td', array( 'style' => 'white-space: nowrap' ) @@ -879,27 +907,30 @@ class SpecialSearch extends SpecialPage { ) . Xml::closeElement( 'td' ); } + $rows = array_values( $rows ); $numRows = count( $rows ); // Lays out namespaces in multiple floating two-column tables so they'll // be arranged nicely while still accommodating different screen widths $namespaceTables = ''; - for( $i = 0; $i < $numRows; $i += 4 ) { + for ( $i = 0; $i < $numRows; $i += 4 ) { $namespaceTables .= Xml::openElement( 'table', array( 'cellpadding' => 0, 'cellspacing' => 0 ) ); - for( $j = $i; $j < $i + 4 && $j < $numRows; $j++ ) { + + for ( $j = $i; $j < $i + 4 && $j < $numRows; $j++ ) { $namespaceTables .= Xml::tags( 'tr', null, $rows[$j] ); } + $namespaceTables .= Xml::closeElement( 'table' ); } $showSections = array( 'namespaceTables' => $namespaceTables ); // Show redirects check only if backend supports it - if( $this->getSearchEngine()->supports( 'list-redirects' ) ) { + if ( $this->getSearchEngine()->supports( 'list-redirects' ) ) { $showSections['redirects'] = Xml::checkLabel( $this->msg( 'powersearch-redir' )->text(), 'redirs', 'redirs', $this->searchRedirects ); } @@ -908,12 +939,11 @@ class SpecialSearch extends SpecialPage { $hidden = ''; unset( $opts['redirs'] ); - foreach( $opts as $key => $value ) { + foreach ( $opts as $key => $value ) { $hidden .= Html::hidden( $key, $value ); } // Return final output - return - Xml::openElement( + return Xml::openElement( 'fieldset', array( 'id' => 'mw-searchoptions', 'style' => 'margin:0em;' ) ) . @@ -969,8 +999,10 @@ class SpecialSearch extends SpecialPage { wfRunHooks( 'SpecialSearchProfiles', array( &$profiles ) ); - foreach( $profiles as &$data ) { - if ( !is_array( $data['namespaces'] ) ) continue; + foreach ( $profiles as &$data ) { + if ( !is_array( $data['namespaces'] ) ) { + continue; + } sort( $data['namespaces'] ); } @@ -987,7 +1019,7 @@ class SpecialSearch extends SpecialPage { $out = Xml::openElement( 'div', array( 'class' => 'mw-search-formheader' ) ); $bareterm = $term; - if( $this->startsWithImage( $term ) ) { + if ( $this->startsWithImage( $term ) ) { // Deletes prefixes $bareterm = substr( $term, strpos( $term, ':' ) + 1 ); } @@ -1081,7 +1113,7 @@ class SpecialSearch extends SpecialPage { */ protected function makeSearchLink( $term, $namespaces, $label, $tooltip, $params = array() ) { $opt = $params; - foreach( $namespaces as $n ) { + foreach ( $namespaces as $n ) { $opt['ns' . $n] = 1; } $opt['redirs'] = $this->searchRedirects; @@ -1098,7 +1130,8 @@ class SpecialSearch extends SpecialPage { 'a', array( 'href' => $this->getTitle()->getLocalURL( $stParams ), - 'title' => $tooltip), + 'title' => $tooltip + ), $label ); } @@ -1113,7 +1146,7 @@ class SpecialSearch extends SpecialPage { global $wgContLang; $p = explode( ':', $term ); - if( count( $p ) > 1 ) { + if ( count( $p ) > 1 ) { return $wgContLang->getNsIndex( $p[0] ) == NS_FILE; } return false; @@ -1130,7 +1163,7 @@ class SpecialSearch extends SpecialPage { $allkeyword = $this->msg( 'searchall' )->inContentLanguage()->text(); $p = explode( ':', $term ); - if( count( $p ) > 1 ) { + if ( count( $p ) > 1 ) { return $p[0] == $allkeyword; } return false; @@ -1143,7 +1176,8 @@ class SpecialSearch extends SpecialPage { */ public function getSearchEngine() { if ( $this->searchEngine === null ) { - $this->searchEngine = SearchEngine::create(); + $this->searchEngine = $this->searchEngineType ? + SearchEngine::create( $this->searchEngineType ) : SearchEngine::create(); } return $this->searchEngine; } @@ -1162,6 +1196,6 @@ class SpecialSearch extends SpecialPage { } protected function getGroupName() { - return 'redirects'; + return 'pages'; } } |