Extract main search result rendering from SpecialSearch
[lhc/web/wiklou.git] / includes / specials / SpecialSearch.php
index 37d86c3..735194e 100644 (file)
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Widget\Search\BasicSearchResultSetWidget;
+use MediaWiki\Widget\Search\InterwikiSearchResultSetWidget;
+use MediaWiki\Widget\Search\FullSearchResultWidget;
+use MediaWiki\Widget\Search\SimpleSearchResultWidget;
 
 /**
  * implements Special:Search - Run text & title search and display the output
@@ -75,12 +79,6 @@ class SpecialSearch extends SpecialPage {
         */
        protected $runSuggestion = true;
 
-       /**
-        * Names of the wikis, in format: Interwiki prefix -> caption
-        * @var array
-        */
-       protected $customCaptions;
-
        /**
         * Search engine configurations.
         * @var SearchEngineConfig
@@ -327,6 +325,9 @@ class SpecialSearch extends SpecialPage {
                if ( $textMatches ) {
                        $textMatchesNum = $textMatches->numRows();
                        $numTextMatches = $textMatches->getTotalHits();
+                       if ( $textMatchesNum > 0 ) {
+                               $search->augmentSearchResults( $textMatches );
+                       }
                }
                $num = $titleMatchesNum + $textMatchesNum;
                $totalRes = $numTitleMatches + $numTextMatches;
@@ -373,6 +374,8 @@ class SpecialSearch extends SpecialPage {
                // Show the create link ahead
                $this->showCreateLink( $title, $num, $titleMatches, $textMatches );
 
+               Hooks::run( 'SpecialSearchResults', [ $term, $titleMatches, $textMatches ] );
+
                // If we have no results and have not already displayed an error message
                if ( $num === 0 && !$hasErrors ) {
                        $out->wrapWikiMsg( "<p class=\"mw-search-nonefound\">\n$1</p>", [
@@ -381,50 +384,27 @@ class SpecialSearch extends SpecialPage {
                        ] );
                }
 
-               Hooks::run( 'SpecialSearchResults', [ $term, $titleMatches, $textMatches ] );
+               // Although $num might be 0 there can still be secondary or inline
+               // results to display.
+               $linkRenderer = $this->getLinkRenderer();
+               $mainResultWidget = new FullSearchResultWidget( $this, $linkRenderer );
+               $sidebarResultWidget = new SimpleSearchResultWidget( $this, $linkRenderer );
+               $sidebarResultsWidget = new InterwikiSearchResultSetWidget(
+                       $this,
+                       $sidebarResultWidget,
+                       $linkRenderer,
+                       MediaWikiServices::getInstance()->getInterwikiLookup()
+               );
+               $widget = new BasicSearchResultSetWidget( $this, $mainResultWidget, $sidebarResultsWidget );
+
+               $out->addHTML( $widget->render(
+                       $term, $this->offset, $titleMatches, $textMatches
+               ) );
 
-               $out->parserOptions()->setEditSection( false );
                if ( $titleMatches ) {
-                       if ( $numTitleMatches > 0 ) {
-                               $out->wrapWikiMsg( "==$1==\n", 'titlematches' );
-                               $out->addHTML( $this->showMatches( $titleMatches ) );
-                       }
                        $titleMatches->free();
                }
 
-               if ( $textMatches ) {
-                       // output appropriate heading
-                       if ( $numTextMatches > 0 && $numTitleMatches > 0 ) {
-                               $out->addHTML( '<div class="mw-search-visualclear"></div>' );
-                               // if no title matches the heading is redundant
-                               $out->wrapWikiMsg( "==$1==\n", 'textmatches' );
-                       }
-
-                       // show results
-                       if ( $numTextMatches > 0 ) {
-                               $search->augmentSearchResults( $textMatches );
-                               $out->addHTML( $this->showMatches( $textMatches ) );
-                       }
-
-                       // show secondary interwiki results if any
-                       if ( $textMatches->hasInterwikiResults( SearchResultSet::SECONDARY_RESULTS ) ) {
-                               $out->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(
-                                               SearchResultSet::SECONDARY_RESULTS ), $term ) );
-                       }
-               }
-
-               if ( $hasOtherResults ) {
-                       foreach ( $textMatches->getInterwikiResults( SearchResultSet::INLINE_RESULTS )
-                                               as $interwiki => $interwikiResult ) {
-                               if ( $interwikiResult instanceof Status || $interwikiResult->numRows() == 0 ) {
-                                       // ignore bad interwikis for now
-                                       continue;
-                               }
-                               // TODO: wiki header
-                               $out->addHTML( $this->showMatches( $interwikiResult, $interwiki ) );
-                       }
-               }
-
                if ( $textMatches ) {
                        $textMatches->free();
                }
@@ -449,18 +429,6 @@ class SpecialSearch extends SpecialPage {
                Hooks::run( 'SpecialSearchResultsAppend', [ $this, $out, $term ] );
        }
 
-       /**
-        * Produce wiki header for interwiki results
-        * @param string $interwiki Interwiki name
-        * @param SearchResultSet $interwikiResult The result set
-        * @return string
-        */
-       protected function interwikiHeader( $interwiki, $interwikiResult ) {
-               // TODO: we need to figure out how to name wikis correctly
-               $wikiMsg = $this->msg( 'search-interwiki-results-' . $interwiki )->parse();
-               return "<p class=\"mw-search-interwiki-header mw-search-visualclear\">\n$wikiMsg</p>";
-       }
-
        /**
         * Generates HTML shown to the user when we have a suggestion about a query
         * that might give more results than their current query.
@@ -711,146 +679,6 @@ class SpecialSearch extends SpecialPage {
                return false;
        }
 
-       /**
-        * Show whole set of results
-        *
-        * @param SearchResultSet $matches
-        * @param string $interwiki Interwiki name
-        *
-        * @return string
-        */
-       protected function showMatches( $matches, $interwiki = null ) {
-               global $wgContLang;
-
-               $terms = $wgContLang->convertForSearchResult( $matches->termMatches() );
-               $out = '';
-               $result = $matches->next();
-               $pos = $this->offset;
-
-               if ( $result && $interwiki ) {
-                       $out .= $this->interwikiHeader( $interwiki, $matches );
-               }
-
-               $out .= "<ul class='mw-search-results'>\n";
-               $widget = new \MediaWiki\Widget\Search\FullSearchResultWidget(
-                       $this,
-                       $this->getLinkRenderer()
-               );
-               while ( $result ) {
-                       $out .= $widget->render( $result, $terms, $pos++ );
-                       $result = $matches->next();
-               }
-               $out .= "</ul>\n";
-
-               // convert the whole thing to desired language variant
-               $out = $wgContLang->convert( $out );
-
-               return $out;
-       }
-
-       /**
-        * Extract custom captions from search-interwiki-custom message
-        */
-       protected function getCustomCaptions() {
-               if ( is_null( $this->customCaptions ) ) {
-                       $this->customCaptions = [];
-                       // format per line <iwprefix>:<caption>
-                       $customLines = explode( "\n", $this->msg( 'search-interwiki-custom' )->text() );
-                       foreach ( $customLines as $line ) {
-                               $parts = explode( ":", $line, 2 );
-                               if ( count( $parts ) == 2 ) { // validate line
-                                       $this->customCaptions[$parts[0]] = $parts[1];
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Show results from other wikis
-        *
-        * @param SearchResultSet|array $matches
-        * @param string $terms
-        *
-        * @return string
-        */
-       protected function showInterwiki( $matches, $terms ) {
-               global $wgContLang;
-
-               // work out custom project captions
-               $this->getCustomCaptions();
-
-               if ( !is_array( $matches ) ) {
-                       $matches = [ $matches ];
-               }
-
-               $iwResults = [];
-               foreach ( $matches as $set ) {
-                       $result = $set->next();
-                       while ( $result ) {
-                               if ( !$result->isBrokenTitle() ) {
-                                       $iwResults[$result->getTitle()->getInterwiki()][] = $result;
-                               }
-                               $result = $set->next();
-                       }
-               }
-
-               $out = '';
-               $widget = new MediaWiki\Widget\Search\SimpleSearchResultWidget(
-                       $this,
-                       $this->getLinkRenderer()
-               );
-               foreach ( $iwResults as $iwPrefix => $results ) {
-                       $out .= $this->iwHeaderHtml( $iwPrefix, $terms );
-                       $out .= "<ul class='mw-search-iwresults'>";
-                       foreach ( $results as $result ) {
-                               // This makes the bold asumption interwiki results are never paginated.
-                               // That's currently true, but could change at some point?
-                               $out .= $widget->render( $result, $terms, 0 );
-                       }
-                       $out .= "</ul>";
-               }
-
-               $out =
-                       "<div id='mw-search-interwiki'>" .
-                               "<div id='mw-search-interwiki-caption'>" .
-                                       $this->msg( 'search-interwiki-caption' )->escaped() .
-                               "</div>" .
-                               $out .
-                       "</div>";
-
-               // convert the whole thing to desired language variant
-               return $wgContLang->convert( $out );
-       }
-
-       /**
-        * @param string $iwPrefix The interwiki prefix to render a header for
-        * @param string $terms The user-provided search terms
-        */
-       protected function iwHeaderHtml( $iwPrefix, $terms ) {
-               if ( isset( $this->customCaptions[$iwPrefix] ) ) {
-                       $caption = $this->customCaptions[$iwPrefix];
-               } else {
-                       $iwLookup = MediaWiki\MediaWikiServices::getInstance()->getInterwikiLookup();
-                       $interwiki = $iwLookup->fetch( $iwPrefix );
-                       $parsed = wfParseUrl( wfExpandUrl( $interwiki ? $interwiki->getURL() : '/' ) );
-                       $caption = $this->msg( 'search-interwiki-default', $parsed['host'] )->text();
-               }
-               $searchLink = Linker::linkKnown(
-                       Title::newFromText( "$iwPrefix:Special:Search" ),
-                       $this->msg( 'search-interwiki-more' )->text(),
-                       [],
-                       [
-                               'search' => $terms,
-                               'fulltext' => 1,
-                       ]
-               );
-               return
-                       "<div class='mw-search-interwiki-project'>" .
-                               "<span class='mw-search-interwiki-more'>{$searchLink}</span>" .
-                               $caption .
-                       "</div>";
-       }
-
        /**
         * @return array
         */