Completed
Branch master (02e057)
by
unknown
27:42
created

SearchEngine::getProfiles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * Basic search engine
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
 * @defgroup Search Search
26
 */
27
28
use MediaWiki\MediaWikiServices;
29
30
/**
31
 * Contain a class for special pages
32
 * @ingroup Search
33
 */
34
abstract class SearchEngine {
35
	/** @var string */
36
	public $prefix = '';
37
38
	/** @var int[]|null */
39
	public $namespaces = [ NS_MAIN ];
40
41
	/** @var int */
42
	protected $limit = 10;
43
44
	/** @var int */
45
	protected $offset = 0;
46
47
	/** @var array|string */
48
	protected $searchTerms = [];
49
50
	/** @var bool */
51
	protected $showSuggestion = true;
52
	private $sort = 'relevance';
53
54
	/** @var array Feature values */
55
	protected $features = [];
56
57
	/** @const string profile type for completionSearch */
58
	const COMPLETION_PROFILE_TYPE = 'completionSearchProfile';
59
60
	/** @const string profile type for query independent ranking features */
61
	const FT_QUERY_INDEP_PROFILE_TYPE = 'fulltextQueryIndepProfile';
62
63
	/**
64
	 * Perform a full text search query and return a result set.
65
	 * If full text searches are not supported or disabled, return null.
66
	 * STUB
67
	 *
68
	 * @param string $term Raw search term
69
	 * @return SearchResultSet|Status|null
70
	 */
71
	function searchText( $term ) {
72
		return null;
73
	}
74
75
	/**
76
	 * Perform a title-only search query and return a result set.
77
	 * If title searches are not supported or disabled, return null.
78
	 * STUB
79
	 *
80
	 * @param string $term Raw search term
81
	 * @return SearchResultSet|null
82
	 */
83
	function searchTitle( $term ) {
84
		return null;
85
	}
86
87
	/**
88
	 * @since 1.18
89
	 * @param string $feature
90
	 * @return bool
91
	 */
92
	public function supports( $feature ) {
93
		switch ( $feature ) {
94
		case 'search-update':
95
			return true;
96
		case 'title-suffix-filter':
97
		default:
98
			return false;
99
		}
100
	}
101
102
	/**
103
	 * Way to pass custom data for engines
104
	 * @since 1.18
105
	 * @param string $feature
106
	 * @param mixed $data
107
	 * @return bool
108
	 */
109
	public function setFeatureData( $feature, $data ) {
110
		$this->features[$feature] = $data;
111
	}
112
113
	/**
114
	 * When overridden in derived class, performs database-specific conversions
115
	 * on text to be used for searching or updating search index.
116
	 * Default implementation does nothing (simply returns $string).
117
	 *
118
	 * @param string $string String to process
119
	 * @return string
120
	 */
121
	public function normalizeText( $string ) {
122
		global $wgContLang;
123
124
		// Some languages such as Chinese require word segmentation
125
		return $wgContLang->segmentByWord( $string );
126
	}
127
128
	/**
129
	 * Transform search term in cases when parts of the query came as different
130
	 * GET params (when supported), e.g. for prefix queries:
131
	 * search=test&prefix=Main_Page/Archive -> test prefix:Main Page/Archive
132
	 * @param string $term
133
	 * @return string
134
	 */
135
	public function transformSearchTerm( $term ) {
136
		return $term;
137
	}
138
139
	/**
140
	 * Get service class to finding near matches.
141
	 * @param Config $config Configuration to use for the matcher.
142
	 * @return SearchNearMatcher
143
	 */
144
	public function getNearMatcher( Config $config ) {
145
		global $wgContLang;
146
		return new SearchNearMatcher( $config, $wgContLang );
147
	}
148
149
	/**
150
	 * Get near matcher for default SearchEngine.
151
	 * @return SearchNearMatcher
152
	 */
153
	protected static function defaultNearMatcher() {
154
		$config = MediaWikiServices::getInstance()->getMainConfig();
155
		return MediaWikiServices::getInstance()->newSearchEngine()->getNearMatcher( $config );
156
	}
157
158
	/**
159
	 * If an exact title match can be found, or a very slightly close match,
160
	 * return the title. If no match, returns NULL.
161
	 * @deprecated since 1.27; Use SearchEngine::getNearMatcher()
162
	 * @param string $searchterm
163
	 * @return Title
164
	 */
165
	public static function getNearMatch( $searchterm ) {
166
		return static::defaultNearMatcher()->getNearMatch( $searchterm );
167
	}
168
169
	/**
170
	 * Do a near match (see SearchEngine::getNearMatch) and wrap it into a
171
	 * SearchResultSet.
172
	 * @deprecated since 1.27; Use SearchEngine::getNearMatcher()
173
	 * @param string $searchterm
174
	 * @return SearchResultSet
175
	 */
176
	public static function getNearMatchResultSet( $searchterm ) {
177
		return static::defaultNearMatcher()->getNearMatchResultSet( $searchterm );
178
	}
179
180
	/**
181
	 * Get chars legal for search.
182
	 * NOTE: usage as static is deprecated and preserved only as BC measure
183
	 * @return string
184
	 */
185
	public static function legalSearchChars() {
186
		return "A-Za-z_'.0-9\\x80-\\xFF\\-";
187
	}
188
189
	/**
190
	 * Set the maximum number of results to return
191
	 * and how many to skip before returning the first.
192
	 *
193
	 * @param int $limit
194
	 * @param int $offset
195
	 */
196
	function setLimitOffset( $limit, $offset = 0 ) {
197
		$this->limit = intval( $limit );
198
		$this->offset = intval( $offset );
199
	}
200
201
	/**
202
	 * Set which namespaces the search should include.
203
	 * Give an array of namespace index numbers.
204
	 *
205
	 * @param int[]|null $namespaces
206
	 */
207
	function setNamespaces( $namespaces ) {
208
		if ( $namespaces ) {
209
			// Filter namespaces to only keep valid ones
210
			$validNs = $this->searchableNamespaces();
0 ignored issues
show
Deprecated Code introduced by
The method SearchEngine::searchableNamespaces() has been deprecated with message: since 1.27; use SearchEngineConfig::searchableNamespaces()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
211
			$namespaces = array_filter( $namespaces, function( $ns ) use( $validNs ) {
212
				return $ns < 0 || isset( $validNs[$ns] );
213
			} );
214
		} else {
215
			$namespaces = [];
216
		}
217
		$this->namespaces = $namespaces;
218
	}
219
220
	/**
221
	 * Set whether the searcher should try to build a suggestion.  Note: some searchers
222
	 * don't support building a suggestion in the first place and others don't respect
223
	 * this flag.
224
	 *
225
	 * @param bool $showSuggestion Should the searcher try to build suggestions
226
	 */
227
	function setShowSuggestion( $showSuggestion ) {
228
		$this->showSuggestion = $showSuggestion;
229
	}
230
231
	/**
232
	 * Get the valid sort directions.  All search engines support 'relevance' but others
233
	 * might support more. The default in all implementations should be 'relevance.'
234
	 *
235
	 * @since 1.25
236
	 * @return array(string) the valid sort directions for setSort
0 ignored issues
show
Documentation introduced by
The doc-type array(string) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
237
	 */
238
	public function getValidSorts() {
239
		return [ 'relevance' ];
240
	}
241
242
	/**
243
	 * Set the sort direction of the search results. Must be one returned by
244
	 * SearchEngine::getValidSorts()
245
	 *
246
	 * @since 1.25
247
	 * @throws InvalidArgumentException
248
	 * @param string $sort sort direction for query result
249
	 */
250
	public function setSort( $sort ) {
251
		if ( !in_array( $sort, $this->getValidSorts() ) ) {
252
			throw new InvalidArgumentException( "Invalid sort: $sort. " .
253
				"Must be one of: " . implode( ', ', $this->getValidSorts() ) );
254
		}
255
		$this->sort = $sort;
256
	}
257
258
	/**
259
	 * Get the sort direction of the search results
260
	 *
261
	 * @since 1.25
262
	 * @return string
263
	 */
264
	public function getSort() {
265
		return $this->sort;
266
	}
267
268
	/**
269
	 * Parse some common prefixes: all (search everything)
270
	 * or namespace names
271
	 *
272
	 * @param string $query
273
	 * @return string
274
	 */
275
	function replacePrefixes( $query ) {
276
		global $wgContLang;
277
278
		$parsed = $query;
279
		if ( strpos( $query, ':' ) === false ) { // nothing to do
280
			return $parsed;
281
		}
282
283
		$allkeyword = wfMessage( 'searchall' )->inContentLanguage()->text() . ":";
284
		if ( strncmp( $query, $allkeyword, strlen( $allkeyword ) ) == 0 ) {
285
			$this->namespaces = null;
286
			$parsed = substr( $query, strlen( $allkeyword ) );
287
		} elseif ( strpos( $query, ':' ) !== false ) {
288
			$prefix = str_replace( ' ', '_', substr( $query, 0, strpos( $query, ':' ) ) );
289
			$index = $wgContLang->getNsIndex( $prefix );
290
			if ( $index !== false ) {
291
				$this->namespaces = [ $index ];
292
				$parsed = substr( $query, strlen( $prefix ) + 1 );
293
			}
294
		}
295
		if ( trim( $parsed ) == '' ) {
296
			$parsed = $query; // prefix was the whole query
297
		}
298
299
		return $parsed;
300
	}
301
302
	/**
303
	 * Find snippet highlight settings for all users
304
	 * @return array Contextlines, contextchars
305
	 */
306
	public static function userHighlightPrefs() {
307
		$contextlines = 2; // Hardcode this. Old defaults sucked. :)
308
		$contextchars = 75; // same as above.... :P
309
		return [ $contextlines, $contextchars ];
310
	}
311
312
	/**
313
	 * Create or update the search index record for the given page.
314
	 * Title and text should be pre-processed.
315
	 * STUB
316
	 *
317
	 * @param int $id
318
	 * @param string $title
319
	 * @param string $text
320
	 */
321
	function update( $id, $title, $text ) {
322
		// no-op
323
	}
324
325
	/**
326
	 * Update a search index record's title only.
327
	 * Title should be pre-processed.
328
	 * STUB
329
	 *
330
	 * @param int $id
331
	 * @param string $title
332
	 */
333
	function updateTitle( $id, $title ) {
334
		// no-op
335
	}
336
337
	/**
338
	 * Delete an indexed page
339
	 * Title should be pre-processed.
340
	 * STUB
341
	 *
342
	 * @param int $id Page id that was deleted
343
	 * @param string $title Title of page that was deleted
344
	 */
345
	function delete( $id, $title ) {
346
		// no-op
347
	}
348
349
	/**
350
	 * Get OpenSearch suggestion template
351
	 *
352
	 * @deprecated since 1.25
353
	 * @return string
354
	 */
355
	public static function getOpenSearchTemplate() {
356
		wfDeprecated( __METHOD__, '1.25' );
357
		return ApiOpenSearch::getOpenSearchTemplate( 'application/x-suggestions+json' );
358
	}
359
360
	/**
361
	 * Get the raw text for updating the index from a content object
362
	 * Nicer search backends could possibly do something cooler than
363
	 * just returning raw text
364
	 *
365
	 * @todo This isn't ideal, we'd really like to have content-specific handling here
366
	 * @param Title $t Title we're indexing
367
	 * @param Content $c Content of the page to index
368
	 * @return string
369
	 */
370
	public function getTextFromContent( Title $t, Content $c = null ) {
371
		return $c ? $c->getTextForSearchIndex() : '';
372
	}
373
374
	/**
375
	 * If an implementation of SearchEngine handles all of its own text processing
376
	 * in getTextFromContent() and doesn't require SearchUpdate::updateText()'s
377
	 * rather silly handling, it should return true here instead.
378
	 *
379
	 * @return bool
380
	 */
381
	public function textAlreadyUpdatedForIndex() {
382
		return false;
383
	}
384
385
	/**
386
	 * Makes search simple string if it was namespaced.
387
	 * Sets namespaces of the search to namespaces extracted from string.
388
	 * @param string $search
389
	 * @return string Simplified search string
390
	 */
391
	protected function normalizeNamespaces( $search ) {
392
		// Find a Title which is not an interwiki and is in NS_MAIN
393
		$title = Title::newFromText( $search );
394
		$ns = $this->namespaces;
395
		if ( $title && !$title->isExternal() ) {
396
			$ns = [ $title->getNamespace() ];
397
			$search = $title->getText();
398 View Code Duplication
			if ( $ns[0] == NS_MAIN ) {
399
				$ns = $this->namespaces; // no explicit prefix, use default namespaces
400
				Hooks::run( 'PrefixSearchExtractNamespace', [ &$ns, &$search ] );
401
			}
402
		} else {
403
			$title = Title::newFromText( $search . 'Dummy' );
404 View Code Duplication
			if ( $title && $title->getText() == 'Dummy'
405
					&& $title->getNamespace() != NS_MAIN
406
					&& !$title->isExternal() )
407
			{
408
				$ns = [ $title->getNamespace() ];
409
				$search = '';
410
			} else {
411
				Hooks::run( 'PrefixSearchExtractNamespace', [ &$ns, &$search ] );
412
			}
413
		}
414
415
		$ns = array_map( function( $space ) {
416
			return $space == NS_MEDIA ? NS_FILE : $space;
417
		}, $ns );
418
419
		$this->setNamespaces( $ns );
420
		return $search;
421
	}
422
423
	/**
424
	 * Perform a completion search.
425
	 * Does not resolve namespaces and does not check variants.
426
	 * Search engine implementations may want to override this function.
427
	 * @param string $search
428
	 * @return SearchSuggestionSet
429
	 */
430
	protected function completionSearchBackend( $search ) {
431
		$results = [];
432
433
		$search = trim( $search );
434
435
		if ( !in_array( NS_SPECIAL, $this->namespaces ) && // We do not run hook on Special: search
436
			 !Hooks::run( 'PrefixSearchBackend',
437
				[ $this->namespaces, $search, $this->limit, &$results, $this->offset ]
438
		) ) {
439
			// False means hook worked.
440
			// FIXME: Yes, the API is weird. That's why it is going to be deprecated.
441
442
			return SearchSuggestionSet::fromStrings( $results );
443
		} else {
444
			// Hook did not do the job, use default simple search
445
			$results = $this->simplePrefixSearch( $search );
446
			return SearchSuggestionSet::fromTitles( $results );
447
		}
448
	}
449
450
	/**
451
	 * Perform a completion search.
452
	 * @param string $search
453
	 * @return SearchSuggestionSet
454
	 */
455
	public function completionSearch( $search ) {
456
		if ( trim( $search ) === '' ) {
457
			return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
458
		}
459
		$search = $this->normalizeNamespaces( $search );
460
		return $this->processCompletionResults( $search, $this->completionSearchBackend( $search ) );
461
	}
462
463
	/**
464
	 * Perform a completion search with variants.
465
	 * @param string $search
466
	 * @return SearchSuggestionSet
467
	 */
468
	public function completionSearchWithVariants( $search ) {
469
		if ( trim( $search ) === '' ) {
470
			return SearchSuggestionSet::emptySuggestionSet(); // Return empty result
471
		}
472
		$search = $this->normalizeNamespaces( $search );
473
474
		$results = $this->completionSearchBackend( $search );
475
		$fallbackLimit = $this->limit - $results->getSize();
476
		if ( $fallbackLimit > 0 ) {
477
			global $wgContLang;
478
479
			$fallbackSearches = $wgContLang->autoConvertToAllVariants( $search );
480
			$fallbackSearches = array_diff( array_unique( $fallbackSearches ), [ $search ] );
481
482
			foreach ( $fallbackSearches as $fbs ) {
483
				$this->setLimitOffset( $fallbackLimit );
484
				$fallbackSearchResult = $this->completionSearch( $fbs );
485
				$results->appendAll( $fallbackSearchResult );
486
				$fallbackLimit -= count( $fallbackSearchResult );
487
				if ( $fallbackLimit <= 0 ) {
488
					break;
489
				}
490
			}
491
		}
492
		return $this->processCompletionResults( $search, $results );
493
	}
494
495
	/**
496
	 * Extract titles from completion results
497
	 * @param SearchSuggestionSet $completionResults
498
	 * @return Title[]
499
	 */
500
	public function extractTitles( SearchSuggestionSet $completionResults ) {
501
		return $completionResults->map( function( SearchSuggestion $sugg ) {
502
			return $sugg->getSuggestedTitle();
503
		} );
504
	}
505
506
	/**
507
	 * Process completion search results.
508
	 * Resolves the titles and rescores.
509
	 * @param SearchSuggestionSet $suggestions
510
	 * @return SearchSuggestionSet
511
	 */
512
	protected function processCompletionResults( $search, SearchSuggestionSet $suggestions ) {
513
		$search = trim( $search );
514
		// preload the titles with LinkBatch
515
		$titles = $suggestions->map( function( SearchSuggestion $sugg ) {
516
			return $sugg->getSuggestedTitle();
517
		} );
518
		$lb = new LinkBatch( $titles );
519
		$lb->setCaller( __METHOD__ );
520
		$lb->execute();
521
522
		$results = $suggestions->map( function( SearchSuggestion $sugg ) {
523
			return $sugg->getSuggestedTitle()->getPrefixedText();
524
		} );
525
526
		// Rescore results with an exact title match
527
		// NOTE: in some cases like cross-namespace redirects
528
		// (frequently used as shortcuts e.g. WP:WP on huwiki) some
529
		// backends like Cirrus will return no results. We should still
530
		// try an exact title match to workaround this limitation
531
		$rescorer = new SearchExactMatchRescorer();
532
		$rescoredResults = $rescorer->rescore( $search, $this->namespaces, $results, $this->limit );
0 ignored issues
show
Bug introduced by
It seems like $this->namespaces can also be of type null; however, SearchExactMatchRescorer::rescore() does only seem to accept array<integer,integer>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
533
534
		if ( count( $rescoredResults ) > 0 ) {
535
			$found = array_search( $rescoredResults[0], $results );
536
			if ( $found === false ) {
537
				// If the first result is not in the previous array it
538
				// means that we found a new exact match
539
				$exactMatch = SearchSuggestion::fromTitle( 0, Title::newFromText( $rescoredResults[0] ) );
0 ignored issues
show
Bug introduced by
It seems like \Title::newFromText($rescoredResults[0]) can be null; however, fromTitle() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
540
				$suggestions->prepend( $exactMatch );
541
				$suggestions->shrink( $this->limit );
542
			} else {
543
				// if the first result is not the same we need to rescore
544
				if ( $found > 0 ) {
545
					$suggestions->rescore( $found );
546
				}
547
			}
548
		}
549
550
		return $suggestions;
551
	}
552
553
	/**
554
	 * Simple prefix search for subpages.
555
	 * @param string $search
556
	 * @return Title[]
557
	 */
558
	public function defaultPrefixSearch( $search ) {
559
		if ( trim( $search ) === '' ) {
560
			return [];
561
		}
562
563
		$search = $this->normalizeNamespaces( $search );
564
		return $this->simplePrefixSearch( $search );
565
	}
566
567
	/**
568
	 * Call out to simple search backend.
569
	 * Defaults to TitlePrefixSearch.
570
	 * @param string $search
571
	 * @return Title[]
572
	 */
573
	protected function simplePrefixSearch( $search ) {
574
		// Use default database prefix search
575
		$backend = new TitlePrefixSearch;
0 ignored issues
show
Deprecated Code introduced by
The class TitlePrefixSearch has been deprecated with message: Since 1.27, Use SearchEngine::prefixSearchSubpages or SearchEngine::completionSearch

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
576
		return $backend->defaultSearchBackend( $this->namespaces, $search, $this->limit, $this->offset );
0 ignored issues
show
Bug introduced by
It seems like $this->namespaces can also be of type null; however, PrefixSearch::defaultSearchBackend() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
577
	}
578
579
	/**
580
	 * Make a list of searchable namespaces and their canonical names.
581
	 * @deprecated since 1.27; use SearchEngineConfig::searchableNamespaces()
582
	 * @return array
583
	 */
584
	public static function searchableNamespaces() {
585
		return MediaWikiServices::getInstance()->getSearchEngineConfig()->searchableNamespaces();
586
	}
587
588
	/**
589
	 * Extract default namespaces to search from the given user's
590
	 * settings, returning a list of index numbers.
591
	 * @deprecated since 1.27; use SearchEngineConfig::userNamespaces()
592
	 * @param user $user
593
	 * @return array
594
	 */
595
	public static function userNamespaces( $user ) {
596
		return MediaWikiServices::getInstance()->getSearchEngineConfig()->userNamespaces( $user );
597
	}
598
599
	/**
600
	 * An array of namespaces indexes to be searched by default
601
	 * @deprecated since 1.27; use SearchEngineConfig::defaultNamespaces()
602
	 * @return array
603
	 */
604
	public static function defaultNamespaces() {
605
		return MediaWikiServices::getInstance()->getSearchEngineConfig()->defaultNamespaces();
606
	}
607
608
	/**
609
	 * Get a list of namespace names useful for showing in tooltips
610
	 * and preferences
611
	 * @deprecated since 1.27; use SearchEngineConfig::namespacesAsText()
612
	 * @param array $namespaces
613
	 * @return array
614
	 */
615
	public static function namespacesAsText( $namespaces ) {
616
		return MediaWikiServices::getInstance()->getSearchEngineConfig()->namespacesAsText( $namespaces );
617
	}
618
619
	/**
620
	 * Load up the appropriate search engine class for the currently
621
	 * active database backend, and return a configured instance.
622
	 * @deprecated since 1.27; Use SearchEngineFactory::create
623
	 * @param string $type Type of search backend, if not the default
624
	 * @return SearchEngine
625
	 */
626
	public static function create( $type = null ) {
627
		return MediaWikiServices::getInstance()->getSearchEngineFactory()->create( $type );
628
	}
629
630
	/**
631
	 * Return the search engines we support. If only $wgSearchType
632
	 * is set, it'll be an array of just that one item.
633
	 * @deprecated since 1.27; use SearchEngineConfig::getSearchTypes()
634
	 * @return array
635
	 */
636
	public static function getSearchTypes() {
637
		return MediaWikiServices::getInstance()->getSearchEngineConfig()->getSearchTypes();
638
	}
639
640
	/**
641
	 * Get a list of supported profiles.
642
	 * Some search engine implementations may expose specific profiles to fine-tune
643
	 * its behaviors.
644
	 * The profile can be passed as a feature data with setFeatureData( $profileType, $profileName )
645
	 * The array returned by this function contains the following keys:
646
	 * - name: the profile name to use with setFeatureData
647
	 * - desc-message: the i18n description
648
	 * - default: set to true if this profile is the default
649
	 *
650
	 * @since 1.28
651
	 * @param $profileType the type of profiles
652
	 * @return array|null the list of profiles or null if none available
653
	 */
654
	public function getProfiles( $profileType ) {
655
		return null;
656
	}
657
658
}
659
660
/**
661
 * Dummy class to be used when non-supported Database engine is present.
662
 * @todo FIXME: Dummy class should probably try something at least mildly useful,
663
 * such as a LIKE search through titles.
664
 * @ingroup Search
665
 */
666
class SearchEngineDummy extends SearchEngine {
667
	// no-op
668
}
669