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