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