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