From 222b01f5169f1c7e69762e0e8904c24f78f71882 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 28 Jul 2010 11:52:48 +0200 Subject: update to MediaWiki 1.16.0 --- includes/specials/SpecialSearch.php | 1419 ++++++++++++----------------------- 1 file changed, 471 insertions(+), 948 deletions(-) (limited to 'includes/specials/SpecialSearch.php') diff --git a/includes/specials/SpecialSearch.php b/includes/specials/SpecialSearch.php index cb783819..da054e02 100644 --- a/includes/specials/SpecialSearch.php +++ b/includes/specials/SpecialSearch.php @@ -29,16 +29,15 @@ * @param $par String: (default '') */ function wfSpecialSearch( $par = '' ) { - global $wgRequest, $wgUser, $wgUseOldSearchUI; + global $wgRequest, $wgUser; // Strip underscores from title parameter; most of the time we'll want // text form here. But don't strip underscores from actual text params! $titleParam = str_replace( '_', ' ', $par ); // Fetch the search term $search = str_replace( "\n", " ", $wgRequest->getText( 'search', $titleParam ) ); - $class = $wgUseOldSearchUI ? 'SpecialSearchOld' : 'SpecialSearch'; - $searchPage = new $class( $wgRequest, $wgUser ); - if( $wgRequest->getVal( 'fulltext' ) - || !is_null( $wgRequest->getVal( 'offset' )) + $searchPage = new SpecialSearch( $wgRequest, $wgUser ); + if( $wgRequest->getVal( 'fulltext' ) + || !is_null( $wgRequest->getVal( 'offset' )) || !is_null( $wgRequest->getVal( 'searchx' )) ) { $searchPage->showResults( $search ); @@ -74,7 +73,7 @@ class SpecialSearch { $this->active = 'advanced'; $this->sk = $user->getSkin(); $this->didYouMeanHtml = ''; # html of did you mean... link - $this->fulltext = $request->getVal('fulltext'); + $this->fulltext = $request->getVal('fulltext'); } /** @@ -103,7 +102,7 @@ class SpecialSearch { wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) ); # If the feature is enabled, go straight to the edit page if( $wgGoToEdit ) { - $wgOut->redirect( $t->getFullURL( 'action=edit' ) ); + $wgOut->redirect( $t->getFullURL( array( 'action' => 'edit' ) ) ); return; } } @@ -114,11 +113,11 @@ class SpecialSearch { * @param string $term */ public function showResults( $term ) { - global $wgOut, $wgUser, $wgDisableTextSearch, $wgContLang; + global $wgOut, $wgUser, $wgDisableTextSearch, $wgContLang, $wgScript; wfProfileIn( __METHOD__ ); - + $sk = $wgUser->getSkin(); - + $this->searchEngine = SearchEngine::create(); $search =& $this->searchEngine; $search->setLimitOffset( $this->limit, $this->offset ); @@ -126,9 +125,9 @@ class SpecialSearch { $search->showRedirects = $this->searchRedirects; $search->prefix = $this->mPrefix; $term = $search->transformSearchTerm($term); - + $this->setupPage( $term ); - + if( $wgDisableTextSearch ) { global $wgSearchForwardUrl; if( $wgSearchForwardUrl ) { @@ -152,10 +151,10 @@ class SpecialSearch { wfProfileOut( __METHOD__ ); return; } - + $t = Title::newFromText( $term ); - - // fetch search results + + // fetch search results $rewritten = $search->replacePrefixes($term); $titleMatches = $search->searchTitle( $rewritten ); @@ -165,95 +164,116 @@ class SpecialSearch { // did you mean... suggestions if( $textMatches && $textMatches->hasSuggestion() ) { $st = SpecialPage::getTitleFor( 'Search' ); + # mirror Go/Search behaviour of original request .. $didYouMeanParams = array( 'search' => $textMatches->getSuggestionQuery() ); - if($this->fulltext != NULL) - $didYouMeanParams['fulltext'] = $this->fulltext; - $stParams = wfArrayToCGI( + + if($this->fulltext != null) + $didYouMeanParams['fulltext'] = $this->fulltext; + + $stParams = array_merge( $didYouMeanParams, $this->powerSearchOptions() ); - $suggestLink = $sk->makeKnownLinkObj( $st, - $textMatches->getSuggestionSnippet(), - $stParams ); + + $suggestionSnippet = $textMatches->getSuggestionSnippet(); + + if( $suggestionSnippet == '' ) + $suggestionSnippet = null; + + $suggestLink = $sk->linkKnown( + $st, + $suggestionSnippet, + array(), + $stParams + ); $this->didYouMeanHtml = '
'.wfMsg('search-suggest',$suggestLink).'
'; } - - // start rendering the page - $wgOut->addHtml( - Xml::openElement( 'table', array( 'border'=>0, 'cellpadding'=>0, 'cellspacing'=>0 ) ) . + // start rendering the page + $wgOut->addHtml( + Xml::openElement( + 'form', + array( + 'id' => ( $this->searchAdvanced ? 'powersearch' : 'search' ), + 'method' => 'get', + 'action' => $wgScript + ) + ) + ); + $wgOut->addHtml( + Xml::openElement( 'table', array( 'id'=>'mw-search-top-table', 'border'=>0, 'cellpadding'=>0, 'cellspacing'=>0 ) ) . Xml::openElement( 'tr' ) . Xml::openElement( 'td' ) . "\n" . - ( $this->searchAdvanced ? $this->powerSearchBox( $term ) : $this->shortDialog( $term ) ) . + $this->shortDialog( $term ) . Xml::closeElement('td') . Xml::closeElement('tr') . Xml::closeElement('table') ); - + // Sometimes the search engine knows there are too many hits if( $titleMatches instanceof SearchResultTooMany ) { $wgOut->addWikiText( '==' . wfMsg( 'toomanymatches' ) . "==\n" ); wfProfileOut( __METHOD__ ); return; } - + $filePrefix = $wgContLang->getFormattedNsText(NS_FILE).':'; - if( '' === trim( $term ) || $filePrefix === trim( $term ) ) { - $wgOut->addHTML( $this->searchAdvanced ? $this->powerSearchFocus() : $this->searchFocus() ); + if( trim( $term ) === '' || $filePrefix === trim( $term ) ) { + $wgOut->addHTML( $this->searchFocus() ); + $wgOut->addHTML( $this->formHeader($term, 0, 0)); + if( $this->searchAdvanced ) { + $wgOut->addHTML( $this->powerSearchBox( $term ) ); + } + $wgOut->addHTML( '' ); // Empty query -- straight view of search form wfProfileOut( __METHOD__ ); return; } - // show direct page/create link - if( !is_null($t) ) { - if( !$t->exists() ) { - $wgOut->addWikiMsg( 'searchmenu-new', wfEscapeWikiText( $t->getPrefixedText() ) ); - } else { - $wgOut->addWikiMsg( 'searchmenu-exists', wfEscapeWikiText( $t->getPrefixedText() ) ); - } - } - // Get number of results - $titleMatchesSQL = $titleMatches ? $titleMatches->numRows() : 0; - $textMatchesSQL = $textMatches ? $textMatches->numRows() : 0; + $titleMatchesNum = $titleMatches ? $titleMatches->numRows() : 0; + $textMatchesNum = $textMatches ? $textMatches->numRows() : 0; // Total initial query matches (possible false positives) - $numSQL = $titleMatchesSQL + $textMatchesSQL; + $num = $titleMatchesNum + $textMatchesNum; + // Get total actual results (after second filtering, if any) $numTitleMatches = $titleMatches && !is_null( $titleMatches->getTotalHits() ) ? - $titleMatches->getTotalHits() : $titleMatchesSQL; + $titleMatches->getTotalHits() : $titleMatchesNum; $numTextMatches = $textMatches && !is_null( $textMatches->getTotalHits() ) ? - $textMatches->getTotalHits() : $textMatchesSQL; - $totalRes = $numTitleMatches + $numTextMatches; - + $textMatches->getTotalHits() : $textMatchesNum; + + // get total number of results if backend can calculate it + $totalRes = 0; + if($titleMatches && !is_null( $titleMatches->getTotalHits() ) ) + $totalRes += $titleMatches->getTotalHits(); + if($textMatches && !is_null( $textMatches->getTotalHits() )) + $totalRes += $textMatches->getTotalHits(); + // show number of results and current offset - if( $numSQL > 0 ) { - if( $numSQL > 0 ) { - $top = wfMsgExt('showingresultstotal', array( 'parseinline' ), - $this->offset+1, $this->offset+$numSQL, $totalRes, $numSQL ); - } elseif( $numSQL >= $this->limit ) { - $top = wfShowingResults( $this->offset, $this->limit ); - } else { - $top = wfShowingResultsNum( $this->offset, $this->limit, $numSQL ); - } - $wgOut->addHTML( "

{$top}

\n" ); + $wgOut->addHTML( $this->formHeader($term, $num, $totalRes)); + if( $this->searchAdvanced ) { + $wgOut->addHTML( $this->powerSearchBox( $term ) ); } + + $wgOut->addHtml( Xml::closeElement( 'form' ) ); + $wgOut->addHtml( "
" ); // prev/next links - if( $numSQL || $this->offset ) { + if( $num || $this->offset ) { + // Show the create link ahead + $this->showCreateLink( $t ); $prevnext = wfViewPrevNext( $this->offset, $this->limit, SpecialPage::getTitleFor( 'Search' ), wfArrayToCGI( $this->powerSearchOptions(), array( 'search' => $term ) ), - max( $titleMatchesSQL, $textMatchesSQL ) < $this->limit + max( $titleMatchesNum, $textMatchesNum ) < $this->limit ); - $wgOut->addHTML( "

{$prevnext}

\n" ); + //$wgOut->addHTML( "

{$prevnext}

\n" ); wfRunHooks( 'SpecialSearchResults', array( $term, &$titleMatches, &$textMatches ) ); } else { wfRunHooks( 'SpecialSearchNoResults', array( $term ) ); - } + } - $wgOut->addHtml( "
" ); if( $titleMatches ) { if( $numTitleMatches > 0 ) { $wgOut->wrapWikiMsg( "==$1==\n", 'titlematches' ); @@ -265,10 +285,10 @@ class SpecialSearch { // output appropriate heading if( $numTextMatches > 0 && $numTitleMatches > 0 ) { // if no title matches the heading is redundant - $wgOut->wrapWikiMsg( "==$1==\n", 'textmatches' ); + $wgOut->wrapWikiMsg( "==$1==\n", 'textmatches' ); } elseif( $totalRes == 0 ) { # Don't show the 'no text matches' if we received title matches - $wgOut->wrapWikiMsg( "==$1==\n", 'notextmatches' ); + # $wgOut->wrapWikiMsg( "==$1==\n", 'notextmatches' ); } // show interwiki results if any if( $textMatches->hasInterwikiResults() ) { @@ -281,20 +301,41 @@ class SpecialSearch { $textMatches->free(); } - if( $totalRes === 0 ) { - $wgOut->addWikiMsg( 'search-nonefound' ); + if( $num === 0 ) { + $wgOut->addWikiMsg( 'search-nonefound', wfEscapeWikiText( $term ) ); + $this->showCreateLink( $t ); } $wgOut->addHtml( "
" ); - if( $totalRes === 0 ) { - $wgOut->addHTML( $this->searchAdvanced ? $this->powerSearchFocus() : $this->searchFocus() ); + if( $num === 0 ) { + $wgOut->addHTML( $this->searchFocus() ); } - if( $numSQL || $this->offset ) { + if( $num || $this->offset ) { $wgOut->addHTML( "

{$prevnext}

\n" ); } wfProfileOut( __METHOD__ ); } + protected function showCreateLink( $t ) { + global $wgOut; + + // show direct page/create link if applicable + $messageName = null; + if( !is_null($t) ) { + if( $t->isKnown() ) { + $messageName = 'searchmenu-exists'; + } elseif( $t->userCan( 'create' ) ) { + $messageName = 'searchmenu-new'; + } + } + if( $messageName ) { + $wgOut->addWikiMsg( $messageName, wfEscapeWikiText( $t->getPrefixedText() ) ); + } else { + // preserve the paragraph for margins etc... + $wgOut->addHtml( '

' ); + } + } + /** * */ @@ -304,24 +345,25 @@ class SpecialSearch { $nsAllSet = array_keys( SearchEngine::searchableNamespaces() ); if( $this->searchAdvanced ) $this->active = 'advanced'; - else if( $this->namespaces === NS_FILE || $this->startsWithImage( $term ) ) - $this->active = 'images'; - elseif( $this->namespaces === $nsAllSet ) - $this->active = 'all'; - elseif( $this->namespaces === SearchEngine::defaultNamespaces() ) - $this->active = 'default'; - elseif( $this->namespaces === SearchEngine::projectNamespaces() ) - $this->active = 'project'; - else - $this->active = 'advanced'; + else { + $profiles = $this->getSearchProfiles(); + + foreach( $profiles as $key => $data ) { + if ( $this->namespaces == $data['namespaces'] && $key != 'advanced') + $this->active = $key; + } + + } # Should advanced UI be used? $this->searchAdvanced = ($this->active === 'advanced'); if( !empty( $term ) ) { $wgOut->setPageTitle( wfMsg( 'searchresults') ); $wgOut->setHTMLTitle( wfMsg( 'pagetitle', wfMsg( 'searchresults-title', $term ) ) ); - } + } $wgOut->setArticleRelated( false ); $wgOut->setRobotPolicy( 'noindex,nofollow' ); + // add javascript specific to special:search + $wgOut->addScriptFile( 'search.js' ); } /** @@ -358,8 +400,8 @@ class SpecialSearch { } /** - * Show whole set of results - * + * Show whole set of results + * * @param SearchResultSet $matches */ protected function showMatches( &$matches ) { @@ -403,7 +445,20 @@ class SpecialSearch { $sk = $wgUser->getSkin(); $t = $result->getTitle(); - $link = $this->sk->makeKnownLinkObj( $t, $result->getTitleSnippet($terms)); + $titleSnippet = $result->getTitleSnippet($terms); + + if( $titleSnippet == '' ) + $titleSnippet = null; + + $link_t = clone $t; + + wfRunHooks( 'ShowSearchHitTitle', + array( &$link_t, &$titleSnippet, $result, $terms, $this ) ); + + $link = $this->sk->linkKnown( + $link_t, + $titleSnippet + ); //If page content is not readable, just return the title. //This is not quite safe, but better than showing excerpts from non-readable pages @@ -427,19 +482,42 @@ class SpecialSearch { $sectionTitle = $result->getSectionTitle(); $sectionText = $result->getSectionSnippet($terms); $redirect = ''; - if( !is_null($redirectTitle) ) - $redirect = "" - .wfMsg('search-redirect',$this->sk->makeKnownLinkObj( $redirectTitle, $redirectText)) - .""; + + if( !is_null($redirectTitle) ) { + if( $redirectText == '' ) + $redirectText = null; + + $redirect = "" . + wfMsg( + 'search-redirect', + $this->sk->linkKnown( + $redirectTitle, + $redirectText + ) + ) . + ""; + } + $section = ''; - if( !is_null($sectionTitle) ) - $section = "" - .wfMsg('search-section', $this->sk->makeKnownLinkObj( $sectionTitle, $sectionText)) - .""; + + + if( !is_null($sectionTitle) ) { + if( $sectionText == '' ) + $sectionText = null; + + $section = "" . + wfMsg( + 'search-section', $this->sk->linkKnown( + $sectionTitle, + $sectionText + ) + ) . + ""; + } // format text extract $extract = "
".$result->getTextSnippet($terms)."
"; - + // format score if( is_null( $result->getScore() ) ) { // Search engine doesn't report scoring info @@ -454,20 +532,32 @@ class SpecialSearch { $byteSize = $result->getByteSize(); $wordCount = $result->getWordCount(); $timestamp = $result->getTimestamp(); - $size = wfMsgExt( 'search-result-size', array( 'parsemag', 'escape' ), - $this->sk->formatSize( $byteSize ), $wordCount ); + $size = wfMsgExt( + 'search-result-size', + array( 'parsemag', 'escape' ), + $this->sk->formatSize( $byteSize ), + $wgLang->formatNum( $wordCount ) + ); $date = $wgLang->timeanddate( $timestamp ); // link to related articles if supported $related = ''; if( $result->hasRelated() ) { $st = SpecialPage::getTitleFor( 'Search' ); - $stParams = wfArrayToCGI( $this->powerSearchOptions(), - array('search' => wfMsgForContent('searchrelated').':'.$t->getPrefixedText(), - 'fulltext' => wfMsg('search') )); - - $related = ' -- ' . $sk->makeKnownLinkObj( $st, - wfMsg('search-relatedarticle'), $stParams ); + $stParams = array_merge( + $this->powerSearchOptions(), + array( + 'search' => wfMsgForContent( 'searchrelated' ) . ':' . $t->getPrefixedText(), + 'fulltext' => wfMsg( 'search' ) + ) + ); + + $related = ' -- ' . $sk->linkKnown( + $st, + wfMsg('search-relatedarticle'), + array(), + $stParams + ); } // Include a thumbnail for media files... @@ -508,7 +598,7 @@ class SpecialSearch { /** * Show results from other wikis - * + * * @param SearchResultSet $matches */ protected function showInterwiki( &$matches, $query ) { @@ -517,7 +607,7 @@ class SpecialSearch { $terms = $wgContLang->convertForSearchResult( $matches->termMatches() ); $out = "
". - wfMsg('search-interwiki-caption')."
\n"; + wfMsg('search-interwiki-caption')."
\n"; $off = $this->offset + 1; $out .= "
\n"; // convert the whole thing to desired language variant @@ -543,63 +633,88 @@ class SpecialSearch { wfProfileOut( __METHOD__ ); return $out; } - + /** * Show single interwiki link * * @param SearchResult $result * @param string $lastInterwiki * @param array $terms - * @param string $query + * @param string $query * @param array $customCaptions iw prefix -> caption */ protected function showInterwikiHit( $result, $lastInterwiki, $terms, $query, $customCaptions) { wfProfileIn( __METHOD__ ); global $wgContLang, $wgLang; - + if( $result->isBrokenTitle() ) { wfProfileOut( __METHOD__ ); return "\n"; } - + $t = $result->getTitle(); - $link = $this->sk->makeKnownLinkObj( $t, $result->getTitleSnippet($terms)); + $titleSnippet = $result->getTitleSnippet($terms); + + if( $titleSnippet == '' ) + $titleSnippet = null; + + $link = $this->sk->linkKnown( + $t, + $titleSnippet + ); // format redirect if any $redirectTitle = $result->getRedirectTitle(); $redirectText = $result->getRedirectSnippet($terms); $redirect = ''; - if( !is_null($redirectTitle) ) - $redirect = "" - .wfMsg('search-redirect',$this->sk->makeKnownLinkObj( $redirectTitle, $redirectText)) - .""; + if( !is_null($redirectTitle) ) { + if( $redirectText == '' ) + $redirectText = null; + + $redirect = "" . + wfMsg( + 'search-redirect', + $this->sk->linkKnown( + $redirectTitle, + $redirectText + ) + ) . + ""; + } $out = ""; - // display project name + // display project name if(is_null($lastInterwiki) || $lastInterwiki != $t->getInterwiki()) { if( key_exists($t->getInterwiki(),$customCaptions) ) // captions from 'search-interwiki-custom' $caption = $customCaptions[$t->getInterwiki()]; else{ - // default is to show the hostname of the other wiki which might suck + // default is to show the hostname of the other wiki which might suck // if there are many wikis on one hostname $parsed = parse_url($t->getFullURL()); - $caption = wfMsg('search-interwiki-default', $parsed['host']); - } + $caption = wfMsg('search-interwiki-default', $parsed['host']); + } // "more results" link (special page stuff could be localized, but we might not know target lang) - $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search"); - $searchLink = $this->sk->makeKnownLinkObj( $searchTitle, wfMsg('search-interwiki-more'), - wfArrayToCGI(array('search' => $query, 'fulltext' => 'Search'))); + $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search"); + $searchLink = $this->sk->linkKnown( + $searchTitle, + wfMsg('search-interwiki-more'), + array(), + array( + 'search' => $query, + 'fulltext' => 'Search' + ) + ); $out .= "
{$searchLink}{$caption}
\n
{$searchLink}{$caption}
\n