aboutsummaryrefslogtreecommitdiffstats
path: root/includes/search/SearchEngineConfig.php
blob: 0554c7c2bf0156219fe5a8251881343da9b2a764 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
<?php

use MediaWiki\Config\Config;
use MediaWiki\Config\ServiceOptions;
use MediaWiki\HookContainer\HookContainer;
use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Language\Language;
use MediaWiki\MainConfigNames;
use MediaWiki\User\Options\UserOptionsLookup;
use MediaWiki\User\UserIdentity;

/**
 * Configuration handling class for SearchEngine.
 * Provides added service over plain configuration.
 *
 * @since 1.27
 */
class SearchEngineConfig {

	/** @internal For use by ServiceWiring.php ONLY */
	public const CONSTRUCTOR_OPTIONS = [
		MainConfigNames::NamespacesToBeSearchedDefault,
		MainConfigNames::SearchTypeAlternatives,
		MainConfigNames::SearchType,
	];

	/**
	 * Config object from which the settings will be derived.
	 * @var Config
	 */
	private $config;

	/**
	 * Search Engine Mappings
	 *
	 * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives).
	 * Value is a specification for ObjectFactory.
	 *
	 * @var array
	 */
	private $engineMappings;

	private ServiceOptions $options;
	private Language $language;
	private HookRunner $hookRunner;
	private UserOptionsLookup $userOptionsLookup;

	public function __construct(
		ServiceOptions $options,
		Language $language,
		HookContainer $hookContainer,
		array $engineMappings,
		UserOptionsLookup $userOptionsLookup
	) {
		$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
		$this->options = $options;
		$this->language = $language;
		$this->engineMappings = $engineMappings;
		$this->hookRunner = new HookRunner( $hookContainer );
		$this->userOptionsLookup = $userOptionsLookup;
	}

	/**
	 * Retrieve original config.
	 * @deprecated since 1.43, use ServiceOptions instead with DI.
	 * @return Config
	 */
	public function getConfig() {
		wfDeprecated( __METHOD__, '1.43' );
		return $this->config;
	}

	/**
	 * Make a list of searchable namespaces and their localized names.
	 * @return string[] Namespace ID => name
	 * @phan-return array<int,string>
	 */
	public function searchableNamespaces() {
		$arr = [];
		foreach ( $this->language->getNamespaces() as $ns => $name ) {
			if ( $ns >= NS_MAIN ) {
				$arr[$ns] = $name;
			}
		}

		$this->hookRunner->onSearchableNamespaces( $arr );
		return $arr;
	}

	/**
	 * Extract default namespaces to search from the given user's
	 * settings, returning a list of index numbers.
	 *
	 * @param UserIdentity $user
	 * @return int[]
	 */
	public function userNamespaces( $user ) {
		$arr = [];
		foreach ( $this->searchableNamespaces() as $ns => $name ) {
			if ( $this->userOptionsLookup->getOption( $user, 'searchNs' . $ns ) ) {
				$arr[] = $ns;
			}
		}

		return $arr;
	}

	/**
	 * An array of namespaces indexes to be searched by default
	 *
	 * @return int[] Namespace IDs
	 */
	public function defaultNamespaces() {
		return array_keys( $this->options->get( MainConfigNames::NamespacesToBeSearchedDefault ),
			true );
	}

	/**
	 * Return the search engines we support. If only $wgSearchType
	 * is set, it'll be an array of just that one item.
	 *
	 * @return array
	 */
	public function getSearchTypes() {
		$alternatives = $this->options->get( MainConfigNames::SearchTypeAlternatives ) ?: [];
		array_unshift( $alternatives, $this->options->get( MainConfigNames::SearchType ) );

		return $alternatives;
	}

	/**
	 * Return the search engine configured in $wgSearchType, etc.
	 *
	 * @return string|null
	 */
	public function getSearchType() {
		return $this->options->get( MainConfigNames::SearchType );
	}

	/**
	 * Returns the mappings between canonical search name and underlying PHP class
	 *
	 * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives).
	 * Value is a specification for ObjectFactory.
	 *
	 * For example to be able to use 'foobarsearch' in $wgSearchType and
	 * $wgSearchTypeAlternatives but the PHP class for 'foobarsearch'
	 * is 'MediaWiki\Extension\FoobarSearch\FoobarSearch' set:
	 *
	 * @par extension.json Example:
	 * @code
	 * "SearchMappings": {
	 * 	"foobarsearch": { "class": "MediaWiki\\Extension\\FoobarSearch\\FoobarSearch" }
	 * }
	 * @endcode
	 *
	 * @since 1.35
	 * @return array
	 */
	public function getSearchMappings() {
		return $this->engineMappings;
	}

	/**
	 * Get a list of namespace names useful for showing in tooltips
	 * and preferences.
	 *
	 * @param int[] $namespaces
	 * @return string[] List of names
	 */
	public function namespacesAsText( $namespaces ) {
		$formatted = array_map( [ $this->language, 'getFormattedNsText' ], $namespaces );
		foreach ( $formatted as $key => $ns ) {
			if ( !$ns ) {
				$formatted[$key] = wfMessage( 'blanknamespace' )->text();
			}
		}
		return $formatted;
	}
}