Merge "Http::getProxy() method to get proxy configuration"
[lhc/web/wiklou.git] / includes / search / SearchResult.php
1 <?php
2 /**
3 * Search engine result
4 *
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.
9 *
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.
14 *
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
19 *
20 * @file
21 * @ingroup Search
22 */
23
24 /**
25 * @todo FIXME: This class is horribly factored. It would probably be better to
26 * have a useful base class to which you pass some standard information, then
27 * let the fancy self-highlighters extend that.
28 * @ingroup Search
29 */
30 class SearchResult {
31
32 /**
33 * @var Revision
34 */
35 protected $mRevision = null;
36
37 /**
38 * @var File
39 */
40 protected $mImage = null;
41
42 /**
43 * @var Title
44 */
45 protected $mTitle;
46
47 /**
48 * @var string
49 */
50 protected $mText;
51
52 /**
53 * Return a new SearchResult and initializes it with a title.
54 *
55 * @param Title $title
56 * @return SearchResult
57 */
58 public static function newFromTitle( $title ) {
59 $result = new self();
60 $result->initFromTitle( $title );
61 return $result;
62 }
63
64 /**
65 * Initialize from a Title and if possible initializes a corresponding
66 * Revision and File.
67 *
68 * @param Title $title
69 */
70 protected function initFromTitle( $title ) {
71 $this->mTitle = $title;
72 if ( !is_null( $this->mTitle ) ) {
73 $id = false;
74 Hooks::run( 'SearchResultInitFromTitle', [ $title, &$id ] );
75 $this->mRevision = Revision::newFromTitle(
76 $this->mTitle, $id, Revision::READ_NORMAL );
77 if ( $this->mTitle->getNamespace() === NS_FILE ) {
78 $this->mImage = wfFindFile( $this->mTitle );
79 }
80 }
81 }
82
83 /**
84 * Check if this is result points to an invalid title
85 *
86 * @return bool
87 */
88 function isBrokenTitle() {
89 return is_null( $this->mTitle );
90 }
91
92 /**
93 * Check if target page is missing, happens when index is out of date
94 *
95 * @return bool
96 */
97 function isMissingRevision() {
98 return !$this->mRevision && !$this->mImage;
99 }
100
101 /**
102 * @return Title
103 */
104 function getTitle() {
105 return $this->mTitle;
106 }
107
108 /**
109 * Get the file for this page, if one exists
110 * @return File|null
111 */
112 function getFile() {
113 return $this->mImage;
114 }
115
116 /**
117 * Lazy initialization of article text from DB
118 */
119 protected function initText() {
120 if ( !isset( $this->mText ) ) {
121 if ( $this->mRevision != null ) {
122 $this->mText = SearchEngine::create()
123 ->getTextFromContent( $this->mTitle, $this->mRevision->getContent() );
124 } else { // TODO: can we fetch raw wikitext for commons images?
125 $this->mText = '';
126 }
127 }
128 }
129
130 /**
131 * @param array $terms Terms to highlight
132 * @return string Highlighted text snippet, null (and not '') if not supported
133 */
134 function getTextSnippet( $terms ) {
135 global $wgAdvancedSearchHighlighting;
136 $this->initText();
137
138 // TODO: make highliter take a content object. Make ContentHandler a factory for SearchHighliter.
139 list( $contextlines, $contextchars ) = SearchEngine::userHighlightPrefs();
140
141 $h = new SearchHighlighter();
142 if ( count( $terms ) > 0 ) {
143 if ( $wgAdvancedSearchHighlighting ) {
144 return $h->highlightText( $this->mText, $terms, $contextlines, $contextchars );
145 } else {
146 return $h->highlightSimple( $this->mText, $terms, $contextlines, $contextchars );
147 }
148 } else {
149 return $h->highlightNone( $this->mText, $contextlines, $contextchars );
150 }
151 }
152
153 /**
154 * @return string Highlighted title, '' if not supported
155 */
156 function getTitleSnippet() {
157 return '';
158 }
159
160 /**
161 * @return string Highlighted redirect name (redirect to this page), '' if none or not supported
162 */
163 function getRedirectSnippet() {
164 return '';
165 }
166
167 /**
168 * @return Title|null Title object for the redirect to this page, null if none or not supported
169 */
170 function getRedirectTitle() {
171 return null;
172 }
173
174 /**
175 * @return string Highlighted relevant section name, null if none or not supported
176 */
177 function getSectionSnippet() {
178 return '';
179 }
180
181 /**
182 * @return Title|null Title object (pagename+fragment) for the section,
183 * null if none or not supported
184 */
185 function getSectionTitle() {
186 return null;
187 }
188
189 /**
190 * @return string Highlighted relevant category name or '' if none or not supported
191 */
192 public function getCategorySnippet() {
193 return '';
194 }
195
196 /**
197 * @return string Timestamp
198 */
199 function getTimestamp() {
200 if ( $this->mRevision ) {
201 return $this->mRevision->getTimestamp();
202 } elseif ( $this->mImage ) {
203 return $this->mImage->getTimestamp();
204 }
205 return '';
206 }
207
208 /**
209 * @return int Number of words
210 */
211 function getWordCount() {
212 $this->initText();
213 return str_word_count( $this->mText );
214 }
215
216 /**
217 * @return int Size in bytes
218 */
219 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 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 function getInterwikiNamespaceText() {
235 return '';
236 }
237
238 /**
239 * Did this match file contents (eg: PDF/DJVU)?
240 * @return bool
241 */
242 function isFileMatch() {
243 return false;
244 }
245 }