00001 <?php
00002 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>
00003 # http://www.mediawiki.org/
00004 #
00005 # This program is free software; you can redistribute it and/or modify
00006 # it under the terms of the GNU General Public License as published by
00007 # the Free Software Foundation; either version 2 of the License, or
00008 # (at your option) any later version.
00009 #
00010 # This program is distributed in the hope that it will be useful,
00011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 # GNU General Public License for more details.
00014 #
00015 # You should have received a copy of the GNU General Public License along
00016 # with this program; if not, write to the Free Software Foundation, Inc.,
00017 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 # http://www.gnu.org/copyleft/gpl.html
00019
00031 function wfSpecialSearch( $par = '' ) {
00032 global $wgRequest, $wgUser, $wgUseOldSearchUI;
00033
00034
00035
00036 $titleParam = str_replace( '_', ' ', $par );
00037
00038 $search = str_replace( "\n", " ", $wgRequest->getText( 'search', $titleParam ) );
00039 $class = $wgUseOldSearchUI ? 'SpecialSearchOld' : 'SpecialSearch';
00040 $searchPage = new $class( $wgRequest, $wgUser );
00041 if( $wgRequest->getVal( 'fulltext' )
00042 || !is_null( $wgRequest->getVal( 'offset' ))
00043 || !is_null( $wgRequest->getVal( 'searchx' )) )
00044 {
00045 $searchPage->showResults( $search, 'search' );
00046 } else {
00047 $searchPage->goResult( $search );
00048 }
00049 }
00050
00055 class SpecialSearch {
00056
00065 function __construct( &$request, &$user ) {
00066 list( $this->limit, $this->offset ) = $request->getLimitOffset( 20, 'searchlimit' );
00067
00068 $this->namespaces = $this->powerSearch( $request );
00069 if( empty( $this->namespaces ) ) {
00070 $this->namespaces = SearchEngine::userNamespaces( $user );
00071 }
00072
00073 $this->searchRedirects = $request->getcheck( 'redirs' ) ? true : false;
00074 $this->searchAdvanced = $request->getVal('advanced');
00075 }
00076
00082 function goResult( $term ) {
00083 global $wgOut, $wgGoToEdit;
00084
00085 $this->setupPage( $term );
00086
00087 # Try to go to page as entered.
00088 $t = Title::newFromText( $term );
00089
00090 # If the string cannot be used to create a title
00091 if( is_null( $t ) ) {
00092 return $this->showResults( $term );
00093 }
00094
00095 # If there's an exact or very near match, jump right there.
00096 $t = SearchEngine::getNearMatch( $term );
00097 if( !is_null( $t ) ) {
00098 $wgOut->redirect( $t->getFullURL() );
00099 return;
00100 }
00101
00102 # No match, generate an edit URL
00103 $t = Title::newFromText( $term );
00104 if( ! is_null( $t ) ) {
00105 wfRunHooks( 'SpecialSearchNogomatch', array( &$t ) );
00106 # If the feature is enabled, go straight to the edit page
00107 if( $wgGoToEdit ) {
00108 $wgOut->redirect( $t->getFullURL( 'action=edit' ) );
00109 return;
00110 }
00111 }
00112
00113 return $this->showResults( $term );
00114 }
00115
00120 function showResults( $term ) {
00121 wfProfileIn( __METHOD__ );
00122 global $wgOut, $wgUser;
00123 $sk = $wgUser->getSkin();
00124
00125 $this->setupPage( $term );
00126 $this->searchEngine = SearchEngine::create();
00127
00128 $t = Title::newFromText( $term );
00129
00130 $wgOut->addHtml(
00131 Xml::openElement( 'table', array( 'border'=>0, 'cellpadding'=>0, 'cellspacing'=>0 ) ) .
00132 Xml::openElement( 'tr' ) .
00133 Xml::openElement( 'td' ) . "\n"
00134 );
00135 if( $this->searchAdvanced ) {
00136 $wgOut->addHTML( $this->powerSearchBox( $term ) );
00137 $showMenu = false;
00138 } else {
00139 $wgOut->addHTML( $this->shortDialog( $term ) );
00140 $showMenu = true;
00141 }
00142 $wgOut->addHtml(
00143 Xml::closeElement('td') .
00144 Xml::closeElement('tr') .
00145 Xml::closeElement('table')
00146 );
00147
00148 if( '' === trim( $term ) ) {
00149
00150 wfProfileOut( __METHOD__ );
00151 return;
00152 }
00153
00154 global $wgDisableTextSearch;
00155 if( $wgDisableTextSearch ) {
00156 global $wgSearchForwardUrl;
00157 if( $wgSearchForwardUrl ) {
00158 $url = str_replace( '$1', urlencode( $term ), $wgSearchForwardUrl );
00159 $wgOut->redirect( $url );
00160 return;
00161 }
00162 global $wgInputEncoding;
00163 $wgOut->addHTML(
00164 Xml::openElement( 'fieldset' ) .
00165 Xml::element( 'legend', null, wfMsg( 'search-external' ) ) .
00166 Xml::element( 'p', array( 'class' => 'mw-searchdisabled' ), wfMsg( 'searchdisabled' ) ) .
00167 wfMsg( 'googlesearch',
00168 htmlspecialchars( $term ),
00169 htmlspecialchars( $wgInputEncoding ),
00170 htmlspecialchars( wfMsg( 'searchbutton' ) )
00171 ) .
00172 Xml::closeElement( 'fieldset' )
00173 );
00174 wfProfileOut( __METHOD__ );
00175 return;
00176 }
00177
00178 $search =& $this->searchEngine;
00179 $search->setLimitOffset( $this->limit, $this->offset );
00180 $search->setNamespaces( $this->namespaces );
00181 $search->showRedirects = $this->searchRedirects;
00182 $rewritten = $search->replacePrefixes($term);
00183
00184 $titleMatches = $search->searchTitle( $rewritten );
00185
00186
00187 if( $titleMatches instanceof SearchResultTooMany ) {
00188 $wgOut->addWikiText( '==' . wfMsg( 'toomanymatches' ) . "==\n" );
00189 wfProfileOut( __METHOD__ );
00190 return;
00191 }
00192
00193 $textMatches = $search->searchText( $rewritten );
00194
00195
00196 if( $textMatches && $textMatches->hasSuggestion() ) {
00197 $st = SpecialPage::getTitleFor( 'Search' );
00198 $stParams = wfArrayToCGI(
00199 array( 'search' => $textMatches->getSuggestionQuery(), 'fulltext' => wfMsg('search') ),
00200 $this->powerSearchOptions()
00201 );
00202 $suggestLink = '<a href="'.$st->escapeLocalURL($stParams).'">'.
00203 $textMatches->getSuggestionSnippet().'</a>';
00204
00205 $wgOut->addHTML('<div class="searchdidyoumean">'.wfMsg('search-suggest',$suggestLink).'</div>');
00206 }
00207
00208
00209 if( !is_null($t) ) {
00210 if( !$t->exists() ) {
00211 $wgOut->addWikiMsg( 'searchmenu-new', wfEscapeWikiText( $t->getPrefixedText() ) );
00212 } else {
00213 $wgOut->addWikiMsg( 'searchmenu-exists', wfEscapeWikiText( $t->getPrefixedText() ) );
00214 }
00215 }
00216
00217
00218 $numTitleMatches = $titleMatches ? $titleMatches->numRows() : 0;
00219 $numTextMatches = $textMatches ? $textMatches->numRows() : 0;
00220 $highestNum = max( $numTitleMatches, $numTextMatches );
00221
00222 $num = $numTitleMatches + $numTextMatches;
00223
00224 $totalNum = 0;
00225 if( $titleMatches && !is_null($titleMatches->getTotalHits()) )
00226 $totalNum += $titleMatches->getTotalHits();
00227 if( $textMatches && !is_null($textMatches->getTotalHits()) )
00228 $totalNum += $textMatches->getTotalHits();
00229 if( $num > 0 ) {
00230 if( $totalNum > 0 ) {
00231 $top = wfMsgExt('showingresultstotal', array( 'parseinline' ),
00232 $this->offset+1, $this->offset+$num, $totalNum, $num );
00233 } elseif( $num >= $this->limit ) {
00234 $top = wfShowingResults( $this->offset, $this->limit );
00235 } else {
00236 $top = wfShowingResultsNum( $this->offset, $this->limit, $num );
00237 }
00238 $wgOut->addHTML( "<p class='mw-search-numberresults'>{$top}</p>\n" );
00239 }
00240
00241
00242 if( $num || $this->offset ) {
00243 $prevnext = wfViewPrevNext( $this->offset, $this->limit,
00244 SpecialPage::getTitleFor( 'Search' ),
00245 wfArrayToCGI( $this->powerSearchOptions(), array( 'search' => $term ) ),
00246 ($highestNum < $this->limit)
00247 );
00248 $wgOut->addHTML( "<p class='mw-search-pager-top'>{$prevnext}</p>\n" );
00249 wfRunHooks( 'SpecialSearchResults', array( $term, &$titleMatches, &$textMatches ) );
00250 } else {
00251 wfRunHooks( 'SpecialSearchNoResults', array( $term ) );
00252 }
00253
00254 $wgOut->addHtml( "<div class='searchresults'>" );
00255
00256 if( $titleMatches ) {
00257 if( $titleMatches->numRows() ) {
00258 $wgOut->wrapWikiMsg( "==$1==\n", 'titlematches' );
00259 $wgOut->addHTML( $this->showMatches( $titleMatches ) );
00260 }
00261 $titleMatches->free();
00262 }
00263
00264 if( $textMatches ) {
00265
00266 if( $textMatches->numRows() ) {
00267 if($titleMatches)
00268 $wgOut->wrapWikiMsg( "==$1==\n", 'textmatches' );
00269 else
00270 $wgOut->addHTML("<hr/>");
00271 } elseif( $num == 0 ) {
00272 # Don't show the 'no text matches' if we received title matches
00273 $wgOut->wrapWikiMsg( "==$1==\n", 'notextmatches' );
00274 }
00275
00276 if( $textMatches->hasInterwikiResults() )
00277 $wgOut->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(), $term ));
00278
00279 if( $textMatches->numRows() )
00280 $wgOut->addHTML( $this->showMatches( $textMatches ) );
00281
00282 $textMatches->free();
00283 }
00284
00285 if( $num == 0 ) {
00286 $wgOut->addWikiMsg( 'search-nonefound' );
00287 }
00288
00289 $wgOut->addHtml( "</div>" );
00290
00291 if( $num || $this->offset ) {
00292 $wgOut->addHTML( "<p class='mw-search-pager-bottom'>{$prevnext}</p>\n" );
00293 }
00294 wfProfileOut( __METHOD__ );
00295 }
00296
00300 protected function setupPage( $term ) {
00301 global $wgOut;
00302 if( !empty( $term ) ) {
00303 $wgOut->setPageTitle( wfMsg( 'searchresults') );
00304 $wgOut->setHTMLTitle( wfMsg( 'pagetitle', wfMsg( 'searchresults-title', $term) ) );
00305 }
00306 $wgOut->setArticleRelated( false );
00307 $wgOut->setRobotPolicy( 'noindex,nofollow' );
00308 }
00309
00317 protected function powerSearch( &$request ) {
00318 $arr = array();
00319 foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
00320 if( $request->getCheck( 'ns' . $ns ) ) {
00321 $arr[] = $ns;
00322 }
00323 }
00324 return $arr;
00325 }
00326
00331 protected function powerSearchOptions() {
00332 $opt = array();
00333 foreach( $this->namespaces as $n ) {
00334 $opt['ns' . $n] = 1;
00335 }
00336 $opt['redirs'] = $this->searchRedirects ? 1 : 0;
00337 if( $this->searchAdvanced )
00338 $opt['advanced'] = $this->searchAdvanced;
00339 return $opt;
00340 }
00341
00347 protected function showMatches( &$matches ) {
00348 global $wgContLang;
00349 wfProfileIn( __METHOD__ );
00350
00351 $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
00352
00353 $out = "";
00354
00355 $infoLine = $matches->getInfo();
00356 if( !is_null($infoLine) )
00357 $out .= "\n<!-- {$infoLine} -->\n";
00358
00359
00360 $off = $this->offset + 1;
00361 $out .= "<ul class='mw-search-results'>\n";
00362 while( $result = $matches->next() ) {
00363 $out .= $this->showHit( $result, $terms );
00364 }
00365 $out .= "</ul>\n";
00366
00367
00368 $out = $wgContLang->convert( $out );
00369 wfProfileOut( __METHOD__ );
00370 return $out;
00371 }
00372
00378 protected function showHit( $result, $terms ) {
00379 wfProfileIn( __METHOD__ );
00380 global $wgUser, $wgContLang, $wgLang;
00381
00382 if( $result->isBrokenTitle() ) {
00383 wfProfileOut( __METHOD__ );
00384 return "<!-- Broken link in search result -->\n";
00385 }
00386
00387 $t = $result->getTitle();
00388 $sk = $wgUser->getSkin();
00389
00390 $link = $sk->makeKnownLinkObj( $t, $result->getTitleSnippet($terms));
00391
00392
00393
00394
00395 if(!$t->userCanRead()) {
00396 wfProfileOut( __METHOD__ );
00397 return "<li>{$link}</li>\n";
00398 }
00399
00400
00401
00402
00403 if( $result->isMissingRevision() ) {
00404 wfProfileOut( __METHOD__ );
00405 return "<!-- missing page " .
00406 htmlspecialchars( $t->getPrefixedText() ) . "-->\n";
00407 }
00408
00409
00410 $redirectTitle = $result->getRedirectTitle();
00411 $redirectText = $result->getRedirectSnippet($terms);
00412 $sectionTitle = $result->getSectionTitle();
00413 $sectionText = $result->getSectionSnippet($terms);
00414 $redirect = '';
00415 if( !is_null($redirectTitle) )
00416 $redirect = "<span class='searchalttitle'>"
00417 .wfMsg('search-redirect',$sk->makeKnownLinkObj( $redirectTitle, $redirectText))
00418 ."</span>";
00419 $section = '';
00420 if( !is_null($sectionTitle) )
00421 $section = "<span class='searchalttitle'>"
00422 .wfMsg('search-section', $sk->makeKnownLinkObj( $sectionTitle, $sectionText))
00423 ."</span>";
00424
00425
00426 $extract = "<div class='searchresult'>".$result->getTextSnippet($terms)."</div>";
00427
00428
00429 if( is_null( $result->getScore() ) ) {
00430
00431 $score = '';
00432 } else {
00433 $percent = sprintf( '%2.1f', $result->getScore() * 100 );
00434 $score = wfMsg( 'search-result-score', $wgLang->formatNum( $percent ) )
00435 . ' - ';
00436 }
00437
00438
00439 $byteSize = $result->getByteSize();
00440 $wordCount = $result->getWordCount();
00441 $timestamp = $result->getTimestamp();
00442 $size = wfMsgExt( 'search-result-size', array( 'parsemag', 'escape' ),
00443 $sk->formatSize( $byteSize ),
00444 $wordCount );
00445 $date = $wgLang->timeanddate( $timestamp );
00446
00447
00448 $related = '';
00449 if( $result->hasRelated() ) {
00450 $st = SpecialPage::getTitleFor( 'Search' );
00451 $stParams = wfArrayToCGI( $this->powerSearchOptions(),
00452 array('search' => wfMsgForContent('searchrelated').':'.$t->getPrefixedText(),
00453 'fulltext' => wfMsg('search') ));
00454
00455 $related = ' -- <a href="'.$st->escapeLocalURL($stParams).'">'.
00456 wfMsg('search-relatedarticle').'</a>';
00457 }
00458
00459
00460 if( $t->getNamespace() == NS_IMAGE ) {
00461 $img = wfFindFile( $t );
00462 if( $img ) {
00463 $thumb = $img->transform( array( 'width' => 120, 'height' => 120 ) );
00464 if( $thumb ) {
00465 $desc = $img->getShortDesc();
00466 wfProfileOut( __METHOD__ );
00467
00468
00469
00470 return "<li>" .
00471 '<table class="searchResultImage">' .
00472 '<tr>' .
00473 '<td width="120" align="center" valign="top">' .
00474 $thumb->toHtml( array( 'desc-link' => true ) ) .
00475 '</td>' .
00476 '<td valign="top">' .
00477 $link .
00478 $extract .
00479 "<div class='mw-search-result-data'>{$score}{$desc} - {$date}{$related}</div>" .
00480 '</td>' .
00481 '</tr>' .
00482 '</table>' .
00483 "</li>\n";
00484 }
00485 }
00486 }
00487
00488 wfProfileOut( __METHOD__ );
00489 return "<li>{$link} {$redirect} {$section} {$extract}\n" .
00490 "<div class='mw-search-result-data'>{$score}{$size} - {$date}{$related}</div>" .
00491 "</li>\n";
00492
00493 }
00494
00500 protected function showInterwiki( &$matches, $query ) {
00501 wfProfileIn( __METHOD__ );
00502
00503 global $wgContLang;
00504 $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
00505
00506 $out = "<div id='mw-search-interwiki'><div id='mw-search-interwiki-caption'>".
00507 wfMsg('search-interwiki-caption')."</div>\n";
00508 $off = $this->offset + 1;
00509 $out .= "<ul start='{$off}' class='mw-search-iwresults'>\n";
00510
00511
00512 $customCaptions = array();
00513 $customLines = explode("\n",wfMsg('search-interwiki-custom'));
00514 foreach($customLines as $line) {
00515 $parts = explode(":",$line,2);
00516 if(count($parts) == 2)
00517 $customCaptions[$parts[0]] = $parts[1];
00518 }
00519
00520
00521 $prev = null;
00522 while( $result = $matches->next() ) {
00523 $out .= $this->showInterwikiHit( $result, $prev, $terms, $query, $customCaptions );
00524 $prev = $result->getInterwikiPrefix();
00525 }
00526
00527 $out .= "</ul></div>\n";
00528
00529
00530 global $wgContLang;
00531 $out = $wgContLang->convert( $out );
00532 wfProfileOut( __METHOD__ );
00533 return $out;
00534 }
00535
00545 protected function showInterwikiHit( $result, $lastInterwiki, $terms, $query, $customCaptions) {
00546 wfProfileIn( __METHOD__ );
00547 global $wgUser, $wgContLang, $wgLang;
00548
00549 if( $result->isBrokenTitle() ) {
00550 wfProfileOut( __METHOD__ );
00551 return "<!-- Broken link in search result -->\n";
00552 }
00553
00554 $t = $result->getTitle();
00555 $sk = $wgUser->getSkin();
00556
00557 $link = $sk->makeKnownLinkObj( $t, $result->getTitleSnippet($terms));
00558
00559
00560 $redirectTitle = $result->getRedirectTitle();
00561 $redirectText = $result->getRedirectSnippet($terms);
00562 $redirect = '';
00563 if( !is_null($redirectTitle) )
00564 $redirect = "<span class='searchalttitle'>"
00565 .wfMsg('search-redirect',$sk->makeKnownLinkObj( $redirectTitle, $redirectText))
00566 ."</span>";
00567
00568 $out = "";
00569
00570 if(is_null($lastInterwiki) || $lastInterwiki != $t->getInterwiki()) {
00571 if( key_exists($t->getInterwiki(),$customCaptions) )
00572
00573 $caption = $customCaptions[$t->getInterwiki()];
00574 else{
00575
00576
00577 $parsed = parse_url($t->getFullURL());
00578 $caption = wfMsg('search-interwiki-default', $parsed['host']);
00579 }
00580
00581 $searchTitle = Title::newFromText($t->getInterwiki().":Special:Search");
00582 $searchLink = $sk->makeKnownLinkObj( $searchTitle, wfMsg('search-interwiki-more'),
00583 wfArrayToCGI(array('search' => $query, 'fulltext' => 'Search')));
00584 $out .= "</ul><div class='mw-search-interwiki-project'><span class='mw-search-interwiki-more'>
00585 {$searchLink}</span>{$caption}</div>\n<ul>";
00586 }
00587
00588 $out .= "<li>{$link} {$redirect}</li>\n";
00589 wfProfileOut( __METHOD__ );
00590 return $out;
00591 }
00592
00593
00599 protected function powerSearchBox( $term ) {
00600 global $wgScript, $wgContLang;
00601
00602 $namespaces = SearchEngine::searchableNamespaces();
00603
00604
00605
00606 $rows = array();
00607 foreach( $namespaces as $ns => $name ) {
00608 $subj = Namespace::getSubject( $ns );
00609 if( !array_key_exists( $subj, $rows ) ) {
00610 $rows[$subj] = "";
00611 }
00612 $name = str_replace( '_', ' ', $name );
00613 if( '' == $name ) {
00614 $name = wfMsg( 'blanknamespace' );
00615 }
00616 $rows[$subj] .= Xml::openElement( 'td', array( 'style' => 'white-space: nowrap' ) ) .
00617 Xml::checkLabel( $name, "ns{$ns}", "mw-search-ns{$ns}", in_array( $ns, $this->namespaces ) ) .
00618 Xml::closeElement( 'td' ) . "\n";
00619 }
00620 $rows = array_values( $rows );
00621 $numRows = count( $rows );
00622
00623
00624
00625 $rowsPerTable = 3;
00626
00627
00628 $tableStyle = ( $wgContLang->isRTL() ?
00629 'float: right; margin: 0 0 1em 1em' :
00630 'float: left; margin: 0 1em 1em 0' );
00631
00632 $tables = "";
00633 for( $i = 0; $i < $numRows; $i += $rowsPerTable ) {
00634 $tables .= Xml::openElement( 'table', array( 'style' => $tableStyle ) );
00635 for( $j = $i; $j < $i + $rowsPerTable && $j < $numRows; $j++ ) {
00636 $tables .= "<tr>\n" . $rows[$j] . "</tr>";
00637 }
00638 $tables .= Xml::closeElement( 'table' ) . "\n";
00639 }
00640
00641 $redirect = Xml::check( 'redirs', $this->searchRedirects, array( 'value' => '1', 'id' => 'redirs' ) );
00642 $redirectLabel = Xml::label( wfMsg( 'powersearch-redir' ), 'redirs' );
00643 $searchField = Xml::input( 'search', 50, $term, array( 'type' => 'text', 'id' => 'powerSearchText' ) );
00644 $searchButton = Xml::submitButton( wfMsg( 'powersearch' ), array( 'name' => 'fulltext' ) ) . "\n";
00645 $searchTitle = SpecialPage::getTitleFor( 'Search' );
00646
00647 $out = Xml::openElement( 'form', array( 'id' => 'powersearch', 'method' => 'get', 'action' => $wgScript ) ) .
00648 Xml::hidden( 'title', $searchTitle->getPrefixedText() ) . "\n" .
00649 "<p>" .
00650 wfMsgExt( 'powersearch-ns', array( 'parseinline' ) ) .
00651 "</p>\n" .
00652 $tables .
00653 "<hr style=\"clear: both\" />\n" .
00654 "<p>" .
00655 $redirect . " " . $redirectLabel .
00656 "</p>\n" .
00657 wfMsgExt( 'powersearch-field', array( 'parseinline' ) ) .
00658 " " .
00659 $searchField .
00660 " " .
00661 $searchButton .
00662 "</form>";
00663 $t = Title::newFromText( $term );
00664 if( $t != null )
00665 $out .= wfMsgExt( 'searchmenu-prefix', array('parseinline'), $term );
00666
00667 return Xml::openElement( 'fieldset', array('id' => 'mw-searchoptions','style' => 'margin:0em;') ) .
00668 Xml::element( 'legend', null, wfMsg('powersearch-legend') ) .
00669 $this->formHeader($term) . $out .
00670 Xml::closeElement( 'fieldset' );
00671 }
00672
00673 protected function powerSearchFocus() {
00674 global $wgJsMimeType;
00675 return "<script type=\"$wgJsMimeType\">" .
00676 "hookEvent(\"load\", function() {" .
00677 "document.getElementById('powerSearchText').focus();" .
00678 "});" .
00679 "</script>";
00680 }
00681
00683 protected function makeSearchLink( $term, $namespaces, $label, $tooltip, $params=array() ) {
00684 $opt = $params;
00685 foreach( $namespaces as $n ) {
00686 $opt['ns' . $n] = 1;
00687 }
00688 $opt['redirs'] = $this->searchRedirects ? 1 : 0;
00689
00690 $st = SpecialPage::getTitleFor( 'Search' );
00691 $stParams = wfArrayToCGI( array( 'search' => $term, 'fulltext' => wfMsg( 'search' ) ), $opt );
00692
00693 return Xml::element( 'a',
00694 array( 'href'=> $st->getLocalURL( $stParams ), 'title' => $tooltip ),
00695 $label );
00696 }
00697
00699 protected function startsWithImage( $term ) {
00700 global $wgContLang;
00701
00702 $p = explode( ':', $term );
00703 if( count( $p ) > 1 ) {
00704 return $wgContLang->getNsIndex( $p[0] ) == NS_IMAGE;
00705 }
00706 return false;
00707 }
00708
00709 protected function formHeader( $term ) {
00710 global $wgContLang, $wgCanonicalNamespaceNames;
00711
00712 $sep = ' ';
00713 $out = Xml::openElement('div', array( 'style' => 'padding-bottom:0.5em;' ) );
00714
00715 $bareterm = $term;
00716 if( $this->startsWithImage( $term ) )
00717 $bareterm = substr( $term, strpos( $term, ':' ) + 1 );
00718
00719 $nsAllSet = array_keys( SearchEngine::searchableNamespaces() );
00720
00721 if( $this->searchAdvanced )
00722 $active = 'advanced';
00723 else if( $this->namespaces === NS_IMAGE || $this->startsWithImage( $term ) )
00724 $active = 'images';
00725 elseif( $this->namespaces === $nsAllSet )
00726 $active = 'all';
00727 elseif( $this->namespaces === SearchEngine::defaultNamespaces() )
00728 $active = 'default';
00729 elseif( $this->namespaces === SearchEngine::defaultAndProjectNamespaces() )
00730 $active = 'withproject';
00731 elseif( $this->namespaces === SearchEngine::projectNamespaces() )
00732 $active = 'project';
00733 else
00734 $active = 'advanced';
00735
00736
00737
00738 $m = wfMsg( 'searchprofile-articles' );
00739 $tt = wfMsg( 'searchprofile-articles-tooltip',
00740 implode( ', ', SearchEngine::namespacesAsText( SearchEngine::defaultNamespaces() ) ) );
00741 if( $active == 'default' ) {
00742 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00743 } else {
00744 $out .= $this->makeSearchLink( $bareterm, SearchEngine::defaultNamespaces(), $m, $tt );
00745 }
00746 $out .= $sep;
00747
00748 $m = wfMsg( 'searchprofile-images' );
00749 $tt = wfMsg( 'searchprofile-images-tooltip' );
00750 if( $active == 'images' ) {
00751 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00752 } else {
00753 $imageTextForm = $wgContLang->getFormattedNsText(NS_IMAGE).':'.$bareterm;
00754 $out .= $this->makeSearchLink( $imageTextForm, array( NS_IMAGE ) , $m, $tt );
00755 }
00756 $out .= $sep;
00757
00758 $m = wfMsg( 'searchprofile-articles-and-proj' );
00759 $tt = wfMsg( 'searchprofile-project-tooltip',
00760 implode( ', ', SearchEngine::namespacesAsText( SearchEngine::defaultAndProjectNamespaces() ) ) );
00761 if( $active == 'withproject' ) {
00762 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00763 } else {
00764 $out .= $this->makeSearchLink( $bareterm, SearchEngine::defaultAndProjectNamespaces(), $m, $tt );
00765 }
00766 $out .= $sep;
00767
00768 $m = wfMsg( 'searchprofile-project' );
00769 $tt = wfMsg( 'searchprofile-project-tooltip',
00770 implode( ', ', SearchEngine::namespacesAsText( SearchEngine::projectNamespaces() ) ) );
00771 if( $active == 'project' ) {
00772 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00773 } else {
00774 $out .= $this->makeSearchLink( $bareterm, SearchEngine::projectNamespaces(), $m, $tt );
00775 }
00776 $out .= $sep;
00777
00778 $m = wfMsg( 'searchprofile-everything' );
00779 $tt = wfMsg( 'searchprofile-everything-tooltip' );
00780 if( $active == 'all' ) {
00781 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00782 } else {
00783 $out .= $this->makeSearchLink( $bareterm, $nsAllSet, $m, $tt );
00784 }
00785 $out .= $sep;
00786
00787 $m = wfMsg( 'searchprofile-advanced' );
00788 $tt = wfMsg( 'searchprofile-advanced-tooltip' );
00789 if( $active == 'advanced' ) {
00790 $out .= Xml::element( 'strong', array( 'title'=>$tt ), $m );
00791 } else {
00792 $out .= $this->makeSearchLink( $bareterm, $this->namespaces, $m, $tt, array( 'advanced' => '1' ) );
00793 }
00794 $out .= Xml::closeElement('div') ;
00795
00796 return $out;
00797 }
00798
00799 protected function shortDialog( $term ) {
00800 global $wgScript;
00801 $out = Xml::openElement( 'form', array( 'id' => 'search', 'method' => 'get', 'action' => $wgScript ) );
00802 $searchTitle = SpecialPage::getTitleFor( 'Search' );
00803 $out .= Xml::hidden( 'title', $searchTitle->getPrefixedText() ) . "\n";
00804 $out .= Xml::input( 'search', 50, $term, array( 'type' => 'text', 'id' => 'searchText' ) ) . "\n";
00805 foreach( SearchEngine::searchableNamespaces() as $ns => $name ) {
00806 if( in_array( $ns, $this->namespaces ) ) {
00807 $out .= Xml::hidden( "ns{$ns}", '1' );
00808 }
00809 }
00810 $out .= Xml::submitButton( wfMsg( 'searchbutton' ), array( 'name' => 'fulltext' ) );
00811 $out .= ' (' . wfMsgExt('searchmenu-help',array('parseinline') ) . ')';
00812 $out .= Xml::closeElement( 'form' );
00813 $t = Title::newFromText( $term );
00814 if( $t != null )
00815 $out .= wfMsgExt( 'searchmenu-prefix', array('parseinline'), $term );
00816 return Xml::openElement( 'fieldset', array('id' => 'mw-searchoptions','style' => 'margin:0em;') ) .
00817 Xml::element( 'legend', null, wfMsg('searchmenu-legend') ) .
00818 $this->formHeader($term) . $out .
00819 Xml::closeElement( 'fieldset' );
00820 }
00821 }
00822
00827 class SpecialSearchOld {
00828
00837 function __construct( &$request, &$user ) {
00838 list( $this->limit, $this->offset ) = $request->getLimitOffset( 20, 'searchlimit' );
00839
00840 $this->namespaces = $this->powerSearch( $request );
00841 if( empty( $this->namespaces ) ) {
00842 $this->namespaces = SearchEngine::userNamespaces( $user );
00843 }
00844
00845 $this->searchRedirects = $request->getcheck( 'redirs' ) ? true : false;
00846 }
00847
00853 function goResult( $term ) {
00854 global $wgOut;
00855 global $wgGoToEdit;
00856
00857 $this->setupPage( $term );
00858
00859 # Try to go to page as entered.
00860 $t = Title::newFromText( $term );
00861
00862 # If the string cannot be used to create a title
00863 if( is_null( $t ) ){
00864 return $this->showResults( $term );
00865 }
00866
00867 # If there's an exact or very near match, jump right there.
00868 $t = SearchEngine::getNearMatch( $term );
00869 if( !is_null( $t ) ) {
00870 $wgOut->redirect( $t->getFullURL() );
00871 return;
00872 }
00873
00874 # No match, generate an edit URL
00875 $t =