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