Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
DidYouMeanWidget
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 4
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 render
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 rewrittenHtml
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
12
 suggestionHtml
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace MediaWiki\Search\SearchWidgets;
4
5use ISearchResultSet;
6use MediaWiki\Html\Html;
7use MediaWiki\Specials\SpecialSearch;
8
9/**
10 * Renders a suggested search for the user, or tells the user
11 * a suggested search was run instead of the one provided.
12 */
13class DidYouMeanWidget {
14    /** @var SpecialSearch */
15    protected $specialSearch;
16
17    public function __construct( SpecialSearch $specialSearch ) {
18        $this->specialSearch = $specialSearch;
19    }
20
21    /**
22     * @param string $term The user provided search term
23     * @param ISearchResultSet $resultSet
24     * @return string HTML
25     */
26    public function render( $term, ISearchResultSet $resultSet ) {
27        if ( $resultSet->hasRewrittenQuery() ) {
28            $html = $this->rewrittenHtml( $term, $resultSet );
29        } elseif ( $resultSet->hasSuggestion() ) {
30            $html = $this->suggestionHtml( $resultSet );
31        } else {
32            return '';
33        }
34
35        return Html::rawElement( 'div', [ 'class' => 'searchdidyoumean' ], $html );
36    }
37
38    /**
39     * Generates HTML shown to user when their query has been internally
40     * rewritten, and the results of the rewritten query are being returned.
41     *
42     * @param string $term The users search input
43     * @param ISearchResultSet $resultSet The response to the search request
44     * @return string HTML Links the user to their original $term query, and the
45     *  one suggested by $resultSet
46     */
47    protected function rewrittenHtml( $term, ISearchResultSet $resultSet ) {
48        $params = [
49            'search' => $resultSet->getQueryAfterRewrite(),
50            // Don't magic this link into a 'go' link, it should always
51            // show search results.
52            'fulltext' => 1,
53        ];
54        $stParams = array_merge( $params, $this->specialSearch->powerSearchOptions() );
55
56        $linkRenderer = $this->specialSearch->getLinkRenderer();
57        $snippet = $resultSet->getQueryAfterRewriteSnippet();
58        if ( $snippet === '' || $snippet === null ) {
59            // This should never happen. But if it did happen we would render
60            // links as `Special:Search` which is even more useless. Since this
61            // was only documented but not enforced previously emit a
62            // deprecation warning and in the future we can simply fail on bad
63            // inputs
64            wfDeprecatedMsg(
65                get_class( $resultSet ) . '::getQueryAfterRewriteSnippet returning empty snippet ' .
66                'was deprecated in MediaWiki 1.35',
67                '1.34', false, false
68            );
69            $snippet = $resultSet->getQueryAfterRewrite();
70        }
71        $rewritten = $linkRenderer->makeKnownLink(
72            $this->specialSearch->getPageTitle(),
73            $snippet,
74            [ 'id' => 'mw-search-DYM-rewritten' ],
75            $stParams
76        );
77
78        $original = $term;
79
80        return $this->specialSearch->msg( 'search-rewritten' )
81            ->rawParams( $rewritten )
82            ->params( $original )
83            ->escaped();
84    }
85
86    /**
87     * Generates HTML shown to the user when we have a suggestion about
88     * a query that might give more/better results than their current
89     * query.
90     *
91     * @param ISearchResultSet $resultSet
92     * @return string HTML
93     */
94    protected function suggestionHtml( ISearchResultSet $resultSet ) {
95        $params = [
96            'search' => $resultSet->getSuggestionQuery(),
97            'fulltext' => 1,
98        ];
99        $stParams = array_merge( $params, $this->specialSearch->powerSearchOptions() );
100
101        $snippet = $resultSet->getSuggestionSnippet();
102        if ( $snippet === '' || $snippet === null ) {
103            // This should never happen. But if it did happen we would render
104            // links as `Special:Search` which is even more useless. Since this
105            // was only documented but not enforced previously emit a
106            // deprecation warning and in the future we can simply fail on bad
107            // inputs
108            wfDeprecatedMsg(
109                get_class( $resultSet ) . '::getSuggestionSnippet returning empty snippet ' .
110                'was deprecated in MediaWiki 1.35',
111                '1.34', false, false
112            );
113            $snippet = $resultSet->getSuggestionSnippet();
114        }
115        $suggest = $this->specialSearch->getLinkRenderer()->makeKnownLink(
116            $this->specialSearch->getPageTitle(),
117            $snippet,
118            [ 'id' => 'mw-search-DYM-suggestion' ],
119            $stParams
120        );
121
122        return $this->specialSearch->msg( 'search-suggest' )
123            ->rawParams( $suggest )->parse();
124    }
125}