Merge "Special:Upload should not crash on failing previews"
[mediawiki.git] / includes / search / SearchResult.php
blob50db84b034ff75169abd92a4956c87ca265a110c
1 <?php
2 /**
3 * Search engine result
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
20 * @file
21 * @ingroup Search
24 use MediaWiki\MediaWikiServices;
26 /**
27 * @todo FIXME: This class is horribly factored. It would probably be better to
28 * have a useful base class to which you pass some standard information, then
29 * let the fancy self-highlighters extend that.
30 * @ingroup Search
32 class SearchResult {
34 /**
35 * @var Revision
37 protected $mRevision = null;
39 /**
40 * @var File
42 protected $mImage = null;
44 /**
45 * @var Title
47 protected $mTitle;
49 /**
50 * @var string
52 protected $mText;
54 /**
55 * @var SearchEngine
57 protected $searchEngine;
59 /**
60 * A set of extension data.
61 * @var array[]
63 protected $extensionData;
65 /**
66 * Return a new SearchResult and initializes it with a title.
68 * @param Title $title
69 * @param SearchResultSet $parentSet
70 * @return SearchResult
72 public static function newFromTitle( $title, SearchResultSet $parentSet = null ) {
73 $result = new static();
74 $result->initFromTitle( $title );
75 if ( $parentSet ) {
76 $parentSet->augmentResult( $result );
78 return $result;
81 /**
82 * Initialize from a Title and if possible initializes a corresponding
83 * Revision and File.
85 * @param Title $title
87 protected function initFromTitle( $title ) {
88 $this->mTitle = $title;
89 if ( !is_null( $this->mTitle ) ) {
90 $id = false;
91 Hooks::run( 'SearchResultInitFromTitle', [ $title, &$id ] );
92 $this->mRevision = Revision::newFromTitle(
93 $this->mTitle, $id, Revision::READ_NORMAL );
94 if ( $this->mTitle->getNamespace() === NS_FILE ) {
95 $this->mImage = wfFindFile( $this->mTitle );
98 $this->searchEngine = MediaWikiServices::getInstance()->newSearchEngine();
102 * Check if this is result points to an invalid title
104 * @return bool
106 function isBrokenTitle() {
107 return is_null( $this->mTitle );
111 * Check if target page is missing, happens when index is out of date
113 * @return bool
115 function isMissingRevision() {
116 return !$this->mRevision && !$this->mImage;
120 * @return Title
122 function getTitle() {
123 return $this->mTitle;
127 * Get the file for this page, if one exists
128 * @return File|null
130 function getFile() {
131 return $this->mImage;
135 * Lazy initialization of article text from DB
137 protected function initText() {
138 if ( !isset( $this->mText ) ) {
139 if ( $this->mRevision != null ) {
140 $this->mText = $this->searchEngine->getTextFromContent(
141 $this->mTitle, $this->mRevision->getContent() );
142 } else { // TODO: can we fetch raw wikitext for commons images?
143 $this->mText = '';
149 * @param array $terms Terms to highlight
150 * @return string Highlighted text snippet, null (and not '') if not supported
152 function getTextSnippet( $terms ) {
153 global $wgAdvancedSearchHighlighting;
154 $this->initText();
156 // TODO: make highliter take a content object. Make ContentHandler a factory for SearchHighliter.
157 list( $contextlines, $contextchars ) = $this->searchEngine->userHighlightPrefs();
159 $h = new SearchHighlighter();
160 if ( count( $terms ) > 0 ) {
161 if ( $wgAdvancedSearchHighlighting ) {
162 return $h->highlightText( $this->mText, $terms, $contextlines, $contextchars );
163 } else {
164 return $h->highlightSimple( $this->mText, $terms, $contextlines, $contextchars );
166 } else {
167 return $h->highlightNone( $this->mText, $contextlines, $contextchars );
172 * @return string Highlighted title, '' if not supported
174 function getTitleSnippet() {
175 return '';
179 * @return string Highlighted redirect name (redirect to this page), '' if none or not supported
181 function getRedirectSnippet() {
182 return '';
186 * @return Title|null Title object for the redirect to this page, null if none or not supported
188 function getRedirectTitle() {
189 return null;
193 * @return string Highlighted relevant section name, null if none or not supported
195 function getSectionSnippet() {
196 return '';
200 * @return Title|null Title object (pagename+fragment) for the section,
201 * null if none or not supported
203 function getSectionTitle() {
204 return null;
208 * @return string Highlighted relevant category name or '' if none or not supported
210 public function getCategorySnippet() {
211 return '';
215 * @return string Timestamp
217 function getTimestamp() {
218 if ( $this->mRevision ) {
219 return $this->mRevision->getTimestamp();
220 } elseif ( $this->mImage ) {
221 return $this->mImage->getTimestamp();
223 return '';
227 * @return int Number of words
229 function getWordCount() {
230 $this->initText();
231 return str_word_count( $this->mText );
235 * @return int Size in bytes
237 function getByteSize() {
238 $this->initText();
239 return strlen( $this->mText );
243 * @return string Interwiki prefix of the title (return iw even if title is broken)
245 function getInterwikiPrefix() {
246 return '';
250 * @return string Interwiki namespace of the title (since we likely can't resolve it locally)
252 function getInterwikiNamespaceText() {
253 return '';
257 * Did this match file contents (eg: PDF/DJVU)?
258 * @return bool
260 function isFileMatch() {
261 return false;
265 * Get the extension data as:
266 * augmentor name => data
267 * @return array[]
269 public function getExtensionData() {
270 return $this->extensionData;
274 * Set extension data for this result.
275 * The data is:
276 * augmentor name => data
277 * @param array[] $extensionData
279 public function setExtensionData( array $extensionData ) {
280 $this->extensionData = $extensionData;