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