Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
95.83% |
23 / 24 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
LanguageConverterFactory | |
95.83% |
23 / 24 |
|
80.00% |
4 / 5 |
8 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
instantiateConverter | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
getLanguageConverter | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
2.02 | |||
isConversionDisabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isLinkConversionDisabled | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Languages; |
22 | |
23 | use BanConverter; |
24 | use CrhConverter; |
25 | use EnConverter; |
26 | use GanConverter; |
27 | use IuConverter; |
28 | use KuConverter; |
29 | use MediaWiki\Config\ServiceOptions; |
30 | use MediaWiki\Language\ILanguageConverter; |
31 | use MediaWiki\Language\Language; |
32 | use MediaWiki\MainConfigNames; |
33 | use MediaWiki\StubObject\StubUserLang; |
34 | use MniConverter; |
35 | use ShConverter; |
36 | use ShiConverter; |
37 | use SrConverter; |
38 | use TgConverter; |
39 | use TlyConverter; |
40 | use TrivialLanguageConverter; |
41 | use UzConverter; |
42 | use Wikimedia\ObjectFactory\ObjectFactory; |
43 | use WuuConverter; |
44 | use ZghConverter; |
45 | use ZhConverter; |
46 | |
47 | /** |
48 | * An interface for creating language converters. |
49 | * |
50 | * @since 1.35 |
51 | * @ingroup Language |
52 | */ |
53 | class LanguageConverterFactory { |
54 | |
55 | /** @var ILanguageConverter[] */ |
56 | private $cache = []; |
57 | /** |
58 | * @var array |
59 | */ |
60 | private $converterList = [ |
61 | 'ban' => [ |
62 | 'class' => BanConverter::class, |
63 | ], |
64 | 'crh' => [ |
65 | 'class' => CrhConverter::class, |
66 | ], |
67 | 'gan' => [ |
68 | 'class' => GanConverter::class, |
69 | ], |
70 | 'iu' => [ |
71 | 'class' => IuConverter::class, |
72 | ], |
73 | 'ku' => [ |
74 | 'class' => KuConverter::class, |
75 | ], |
76 | 'mni' => [ |
77 | 'class' => MniConverter::class, |
78 | ], |
79 | 'shi' => [ |
80 | 'class' => ShiConverter::class, |
81 | ], |
82 | 'sh' => [ |
83 | 'class' => ShConverter::class, |
84 | ], |
85 | 'sr' => [ |
86 | 'class' => SrConverter::class, |
87 | ], |
88 | 'tg' => [ |
89 | 'class' => TgConverter::class, |
90 | ], |
91 | 'tly' => [ |
92 | 'class' => TlyConverter::class, |
93 | ], |
94 | 'uz' => [ |
95 | 'class' => UzConverter::class, |
96 | ], |
97 | 'wuu' => [ |
98 | 'class' => WuuConverter::class, |
99 | ], |
100 | 'zgh' => [ |
101 | 'class' => ZghConverter::class, |
102 | ], |
103 | 'zh' => [ |
104 | 'class' => ZhConverter::class, |
105 | ], |
106 | ]; |
107 | |
108 | private const DEFAULT_CONVERTER = [ |
109 | 'class' => TrivialLanguageConverter::class, |
110 | 'services' => [ |
111 | 'TitleFormatter', |
112 | ] |
113 | ]; |
114 | |
115 | private const EN_CONVERTER = [ |
116 | 'class' => EnConverter::class, |
117 | ]; |
118 | |
119 | /** |
120 | * @internal For use by ServiceWiring |
121 | */ |
122 | public const CONSTRUCTOR_OPTIONS = [ |
123 | MainConfigNames::UsePigLatinVariant, |
124 | MainConfigNames::DisableLangConversion, |
125 | MainConfigNames::DisableTitleConversion, |
126 | ]; |
127 | |
128 | private ServiceOptions $options; |
129 | private ObjectFactory $objectFactory; |
130 | |
131 | /** |
132 | * @var callable callback of "() : Language" |
133 | */ |
134 | private $defaultLanguage; |
135 | |
136 | /** |
137 | * @param ServiceOptions $options |
138 | * @param ObjectFactory $objectFactory |
139 | * @param callable $defaultLanguage callback of "() : Language", should return |
140 | * default language. Used in getLanguageConverter when $language is null. |
141 | * |
142 | * @internal Should be called from MediaWikiServices only. |
143 | */ |
144 | public function __construct( |
145 | ServiceOptions $options, |
146 | ObjectFactory $objectFactory, |
147 | callable $defaultLanguage |
148 | ) { |
149 | $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS ); |
150 | $this->options = $options; |
151 | $this->objectFactory = $objectFactory; |
152 | if ( $options->get( MainConfigNames::UsePigLatinVariant ) ) { |
153 | $this->converterList['en'] = self::EN_CONVERTER; |
154 | } |
155 | $this->defaultLanguage = $defaultLanguage; |
156 | } |
157 | |
158 | /** |
159 | * Returns Converter instance for a given language object |
160 | * |
161 | * @param Language|StubUserLang $lang |
162 | * @return ILanguageConverter |
163 | */ |
164 | private function instantiateConverter( $lang ): ILanguageConverter { |
165 | $code = mb_strtolower( $lang->getCode() ); |
166 | $spec = $this->converterList[$code] ?? self::DEFAULT_CONVERTER; |
167 | // ObjectFactory::createObject accepts an array, not just a callable (phan bug) |
168 | // @phan-suppress-next-line PhanTypeInvalidCallableArrayKey, PhanTypeInvalidCallableArraySize |
169 | return $this->objectFactory->createObject( |
170 | $spec, |
171 | [ |
172 | 'assertClass' => ILanguageConverter::class, |
173 | 'extraArgs' => [ $lang ], |
174 | ] |
175 | ); |
176 | } |
177 | |
178 | /** |
179 | * Provide a LanguageConverter for given language |
180 | * |
181 | * @param Language|StubUserLang|null $language for which a LanguageConverter should be provided. |
182 | * If it is null, then the LanguageConverter provided for current content language as returned |
183 | * by the callback provided to the constructor. |
184 | * |
185 | * @return ILanguageConverter |
186 | */ |
187 | public function getLanguageConverter( $language = null ): ILanguageConverter { |
188 | $lang = $language ?? ( $this->defaultLanguage )(); |
189 | if ( isset( $this->cache[$lang->getCode()] ) ) { |
190 | return $this->cache[$lang->getCode()]; |
191 | } |
192 | // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive |
193 | $converter = $this->instantiateConverter( $lang ); |
194 | $this->cache[$lang->getCode()] = $converter; |
195 | return $converter; |
196 | } |
197 | |
198 | /** |
199 | * Whether to disable language variant conversion. |
200 | * |
201 | * @return bool |
202 | */ |
203 | public function isConversionDisabled() { |
204 | return $this->options->get( MainConfigNames::DisableLangConversion ); |
205 | } |
206 | |
207 | /** |
208 | * Whether to disable language variant conversion for links. |
209 | * |
210 | * @return bool |
211 | */ |
212 | public function isLinkConversionDisabled() { |
213 | return $this->options->get( MainConfigNames::DisableLangConversion ) || |
214 | // Note that this configuration option is misnamed. |
215 | $this->options->get( MainConfigNames::DisableTitleConversion ); |
216 | } |
217 | } |