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