213 $this->loadStatus =
new Status();
216 list( $this->limit, $this->offset ) = $request->getLimitOffsetForUser(
221 $this->mPrefix = $request->getVal(
'prefix',
'' );
222 if ( $this->mPrefix !==
'' ) {
226 $sort = $request->getVal(
'sort', SearchEngine::DEFAULT_SORT );
228 if ( !in_array(
$sort, $validSorts ) ) {
229 $this->loadStatus->warning(
'search-invalid-sort-order',
$sort,
230 implode(
', ', $validSorts ) );
231 } elseif (
$sort !== $this->sort ) {
238 # Extract manually requested namespaces
240 if ( $nslist === [] ) {
241 # Fallback to user preference
242 $nslist = $this->searchConfig->userNamespaces( $user );
246 if ( $nslist === [] ) {
255 foreach ( $profiles as $key => $data ) {
256 if ( $nslist === $data[
'namespaces'] && $key !==
'advanced' ) {
260 $this->namespaces = $nslist;
261 } elseif (
$profile ===
'advanced' ) {
262 $this->namespaces = $nslist;
263 } elseif ( isset( $profiles[
$profile][
'namespaces'] ) ) {
264 $this->namespaces = $profiles[$profile][
'namespaces'];
267 $this->loadStatus->warning(
'search-unknown-profile', $profile );
268 $profile =
'default';
269 $this->namespaces = $profiles[
'default'][
'namespaces'];
272 $this->fulltext = $request->getVal(
'fulltext' );
273 $this->runSuggestion = (bool)$request->getVal(
'runsuggestion',
true );
274 $this->profile = $profile;
332 if ( $this->searchEngineType !==
null ) {
333 $this->
setExtraParam(
'srbackend', $this->searchEngineType );
337 $widgetOptions = $this->
getConfig()->get(
'SpecialSearchFormOptions' );
344 $filePrefix = MediaWikiServices::getInstance()->getContentLanguage()->
345 getFormattedNsText(
NS_FILE ) .
':';
346 if ( trim( $term ) ===
'' || $filePrefix === trim( $term ) ) {
348 if ( !$this->
getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
349 # Hook requested termination
356 $out->addHTML( $formWidget->render(
357 $this->profile, $term, 0, 0, $this->offset, $this->isPowerSearch(), $widgetOptions
363 $engine->setFeatureData(
'rewrite', $this->runSuggestion );
364 $engine->setLimitOffset( $this->limit, $this->offset );
365 $engine->setNamespaces( $this->namespaces );
366 $engine->setSort( $this->sort );
367 $engine->prefix = $this->mPrefix;
369 $this->
getHookRunner()->onSpecialSearchSetupEngine( $this, $this->profile, $engine );
370 if ( !$this->
getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
371 # Hook requested termination
375 $title = Title::newFromText( $term );
376 $showSuggestion =
$title ===
null || !
$title->isKnown();
377 $engine->setShowSuggestion( $showSuggestion );
379 $rewritten = $engine->replacePrefixes( $term );
380 if ( $rewritten !== $term ) {
381 wfDeprecatedMsg(
'SearchEngine::replacePrefixes() was overridden by ' .
382 get_class( $engine ) .
', this is deprecated since MediaWiki 1.32',
383 '1.32',
false,
false );
387 $titleMatches = $engine->searchTitle( $rewritten );
388 $textMatches = $engine->searchText( $rewritten );
391 if ( $textMatches instanceof
Status ) {
392 $textStatus = $textMatches;
393 $textMatches = $textStatus->getValue();
397 $titleMatchesNum = $textMatchesNum = $numTitleMatches = $numTextMatches = 0;
398 if ( $titleMatches ) {
399 $titleMatchesNum = $titleMatches->numRows();
400 $numTitleMatches = $titleMatches->getTotalHits();
402 if ( $textMatches ) {
403 $textMatchesNum = $textMatches->numRows();
404 $numTextMatches = $textMatches->getTotalHits();
405 if ( $textMatchesNum > 0 ) {
406 $engine->augmentSearchResults( $textMatches );
409 $num = $titleMatchesNum + $textMatchesNum;
410 $totalRes = $numTitleMatches + $numTextMatches;
414 $out->addHTML( $formWidget->render(
415 $this->profile, $term, $num, $totalRes, $this->offset, $this->isPowerSearch(), $widgetOptions
419 if ( $textMatches ) {
421 $out->addHTML( $dymWidget->render( $term, $textMatches ) );
424 $hasSearchErrors = $textStatus && $textStatus->getErrors() !== [];
425 $hasOtherResults = $textMatches &&
426 $textMatches->hasInterwikiResults( ISearchResultSet::INLINE_RESULTS );
428 if ( $textMatches && $textMatches->hasInterwikiResults( ISearchResultSet::SECONDARY_RESULTS ) ) {
429 $out->addHTML(
'<div class="searchresults mw-searchresults-has-iw">' );
431 $out->addHTML(
'<div class="searchresults">' );
434 if ( $hasSearchErrors || $this->loadStatus->getErrors() ) {
435 if ( $textStatus ===
null ) {
436 $textStatus = $this->loadStatus;
438 $textStatus->merge( $this->loadStatus );
440 list( $error, $warning ) = $textStatus->splitByErrorType();
441 if ( $error->getErrors() ) {
442 $out->addHTML( Html::errorBox(
443 $error->getHTML(
'search-error' )
446 if ( $warning->getErrors() ) {
447 $out->addHTML( Html::warningBox(
448 $warning->getHTML(
'search-warning' )
456 $this->
getHookRunner()->onSpecialSearchResults( $term, $titleMatches, $textMatches );
459 if ( $num === 0 && !$hasSearchErrors ) {
460 $out->wrapWikiMsg(
"<p class=\"mw-search-nonefound\">\n$1</p>", [
461 $hasOtherResults ?
'search-nonefound-thiswiki' :
'search-nonefound',
473 if ( $engine->getFeatureData(
'enable-new-crossproject-page' ) !==
false ) {
477 $sidebarResultWidget,
479 MediaWikiServices::getInstance()->getInterwikiLookup(),
480 $engine->getFeatureData(
'show-multimedia-search-results' )
486 $sidebarResultWidget,
488 MediaWikiServices::getInstance()->getInterwikiLookup()
494 $out->addHTML( $widget->render(
495 $term, $this->offset, $titleMatches, $textMatches
498 $out->addHTML(
'<div class="mw-search-visualclear"></div>' );
501 if ( $totalRes > $this->limit || $this->offset ) {
504 if ( $textMatches && $textMatches->getOffset() !==
null ) {
505 $offset = $textMatches->getOffset();
507 $offset = $this->offset;
514 $this->limit + $this->offset >= $totalRes
516 $out->addHTML(
"<p class='mw-search-pager-bottom'>{$prevNext}</p>\n" );
520 $out->addHTML(
"</div>" );
522 $this->
getHookRunner()->onSpecialSearchResultsAppend( $this, $out, $term );