Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchEngineConfig
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 9
272
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getConfig
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 searchableNamespaces
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 userNamespaces
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 defaultNamespaces
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSearchTypes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getSearchType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSearchMappings
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 namespacesAsText
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3use MediaWiki\Config\Config;
4use MediaWiki\Config\ServiceOptions;
5use MediaWiki\HookContainer\HookContainer;
6use MediaWiki\HookContainer\HookRunner;
7use MediaWiki\MainConfigNames;
8use MediaWiki\User\Options\UserOptionsLookup;
9use MediaWiki\User\UserIdentity;
10
11/**
12 * Configuration handling class for SearchEngine.
13 * Provides added service over plain configuration.
14 *
15 * @since 1.27
16 */
17class SearchEngineConfig {
18
19    /** @internal For use by ServiceWiring.php ONLY */
20    public const CONSTRUCTOR_OPTIONS = [
21        MainConfigNames::NamespacesToBeSearchedDefault,
22        MainConfigNames::SearchTypeAlternatives,
23        MainConfigNames::SearchType,
24    ];
25
26    /**
27     * Config object from which the settings will be derived.
28     * @var Config
29     */
30    private $config;
31    private ServiceOptions $options;
32
33    /**
34     * Current language
35     * @var Language
36     */
37    private $language;
38
39    /**
40     * Search Engine Mappings
41     *
42     * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives).
43     * Value is a specification for ObjectFactory.
44     *
45     * @var array
46     */
47    private $engineMappings;
48
49    /**
50     * @var HookRunner
51     */
52    private $hookRunner;
53
54    /**
55     * @var UserOptionsLookup
56     */
57    private $userOptionsLookup;
58
59    /**
60     * @param ServiceOptions $options
61     * @param Language $lang
62     * @param HookContainer $hookContainer
63     * @param array $mappings
64     * @param UserOptionsLookup $userOptionsLookup
65     */
66    public function __construct(
67        ServiceOptions $options,
68        Language $lang,
69        HookContainer $hookContainer,
70        array $mappings,
71        UserOptionsLookup $userOptionsLookup
72    ) {
73        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
74        $this->options = $options;
75        $this->language = $lang;
76        $this->engineMappings = $mappings;
77        $this->hookRunner = new HookRunner( $hookContainer );
78        $this->userOptionsLookup = $userOptionsLookup;
79    }
80
81    /**
82     * Retrieve original config.
83     * @deprecated since 1.43, use ServiceOptions instead with DI.
84     * @return Config
85     */
86    public function getConfig() {
87        wfDeprecated( __METHOD__, '1.43' );
88        return $this->config;
89    }
90
91    /**
92     * Make a list of searchable namespaces and their localized names.
93     * @return string[] Namespace ID => name
94     * @phan-return array<int,string>
95     */
96    public function searchableNamespaces() {
97        $arr = [];
98        foreach ( $this->language->getNamespaces() as $ns => $name ) {
99            if ( $ns >= NS_MAIN ) {
100                $arr[$ns] = $name;
101            }
102        }
103
104        $this->hookRunner->onSearchableNamespaces( $arr );
105        return $arr;
106    }
107
108    /**
109     * Extract default namespaces to search from the given user's
110     * settings, returning a list of index numbers.
111     *
112     * @param UserIdentity $user
113     * @return int[]
114     */
115    public function userNamespaces( $user ) {
116        $arr = [];
117        foreach ( $this->searchableNamespaces() as $ns => $name ) {
118            if ( $this->userOptionsLookup->getOption( $user, 'searchNs' . $ns ) ) {
119                $arr[] = $ns;
120            }
121        }
122
123        return $arr;
124    }
125
126    /**
127     * An array of namespaces indexes to be searched by default
128     *
129     * @return int[] Namespace IDs
130     */
131    public function defaultNamespaces() {
132        return array_keys( $this->options->get( MainConfigNames::NamespacesToBeSearchedDefault ),
133            true );
134    }
135
136    /**
137     * Return the search engines we support. If only $wgSearchType
138     * is set, it'll be an array of just that one item.
139     *
140     * @return array
141     */
142    public function getSearchTypes() {
143        $alternatives = $this->options->get( MainConfigNames::SearchTypeAlternatives ) ?: [];
144        array_unshift( $alternatives, $this->options->get( MainConfigNames::SearchType ) );
145
146        return $alternatives;
147    }
148
149    /**
150     * Return the search engine configured in $wgSearchType, etc.
151     *
152     * @return string|null
153     */
154    public function getSearchType() {
155        return $this->options->get( MainConfigNames::SearchType );
156    }
157
158    /**
159     * Returns the mappings between canonical search name and underlying PHP class
160     *
161     * Key is the canonical name (used in $wgSearchType and $wgSearchTypeAlternatives).
162     * Value is a specification for ObjectFactory.
163     *
164     * For example to be able to use 'foobarsearch' in $wgSearchType and
165     * $wgSearchTypeAlternatives but the PHP class for 'foobarsearch'
166     * is 'MediaWiki\Extension\FoobarSearch\FoobarSearch' set:
167     *
168     * @par extension.json Example:
169     * @code
170     * "SearchMappings": {
171     *     "foobarsearch": { "class": "MediaWiki\\Extension\\FoobarSearch\\FoobarSearch" }
172     * }
173     * @endcode
174     *
175     * @since 1.35
176     * @return array
177     */
178    public function getSearchMappings() {
179        return $this->engineMappings;
180    }
181
182    /**
183     * Get a list of namespace names useful for showing in tooltips
184     * and preferences.
185     *
186     * @param int[] $namespaces
187     * @return string[] List of names
188     */
189    public function namespacesAsText( $namespaces ) {
190        $formatted = array_map( [ $this->language, 'getFormattedNsText' ], $namespaces );
191        foreach ( $formatted as $key => $ns ) {
192            if ( !$ns ) {
193                $formatted[$key] = wfMessage( 'blanknamespace' )->text();
194            }
195        }
196        return $formatted;
197    }
198}