wiki.techinc.nl/includes/widget/search/BasicSearchResultSetWidget.php
Erik Bernhardson a0936780bb Extract main search result rendering from SpecialSearch
Has a pre-existing problem related to the link offset of secondary
inline results. Specifically the offset of secondary inline starts
at the provided offset, even though there may be primary results
displayed above it.

Bug: T150390
Change-Id: Id1d6b357f45a2cf615d9412cc95dd597c724e8b6
2017-01-17 15:57:40 -08:00

135 lines
3.9 KiB
PHP

<?php
namespace MediaWiki\Widget\Search;
use Message;
use SearchResultSet;
use SpecialSearch;
use Status;
/**
* Renders the search result area. Handles Title and Full-Text search results,
* along with inline and sidebar secondary (interwiki) results.
*/
class BasicSearchResultSetWidget {
/** @var SpecialSearch */
protected $specialPage;
/** @var SearchResultWidget */
protected $resultWidget;
/** @var InterwikiSearchResultSetWidget */
protected $sidebarWidget;
public function __construct(
SpecialSearch $specialPage,
SearchResultWidget $resultWidget,
InterwikiSearchResultSetWidget $sidebarWidget
) {
$this->specialPage = $specialPage;
$this->resultWidget = $resultWidget;
$this->sidebarWidget = $sidebarWidget;
}
/**
* @param string $term The search term to highlight
* @param int $offset The offset of the first result in the result set
* @param SearchResultSet|null $titleResultSet Results of searching only page titles
* @param SearchResultSet|null $textResultSet Results of general full text search.
* @return string HTML
*/
public function render(
$term,
$offset,
SearchResultSet $titleResultSet = null,
SearchResultSet $textResultSet = null
) {
global $wgContLang;
$hasTitle = $titleResultSet ? $titleResultSet->numRows() > 0 : false;
$hasText = $textResultSet ? $textResultSet->numRows() > 0 : false;
$hasSecondary = $textResultSet
? $textResultSet->hasInterwikiResults( SearchResultSet::SECONDARY_RESULTS )
: false;
$hasSecondaryInline = $textResultSet
? $textResultSet->hasInterwikiResults( SearchResultSet::INLINE_RESULTS )
: false;
if ( !$hasTitle && !$hasText && !$hasSecondary && !$hasSecondaryInline ) {
return '';
}
$out = '';
if ( $hasTitle ) {
$out .= $this->header( $this->specialPage->msg( 'titlematches' ) )
. $this->renderResultSet( $titleResultSet, $offset );
}
if ( $hasText ) {
if ( $hasTitle ) {
$out .= "<div class='mw-search-visualclear'></div>" .
$this->header( $this->specialPage->msg( 'textmatches' ) );
}
$out .= $this->renderResultSet( $textResultSet, $offset );
}
if ( $hasSecondaryInline ) {
$iwResults = $textResultSet->getInterwikiResults( SearchResultSet::INLINE_RESULTS );
foreach ( $iwResults as $interwiki => $results ) {
if ( $results instanceof Status || $results->numRows() === 0 ) {
// ignore bad interwikis for now
continue;
}
$out .=
"<p class='mw-search-interwiki-header mw-search-visualclear'>" .
$this->specialPage->msg( "search-interwiki-results-{$interwiki}" )->parse() .
"</p>";
$out .= $this->renderResultSet( $results, $offset );
}
}
if ( $hasSecondary ) {
$out .= $this->sidebarWidget->render(
$term,
$textResultSet->getInterwikiResults( SearchResultSet::SECONDARY_RESULTS )
);
}
// Convert the whole thing to desired language variant
// TODO: Move this up to Special:Search?
return $wgContLang->convert( $out );
}
/**
* Generate a headline for a section of the search results. In prior
* implementations this was rendering wikitext of '==$1==', but seems
* a waste to call the full parser to generate this tiny bit of html
*
* @param Message $msg i18n message to use as header
* @return string HTML
*/
protected function header( Message $msg ) {
return
"<h2>" .
"<span class='mw-headline'>" . $msg->escaped() . "</span>" .
"</h2>";
}
/**
* @param SearchResultSet $resultSet The search results to render
* @param int $offset Offset of the first result in $resultSet
* @return string HTML
*/
protected function renderResultSet( SearchResultSet $resultSet, $offset ) {
global $wgContLang;
$terms = $wgContLang->convertForSearchResult( $resultSet->termMatches() );
$hits = [];
$result = $resultSet->next();
while ( $result ) {
$hits[] .= $this->resultWidget->render( $result, $terms, $offset++ );
$result = $resultSet->next();
}
return "<ul class='mw-search-results'>" . implode( '', $hits ) . "</ul>";
}
}