Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 24
CRAP
0.00% covered (danger)
0.00%
0 / 1
RevisionSearchResultTrait
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 24
1056
0.00% covered (danger)
0.00%
0 / 1
 initFromTitle
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 isBrokenTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isMissingRevision
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 getTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getFile
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 initText
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 getTextSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTextSnippetField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTitleSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTitleSnippetField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRedirectSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRedirectSnippetField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRedirectTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSectionSnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSectionSnippetField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSectionTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCategorySnippet
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCategorySnippetField
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTimestamp
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getWordCount
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getByteSize
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getInterwikiPrefix
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInterwikiNamespaceText
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isFileMatch
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3use MediaWiki\HookContainer\HookRunner;
4use MediaWiki\MediaWikiServices;
5use MediaWiki\Revision\RevisionRecord;
6use MediaWiki\Revision\SlotRecord;
7use MediaWiki\Title\Title;
8use Wikimedia\Rdbms\IDBAccessObject;
9
10/**
11 * Transitional trait used to share the methods between SearchResult and RevisionSearchResult.
12 * All the content of this trait can be moved to RevisionSearchResult once SearchResult is finally
13 * refactored into an abstract class.
14 * NOTE: This trait MUST NOT be used by something else than SearchResult and RevisionSearchResult.
15 * It will be removed without deprecation period once SearchResult
16 */
17trait RevisionSearchResultTrait {
18    /**
19     * @var RevisionRecord|null
20     */
21    protected $mRevisionRecord = null;
22
23    /**
24     * @var File|null
25     */
26    protected $mImage = null;
27
28    /**
29     * @var Title|null
30     */
31    protected $mTitle;
32
33    /**
34     * @var string
35     */
36    protected $mText;
37
38    /**
39     * Initialize from a Title and if possible initializes a corresponding
40     * RevisionRecord and File.
41     *
42     * @param Title|null $title
43     */
44    protected function initFromTitle( $title ) {
45        $this->mTitle = $title;
46        if ( $title !== null ) {
47            $services = MediaWikiServices::getInstance();
48            $id = false;
49            ( new HookRunner( $services->getHookContainer() ) )->onSearchResultInitFromTitle( $title, $id );
50
51            $this->mRevisionRecord = $services->getRevisionLookup()->getRevisionByTitle(
52                $title,
53                $id,
54                IDBAccessObject::READ_NORMAL
55            );
56            if ( $title->getNamespace() === NS_FILE ) {
57                $this->mImage = $services->getRepoGroup()->findFile( $title );
58            }
59        }
60    }
61
62    /**
63     * Check if this is result points to an invalid title
64     *
65     * @return bool
66     */
67    public function isBrokenTitle() {
68        return $this->mTitle === null;
69    }
70
71    /**
72     * Check if target page is missing, happens when index is out of date
73     *
74     * @return bool
75     */
76    public function isMissingRevision() {
77        return !$this->mRevisionRecord && !$this->mImage;
78    }
79
80    /**
81     * @return Title|null
82     */
83    public function getTitle() {
84        return $this->mTitle;
85    }
86
87    /**
88     * Get the file for this page, if one exists
89     * @return File|null
90     */
91    public function getFile() {
92        return $this->mImage;
93    }
94
95    /**
96     * Lazy initialization of article text from DB
97     */
98    protected function initText() {
99        if ( !isset( $this->mText ) ) {
100            if ( $this->mRevisionRecord != null ) {
101                $content = $this->mRevisionRecord->getContent( SlotRecord::MAIN );
102                $this->mText = $content !== null ? $content->getTextForSearchIndex() : '';
103            } else { // TODO: can we fetch raw wikitext for commons images?
104                $this->mText = '';
105            }
106        }
107    }
108
109    /**
110     * @param string[] $terms Terms to highlight (this parameter is deprecated and ignored)
111     * @return string Highlighted text snippet, null (and not '') if not supported
112     */
113    public function getTextSnippet( $terms = [] ) {
114        return '';
115    }
116
117    /**
118     * @return string Name of the field containing the text snippet, '' if not supported
119     */
120    public function getTextSnippetField() {
121        return '';
122    }
123
124    /**
125     * @return string Highlighted title, '' if not supported
126     */
127    public function getTitleSnippet() {
128        return '';
129    }
130
131    /**
132     * @return string Name of the field containing the title snippet, '' if not supported
133     */
134    public function getTitleSnippetField() {
135        return '';
136    }
137
138    /**
139     * @return string Highlighted redirect name (redirect to this page), '' if none or not supported
140     */
141    public function getRedirectSnippet() {
142        return '';
143    }
144
145    /**
146     * @return string Name of the field containing the redirect snippet, '' if not supported
147     */
148    public function getRedirectSnippetField() {
149        return '';
150    }
151
152    /**
153     * @return Title|null Title object for the redirect to this page, null if none or not supported
154     */
155    public function getRedirectTitle() {
156        return null;
157    }
158
159    /**
160     * @return string Highlighted relevant section name, null if none or not supported
161     */
162    public function getSectionSnippet() {
163        return '';
164    }
165
166    /**
167     * @return string Name of the field containing the section snippet, '' if not supported
168     */
169    public function getSectionSnippetField() {
170        return '';
171    }
172
173    /**
174     * @return Title|null Title object (pagename+fragment) for the section,
175     *  null if none or not supported
176     */
177    public function getSectionTitle() {
178        return null;
179    }
180
181    /**
182     * @return string Highlighted relevant category name or '' if none or not supported
183     */
184    public function getCategorySnippet() {
185        return '';
186    }
187
188    /**
189     * @return string Name of the field containing the category snippet, '' if not supported
190     */
191    public function getCategorySnippetField() {
192        return '';
193    }
194
195    /**
196     * @return string Timestamp
197     */
198    public function getTimestamp() {
199        if ( $this->mRevisionRecord ) {
200            return $this->mRevisionRecord->getTimestamp();
201        } elseif ( $this->mImage ) {
202            return $this->mImage->getTimestamp();
203        }
204        return '';
205    }
206
207    /**
208     * @return int Number of words
209     */
210    public function getWordCount() {
211        $this->initText();
212        return str_word_count( $this->mText );
213    }
214
215    /**
216     * @return int Size in bytes
217     */
218    public function getByteSize() {
219        $this->initText();
220        return strlen( $this->mText );
221    }
222
223    /**
224     * @return string Interwiki prefix of the title (return iw even if title is broken)
225     */
226    public function getInterwikiPrefix() {
227        return '';
228    }
229
230    /**
231     * @return string Interwiki namespace of the title (since we likely can't resolve it locally)
232     */
233    public function getInterwikiNamespaceText() {
234        return '';
235    }
236
237    /**
238     * Did this match file contents (eg: PDF/DJVU)?
239     * @return bool
240     */
241    public function isFileMatch() {
242        return false;
243    }
244}