BasicSearchResultSetWidget.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. namespace MediaWiki\Widget\Search;
  3. use ISearchResultSet;
  4. use MediaWiki\MediaWikiServices;
  5. use Message;
  6. use SpecialSearch;
  7. use Status;
  8. /**
  9. * Renders the search result area. Handles Title and Full-Text search results,
  10. * along with inline and sidebar secondary (interwiki) results.
  11. */
  12. class BasicSearchResultSetWidget {
  13. /** @var SpecialSearch */
  14. protected $specialPage;
  15. /** @var SearchResultWidget */
  16. protected $resultWidget;
  17. /** @var InterwikiSearchResultSetWidget */
  18. protected $sidebarWidget;
  19. public function __construct(
  20. SpecialSearch $specialPage,
  21. SearchResultWidget $resultWidget,
  22. SearchResultSetWidget $sidebarWidget
  23. ) {
  24. $this->specialPage = $specialPage;
  25. $this->resultWidget = $resultWidget;
  26. $this->sidebarWidget = $sidebarWidget;
  27. }
  28. /**
  29. * @param string $term The search term to highlight
  30. * @param int $offset The offset of the first result in the result set
  31. * @param ISearchResultSet|null $titleResultSet Results of searching only page titles
  32. * @param ISearchResultSet|null $textResultSet Results of general full text search.
  33. * @return string HTML
  34. */
  35. public function render(
  36. $term,
  37. $offset,
  38. ISearchResultSet $titleResultSet = null,
  39. ISearchResultSet $textResultSet = null
  40. ) {
  41. $hasTitle = $titleResultSet ? $titleResultSet->numRows() > 0 : false;
  42. $hasText = $textResultSet ? $textResultSet->numRows() > 0 : false;
  43. $hasSecondary = $textResultSet
  44. ? $textResultSet->hasInterwikiResults( ISearchResultSet::SECONDARY_RESULTS )
  45. : false;
  46. $hasSecondaryInline = $textResultSet
  47. ? $textResultSet->hasInterwikiResults( ISearchResultSet::INLINE_RESULTS )
  48. : false;
  49. if ( !$hasTitle && !$hasText && !$hasSecondary && !$hasSecondaryInline ) {
  50. return '';
  51. }
  52. $out = '';
  53. if ( $hasTitle ) {
  54. $out .= $this->header( $this->specialPage->msg( 'titlematches' ) )
  55. . $this->renderResultSet( $titleResultSet, $offset );
  56. }
  57. if ( $hasText ) {
  58. if ( $hasTitle ) {
  59. $out .= "<div class='mw-search-visualclear'></div>" .
  60. $this->header( $this->specialPage->msg( 'textmatches' ) );
  61. }
  62. $out .= $this->renderResultSet( $textResultSet, $offset );
  63. }
  64. if ( $hasSecondaryInline ) {
  65. $iwResults = $textResultSet->getInterwikiResults( ISearchResultSet::INLINE_RESULTS );
  66. foreach ( $iwResults as $interwiki => $results ) {
  67. if ( $results instanceof Status || $results->numRows() === 0 ) {
  68. // ignore bad interwikis for now
  69. continue;
  70. }
  71. $out .=
  72. "<h2 class='mw-search-interwiki-header mw-search-visualclear'>" .
  73. $this->specialPage->msg( "search-interwiki-results-{$interwiki}" )->parse() .
  74. "</h2>";
  75. $out .= $this->renderResultSet( $results, $offset );
  76. }
  77. }
  78. if ( $hasSecondary ) {
  79. $out .= $this->sidebarWidget->render(
  80. $term,
  81. $textResultSet->getInterwikiResults( ISearchResultSet::SECONDARY_RESULTS )
  82. );
  83. }
  84. // Convert the whole thing to desired language variant
  85. // TODO: Move this up to Special:Search?
  86. return MediaWikiServices::getInstance()->getContentLanguage()->convert( $out );
  87. }
  88. /**
  89. * Generate a headline for a section of the search results. In prior
  90. * implementations this was rendering wikitext of '==$1==', but seems
  91. * a waste to call the full parser to generate this tiny bit of html
  92. *
  93. * @param Message $msg i18n message to use as header
  94. * @return string HTML
  95. */
  96. protected function header( Message $msg ) {
  97. return "<h2>" .
  98. "<span class='mw-headline'>" . $msg->escaped() . "</span>" .
  99. "</h2>";
  100. }
  101. /**
  102. * @param ISearchResultSet $resultSet The search results to render
  103. * @param int $offset Offset of the first result in $resultSet
  104. * @return string HTML
  105. */
  106. protected function renderResultSet( ISearchResultSet $resultSet, $offset ) {
  107. $hits = [];
  108. foreach ( $resultSet as $result ) {
  109. $hits[] = $this->resultWidget->render( $result, $offset++ );
  110. }
  111. return "<ul class='mw-search-results'>" . implode( '', $hits ) . "</ul>";
  112. }
  113. }