355 if ( $this->searchEngineType !==
null ) {
356 $this->setExtraParam(
'srbackend', $this->searchEngineType );
359 $out = $this->getOutput();
368 $this->getHookContainer(),
369 $this->languageConverterFactory->getLanguageConverter( $this->getLanguage() ),
371 $this->getSearchProfiles()
373 $filePrefix = $this->getContentLanguage()->getFormattedNsText(
NS_FILE ) .
':';
374 if ( trim( $term ) ===
'' || $filePrefix === trim( $term ) ) {
376 if ( !$this->getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
377 # Hook requested termination
384 $out->
addHTML( $formWidget->render(
385 $this->profile, $term, 0, 0,
false, $this->offset, $this->isPowerSearch(), $widgetOptions
390 $engine = $this->getSearchEngine();
391 $engine->setFeatureData(
'rewrite', $this->runSuggestion );
392 $engine->setLimitOffset( $this->limit, $this->offset );
393 $engine->setNamespaces( $this->namespaces );
394 $engine->setSort( $this->sort );
395 $engine->prefix = $this->mPrefix;
397 $this->getHookRunner()->onSpecialSearchSetupEngine( $this, $this->profile, $engine );
398 if ( !$this->getHookRunner()->onSpecialSearchResultsPrepend( $this, $out, $term ) ) {
399 # Hook requested termination
403 $titleNs = count( $this->namespaces ) === 1 ? reset( $this->namespaces ) :
null;
404 $title = Title::newFromText( $term, $titleNs );
405 $languageConverter = $this->languageConverterFactory->getLanguageConverter( $this->getContentLanguage() );
406 if ( $languageConverter->hasVariants() ) {
409 $variantTerm = $term;
410 $languageConverter->findVariantLink( $variantTerm, $title );
413 $showSuggestion = $title ===
null || !$title->isKnown();
414 $engine->setShowSuggestion( $showSuggestion );
417 $titleMatches = $engine->searchTitle( $term );
418 $textMatches = $engine->searchText( $term );
421 if ( $textMatches instanceof
Status ) {
422 $textStatus = $textMatches;
423 $textMatches = $textStatus->getValue();
426 if ( $textMatches && $textMatches->
numRows() ) {
427 $engine->augmentSearchResults( $textMatches );
430 $this->getHookRunner()->onSpecialSearchResults( $term, $titleMatches, $textMatches );
433 $titleMatchesNum = $textMatchesNum = $numTitleMatches = $numTextMatches = 0;
434 $approxTotalRes =
false;
435 if ( $titleMatches ) {
436 $titleMatchesNum = $titleMatches->
numRows();
437 $numTitleMatches = $titleMatches->getTotalHits();
438 $approxTotalRes = $titleMatches->isApproximateTotalHits();
440 if ( $textMatches ) {
441 $textMatchesNum = $textMatches->
numRows();
445 $num = $titleMatchesNum + $textMatchesNum;
446 $totalRes = $numTitleMatches + $numTextMatches;
450 $out->
addHTML( $formWidget->render(
451 $this->profile, $term, $num, $totalRes, $approxTotalRes, $this->offset, $this->isPowerSearch(),
456 if ( $textMatches ) {
458 $out->
addHTML( $dymWidget->render( $term, $textMatches ) );
461 $hasSearchErrors = $textStatus && $textStatus->getMessages() !== [];
462 $hasInlineIwResults = $textMatches &&
464 $hasSecondaryIwResults = $textMatches &&
467 $classNames = [
'searchresults' ];
468 if ( $hasSecondaryIwResults ) {
469 $classNames[] =
'mw-searchresults-has-iw';
471 if ( $this->offset > 0 ) {
472 $classNames[] =
'mw-searchresults-has-offset';
474 $out->
addHTML( Html::openElement(
'div', [
'class' => $classNames ] ) );
476 $out->
addHTML(
'<div class="mw-search-results-info">' );
478 if ( $hasSearchErrors || $this->loadStatus->getMessages() ) {
479 if ( $textStatus ===
null ) {
480 $textStatus = $this->loadStatus;
482 $textStatus->merge( $this->loadStatus );
484 [ $error, $warning ] = $textStatus->splitByErrorType();
485 if ( $error->getMessages() ) {
487 $error->getHTML(
'search-error' )
490 if ( $warning->getMessages() ) {
491 $out->
addHTML( Html::warningBox(
492 $warning->getHTML(
'search-warning' )
498 if ( $num === 0 && !$hasSearchErrors ) {
499 $out->
wrapWikiMsg(
"<p class=\"mw-search-nonefound\">\n$1</p>", [
500 $hasInlineIwResults ?
'search-nonefound-thiswiki' :
'search-nonefound',
507 $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
514 $linkRenderer = $this->getLinkRenderer();
518 $this->getHookContainer(),
520 $this->thumbnailProvider,
521 $this->userOptionsManager
527 $sidebarResultWidget,
529 $this->interwikiLookup,
530 $engine->getFeatureData(
'show-multimedia-search-results' ) ??
false
535 $out->
addHTML(
'<div class="mw-search-visualclear"></div>' );
536 $this->prevNextLinks( $totalRes, $textMatches, $term,
'mw-search-pager-top', $out );
538 $out->
addHTML( $widget->render(
539 $term, $this->offset, $titleMatches, $textMatches
542 $out->
addHTML(
'<div class="mw-search-visualclear"></div>' );
543 $this->prevNextLinks( $totalRes, $textMatches, $term,
'mw-search-pager-bottom', $out );
548 $this->getHookRunner()->onSpecialSearchResultsAppend( $this, $out, $term );
561 if ( $title ===
null || $title->getDBkey() ===
''
562 || ( $titleMatches !==
null && $titleMatches->searchContainedSyntax() )
567 $this->getOutput()->addHTML(
'<p></p>' );
572 $messageName =
'searchmenu-new-nocreate';
573 $linkClass =
'mw-search-createlink';
575 if ( !$title->isExternal() ) {
576 if ( $title->isKnown() ) {
578 if ( $titleMatches && $titleMatches->numRows() > 0 ) {
579 $firstTitle = $titleMatches->extractTitles()[0] ??
null;
580 } elseif ( $textMatches && $textMatches->
numRows() > 0 ) {
584 if ( $firstTitle && $title->isSamePageAs( $firstTitle ) ) {
587 $messageName =
'searchmenu-exists';
588 $linkClass =
'mw-search-exists';
591 $this->contentHandlerFactory->getContentHandler( $title->getContentModel() )
592 ->supportsDirectEditing()
593 && $this->getAuthority()->probablyCan(
'edit', $title )
595 $messageName =
'searchmenu-new';
598 $messageName =
'searchmenu-new-external';
606 $this->getHookRunner()->onSpecialSearchCreateLink( $title, $params );
609 if ( $messageName ) {
610 $this->getOutput()->wrapWikiMsg(
"<p class=\"$linkClass\">\n$1</p>", $params );