328 if ( $this->searchEngineType !==
null ) {
329 $this->setExtraParam(
'srbackend', $this->searchEngineType );
332 $out = $this->getOutput();
337 $this->getHookContainer(),
338 $this->languageConverterFactory->getLanguageConverter( $this->getLanguage() ),
340 $this->getSearchProfiles()
342 $filePrefix = $this->getContentLanguage()->getFormattedNsText(
NS_FILE ) .
':';
343 if ( trim( $term ) ===
'' || $filePrefix === trim( $term ) ) {
345 if ( !$this->getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
346 # Hook requested termination
353 $out->
addHTML( $formWidget->render(
354 $this->profile, $term, 0, 0,
false, $this->offset, $this->isPowerSearch(), $widgetOptions
359 $engine = $this->getSearchEngine();
360 $engine->setFeatureData(
'rewrite', $this->runSuggestion );
361 $engine->setLimitOffset( $this->limit, $this->offset );
362 $engine->setNamespaces( $this->namespaces );
363 $engine->setSort( $this->sort );
364 $engine->prefix = $this->mPrefix;
366 $this->getHookRunner()->onSpecialSearchSetupEngine( $this, $this->profile, $engine );
367 if ( !$this->getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
368 # Hook requested termination
372 $titleNs = count( $this->namespaces ) === 1 ? reset( $this->namespaces ) :
null;
373 $title = Title::newFromText( $term, $titleNs );
374 $languageConverter = $this->languageConverterFactory->getLanguageConverter( $this->getContentLanguage() );
375 if ( $languageConverter->hasVariants() ) {
378 $variantTerm = $term;
379 $languageConverter->findVariantLink( $variantTerm, $title );
382 $showSuggestion = $title ===
null || !$title->isKnown();
383 $engine->setShowSuggestion( $showSuggestion );
386 $titleMatches = $engine->searchTitle( $term );
387 $textMatches = $engine->searchText( $term );
391 $textStatus = $textMatches;
392 $textMatches = $textStatus->getValue();
395 if ( $textMatches && $textMatches->
numRows() ) {
396 $engine->augmentSearchResults( $textMatches );
399 $this->getHookRunner()->onSpecialSearchResults( $term, $titleMatches, $textMatches );
402 $titleMatchesNum = $textMatchesNum = $numTitleMatches = $numTextMatches = 0;
403 $approxTotalRes =
false;
404 if ( $titleMatches ) {
405 $titleMatchesNum = $titleMatches->
numRows();
406 $numTitleMatches = $titleMatches->getTotalHits();
407 $approxTotalRes = $titleMatches->isApproximateTotalHits();
409 if ( $textMatches ) {
410 $textMatchesNum = $textMatches->
numRows();
414 $num = $titleMatchesNum + $textMatchesNum;
415 $totalRes = $numTitleMatches + $numTextMatches;
419 $out->
addHTML( $formWidget->render(
420 $this->profile, $term, $num, $totalRes, $approxTotalRes, $this->offset, $this->isPowerSearch(),
425 if ( $textMatches ) {
427 $out->
addHTML( $dymWidget->render( $term, $textMatches ) );
430 $hasSearchErrors = $textStatus && $textStatus->getMessages() !== [];
431 $hasInlineIwResults = $textMatches &&
433 $hasSecondaryIwResults = $textMatches &&
436 $classNames = [
'searchresults' ];
437 if ( $hasSecondaryIwResults ) {
438 $classNames[] =
'mw-searchresults-has-iw';
440 if ( $this->offset > 0 ) {
441 $classNames[] =
'mw-searchresults-has-offset';
443 $out->
addHTML( Html::openElement(
'div', [
'class' => $classNames ] ) );
445 $out->
addHTML(
'<div class="mw-search-results-info">' );
447 if ( $hasSearchErrors || $this->loadStatus->getMessages() ) {
448 if ( $textStatus ===
null ) {
449 $textStatus = $this->loadStatus;
451 $textStatus->merge( $this->loadStatus );
453 [ $error, $warning ] = $textStatus->splitByErrorType();
454 if ( $error->getMessages() ) {
456 Status::wrap( $error )->getHTML(
'search-error' )
459 if ( $warning->getMessages() ) {
460 $out->
addHTML( Html::warningBox(
461 Status::wrap( $warning )->getHTML(
'search-warning' )
467 if ( $num === 0 && !$hasSearchErrors ) {
468 $out->
wrapWikiMsg(
"<p class=\"mw-search-nonefound\">\n$1</p>", [
469 $hasInlineIwResults ?
'search-nonefound-thiswiki' :
'search-nonefound',
476 $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
483 $linkRenderer = $this->getLinkRenderer();
487 $this->getHookContainer(),
489 $this->thumbnailProvider,
490 $this->userOptionsManager
496 $sidebarResultWidget,
498 $this->interwikiLookup,
499 $engine->getFeatureData(
'show-multimedia-search-results' ) ??
false
504 $out->
addHTML(
'<div class="mw-search-visualclear"></div>' );
505 $this->prevNextLinks( $totalRes, $textMatches, $term,
'mw-search-pager-top', $out );
507 $out->
addHTML( $widget->render(
508 $term, $this->offset, $titleMatches, $textMatches
511 $out->
addHTML(
'<div class="mw-search-visualclear"></div>' );
512 $this->prevNextLinks( $totalRes, $textMatches, $term,
'mw-search-pager-bottom', $out );
517 $this->getHookRunner()->onSpecialSearchResultsAppend( $this, $out, $term );
530 if ( $title ===
null || $title->getDBkey() ===
''
531 || ( $titleMatches !==
null && $titleMatches->searchContainedSyntax() )
536 $this->getOutput()->addHTML(
'<p></p>' );
541 $messageName =
'searchmenu-new-nocreate';
542 $linkClass =
'mw-search-createlink';
544 if ( !$title->isExternal() ) {
545 if ( $title->isKnown() ) {
547 if ( $titleMatches && $titleMatches->numRows() > 0 ) {
548 $firstTitle = $titleMatches->extractTitles()[0] ??
null;
549 } elseif ( $textMatches && $textMatches->
numRows() > 0 ) {
553 if ( $firstTitle && $title->isSamePageAs( $firstTitle ) ) {
556 $messageName =
'searchmenu-exists';
557 $linkClass =
'mw-search-exists';
560 $this->contentHandlerFactory->getContentHandler( $title->getContentModel() )
561 ->supportsDirectEditing()
562 && $this->getAuthority()->probablyCan(
'edit', $title )
564 $messageName =
'searchmenu-new';
567 $messageName =
'searchmenu-new-external';
575 $this->getHookRunner()->onSpecialSearchCreateLink( $title, $params );
578 if ( $messageName ) {
579 $this->getOutput()->wrapWikiMsg(
"<p class=\"$linkClass\">\n$1</p>", $params );