Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 25
CRAP
0.00% covered (danger)
0.00%
0 / 1
InterleavedResultSet
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 25
702
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getMetrics
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getOffset
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 extractResults
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getElasticResponse
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getElasticaResultSet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addInterwikiResults
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRewrittenQuery
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 count
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 numRows
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTotalHits
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasRewrittenQuery
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryAfterRewrite
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getQueryAfterRewriteSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasSuggestion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSuggestionQuery
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSuggestionSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInterwikiResults
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasInterwikiResults
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 searchContainedSyntax
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 hasMoreResults
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isApproximateTotalHits
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 shrink
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 extractTitles
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setSuggestionQuery
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace CirrusSearch\Search;
4
5use BaseSearchResultSet;
6use Elastica\Response;
7use HtmlArmor;
8use ISearchResultSet;
9use MediaWiki\Title\Title;
10use SearchResultSetTrait;
11
12class InterleavedResultSet extends BaseSearchResultSet implements CirrusSearchResultSet, SearchMetricsProvider {
13    use SearchResultSetTrait;
14
15    /** @var string[] Doc ID's belonging to team A */
16    private $teamA;
17    /** @var string[] Doc ID's belonging to team B */
18    private $teamB;
19    /** @var int Offset to calculate next unused result in team A */
20    private $offset;
21    /** @var CirrusSearchResultSet */
22    private $delegate;
23    /** @var CirrusSearchResult[] */
24    private $results;
25
26    /**
27     * @param CirrusSearchResultSet $nested Original result set for team A (control)
28     * @param CirrusSearchResult[] $interleaved Interleaved results
29     * @param string[] $teamA Document id's belonging to team A
30     * @param string[] $teamB Document id's belonging to team B
31     * @param int $offset Offset to calculate next unused result in team A
32     */
33    public function __construct(
34        CirrusSearchResultSet $nested,
35        array $interleaved,
36        array $teamA,
37        array $teamB,
38        $offset
39    ) {
40        $this->results = $interleaved;
41        $this->teamA = $teamA;
42        $this->teamB = $teamB;
43        $this->offset = $offset;
44        $this->delegate = $nested;
45    }
46
47    /** @inheritDoc */
48    public function getMetrics() {
49        return [
50            'wgCirrusSearchTeamDraft' => [
51                'a' => $this->teamA,
52                'b' => $this->teamB,
53            ],
54        ];
55    }
56
57    /**
58     * @return int|null
59     */
60    public function getOffset() {
61        return $this->offset;
62    }
63
64    /**
65     * @return CirrusSearchResult[]
66     */
67    public function extractResults() {
68        return $this->results;
69    }
70
71    /**
72     * @return Response|null
73     */
74    public function getElasticResponse() {
75        return $this->delegate->getElasticResponse();
76    }
77
78    /**
79     * @return \Elastica\ResultSet|null
80     */
81    public function getElasticaResultSet() {
82        return $this->delegate->getElasticaResultSet();
83    }
84
85    /**
86     * @param CirrusSearchResultSet $res
87     * @param int $type one of searchresultset::* constants
88     * @param string $interwiki
89     */
90    public function addInterwikiResults( CirrusSearchResultSet $res, $type, $interwiki ) {
91        $this->delegate->addInterwikiResults( $res, $type, $interwiki );
92    }
93
94    /**
95     * @param string $newQuery
96     * @param HtmlArmor|string|null $newQuerySnippet
97     */
98    public function setRewrittenQuery( string $newQuery, $newQuerySnippet = null ) {
99        $this->delegate->setRewrittenQuery( $newQuery, $newQuerySnippet );
100    }
101
102    /**
103     * Count elements of an object
104     * @link https://php.net/manual/en/countable.count.php
105     * @return int The custom count as integer.
106     * @since 5.1.0
107     */
108    public function count(): int {
109        return count( $this->results );
110    }
111
112    /**
113     * @return int
114     */
115    public function numRows() {
116        return $this->count();
117    }
118
119    /**
120     * Some search modes return a total hit count for the query
121     * in the entire article database. This may include pages
122     * in namespaces that would not be matched on the given
123     * settings.
124     *
125     * Return null if no total hits number is supported.
126     *
127     * @return int|null
128     */
129    public function getTotalHits() {
130        return $this->delegate->getTotalHits();
131    }
132
133    /**
134     * Some search modes will run an alternative query that it thinks gives
135     * a better result than the provided search. Returns true if this has
136     * occurred.
137     *
138     * @return bool
139     */
140    public function hasRewrittenQuery() {
141        return $this->delegate->hasRewrittenQuery();
142    }
143
144    /**
145     * @return string|null The search the query was internally rewritten to,
146     *  or null when the result of the original query was returned.
147     */
148    public function getQueryAfterRewrite() {
149        return $this->delegate->getQueryAfterRewrite();
150    }
151
152    /**
153     * @return string|null Same as self::getQueryAfterRewrite(), but in HTML
154     *  and with changes highlighted. Null when the query was not rewritten.
155     */
156    public function getQueryAfterRewriteSnippet() {
157        return $this->delegate->getQueryAfterRewriteSnippet();
158    }
159
160    /**
161     * Some search modes return a suggested alternate term if there are
162     * no exact hits. Returns true if there is one on this set.
163     *
164     * @return bool
165     */
166    public function hasSuggestion() {
167        return $this->delegate->hasSuggestion();
168    }
169
170    /**
171     * @return string|null Suggested query, null if none
172     */
173    public function getSuggestionQuery() {
174        return $this->delegate->getSuggestionQuery();
175    }
176
177    /**
178     * @return string HTML highlighted suggested query, '' if none
179     */
180    public function getSuggestionSnippet() {
181        return $this->delegate->getSuggestionSnippet();
182    }
183
184    /**
185     * Return a result set of hits on other (multiple) wikis associated with this one
186     *
187     * @param int $type
188     * @return ISearchResultSet[]
189     */
190    public function getInterwikiResults( $type = self::SECONDARY_RESULTS ) {
191        return $this->delegate->getInterwikiResults( $type );
192    }
193
194    /**
195     * Check if there are results on other wikis
196     *
197     * @param int $type
198     * @return bool
199     */
200    public function hasInterwikiResults( $type = self::SECONDARY_RESULTS ) {
201        return $this->delegate->hasInterwikiResults( $type );
202    }
203
204    /**
205     * Did the search contain search syntax?  If so, Special:Search won't offer
206     * the user a link to a create a page named by the search string because the
207     * name would contain the search syntax.
208     * @return bool
209     */
210    public function searchContainedSyntax() {
211        return $this->delegate->searchContainedSyntax();
212    }
213
214    /**
215     * @return bool True when there are more pages of search results available.
216     */
217    public function hasMoreResults() {
218        return $this->delegate->hasMoreResults();
219    }
220
221    /**
222     * @inheritDoc
223     */
224    public function isApproximateTotalHits(): bool {
225        return $this->delegate->isApproximateTotalHits();
226    }
227
228    /**
229     * @param int $limit Shrink result set to $limit and flag
230     *  if more results are available.
231     */
232    public function shrink( $limit ) {
233        if ( $this->count() > $limit ) {
234            $this->results = array_slice( $this->results, 0, $limit );
235        }
236        $this->delegate->shrink( $limit );
237    }
238
239    /**
240     * Extract all the titles in the result set.
241     * @return Title[]
242     */
243    public function extractTitles() {
244        return $this->delegate->extractTitles();
245    }
246
247    /**
248     * @param string $suggestionQuery
249     * @param HtmlArmor|string|null $suggestionSnippet
250     */
251    public function setSuggestionQuery( string $suggestionQuery, $suggestionSnippet = null ) {
252        $this->delegate->setSuggestionQuery( $suggestionQuery, $suggestionSnippet );
253    }
254}