Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.00% covered (success)
92.00%
23 / 25
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
LanguageConverterFactory
95.83% covered (success)
95.83%
23 / 24
80.00% covered (warning)
80.00%
4 / 5
8
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 instantiateConverter
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageConverter
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 isConversionDisabled
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isLinkConversionDisabled
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * @license GPL-2.0-or-later
4 * @file
5 */
6
7namespace MediaWiki\Language;
8
9use MediaWiki\Config\ServiceOptions;
10use MediaWiki\Language\Converters\BanConverter;
11use MediaWiki\Language\Converters\CrhConverter;
12use MediaWiki\Language\Converters\EnConverter;
13use MediaWiki\Language\Converters\GanConverter;
14use MediaWiki\Language\Converters\IuConverter;
15use MediaWiki\Language\Converters\KuConverter;
16use MediaWiki\Language\Converters\MniConverter;
17use MediaWiki\Language\Converters\ShConverter;
18use MediaWiki\Language\Converters\ShiConverter;
19use MediaWiki\Language\Converters\SrConverter;
20use MediaWiki\Language\Converters\TgConverter;
21use MediaWiki\Language\Converters\TlyConverter;
22use MediaWiki\Language\Converters\UzConverter;
23use MediaWiki\Language\Converters\WuuConverter;
24use MediaWiki\Language\Converters\ZghConverter;
25use MediaWiki\Language\Converters\ZhConverter;
26use MediaWiki\MainConfigNames;
27use MediaWiki\StubObject\StubUserLang;
28use Wikimedia\ObjectFactory\ObjectFactory;
29
30/**
31 * An interface for creating language converters.
32 *
33 * @since 1.35
34 * @ingroup Language
35 */
36class LanguageConverterFactory {
37
38    /** @var ILanguageConverter[] */
39    private $cache = [];
40    /**
41     * @var array
42     * @phpcs-require-sorted-array
43     */
44    private $converterList = [
45        'ban' => [
46            'class' => BanConverter::class,
47        ],
48        'crh' => [
49            'class' => CrhConverter::class,
50        ],
51        'gan' => [
52            'class' => GanConverter::class,
53        ],
54        'iu' => [
55            'class' => IuConverter::class,
56        ],
57        'ku' => [
58            'class' => KuConverter::class,
59        ],
60        'mni' => [
61            'class' => MniConverter::class,
62        ],
63        'sh' => [
64            'class' => ShConverter::class,
65        ],
66        'shi' => [
67            'class' => ShiConverter::class,
68        ],
69        'sr' => [
70            'class' => SrConverter::class,
71        ],
72        'tg' => [
73            'class' => TgConverter::class,
74        ],
75        'tly' => [
76            'class' => TlyConverter::class,
77        ],
78        'uz' => [
79            'class' => UzConverter::class,
80        ],
81        'wuu' => [
82            'class' => WuuConverter::class,
83        ],
84        'zgh' => [
85            'class' => ZghConverter::class,
86        ],
87        'zh' => [
88            'class' => ZhConverter::class,
89        ],
90    ];
91
92    private const DEFAULT_CONVERTER = [
93        'class' => TrivialLanguageConverter::class,
94        'services' => [
95            'TitleFormatter',
96        ]
97    ];
98
99    private const EN_CONVERTER = [
100        'class' => EnConverter::class,
101    ];
102
103    /**
104     * @internal For use by ServiceWiring
105     */
106    public const CONSTRUCTOR_OPTIONS = [
107        MainConfigNames::UsePigLatinVariant,
108        MainConfigNames::DisableLangConversion,
109        MainConfigNames::DisableTitleConversion,
110    ];
111
112    private ServiceOptions $options;
113    private ObjectFactory $objectFactory;
114
115    /**
116     * @var callable callback of "() : Language"
117     */
118    private $defaultLanguage;
119
120    /**
121     * @param ServiceOptions $options
122     * @param ObjectFactory $objectFactory
123     * @param callable $defaultLanguage callback of "() : Language", should return
124     *  default language. Used in getLanguageConverter when $language is null.
125     *
126     * @internal Should be called from MediaWikiServices only.
127     */
128    public function __construct(
129        ServiceOptions $options,
130        ObjectFactory $objectFactory,
131        callable $defaultLanguage
132    ) {
133        $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
134        $this->options = $options;
135        $this->objectFactory = $objectFactory;
136        if ( $options->get( MainConfigNames::UsePigLatinVariant ) ) {
137            $this->converterList['en'] = self::EN_CONVERTER;
138        }
139        $this->defaultLanguage = $defaultLanguage;
140    }
141
142    /**
143     * Returns Converter instance for a given language object
144     *
145     * @param Language|StubUserLang $lang
146     * @return ILanguageConverter
147     */
148    private function instantiateConverter( $lang ): ILanguageConverter {
149        $code = mb_strtolower( $lang->getCode() );
150        $spec = $this->converterList[$code] ?? self::DEFAULT_CONVERTER;
151        return $this->objectFactory->createObject(
152            $spec,
153            [
154                'assertClass' => ILanguageConverter::class,
155                'extraArgs' => [ $lang ],
156            ]
157        );
158    }
159
160    /**
161     * Provide a LanguageConverter for given language
162     *
163     * @param Language|StubUserLang|null $language for which a LanguageConverter should be provided.
164     * If it is null, then the LanguageConverter provided for current content language as returned
165     * by the callback provided to the constructor.
166     *
167     * @return ILanguageConverter
168     */
169    public function getLanguageConverter( $language = null ): ILanguageConverter {
170        $lang = $language ?? ( $this->defaultLanguage )();
171        if ( isset( $this->cache[$lang->getCode()] ) ) {
172            return $this->cache[$lang->getCode()];
173        }
174        // @phan-suppress-next-line PhanTypeMismatchArgumentNullable False positive
175        $converter = $this->instantiateConverter( $lang );
176        $this->cache[$lang->getCode()] = $converter;
177        return $converter;
178    }
179
180    /**
181     * Whether to disable language variant conversion.
182     *
183     * @return bool
184     */
185    public function isConversionDisabled() {
186        return $this->options->get( MainConfigNames::DisableLangConversion );
187    }
188
189    /**
190     * Whether to disable language variant conversion for links.
191     *
192     * @return bool
193     */
194    public function isLinkConversionDisabled() {
195        return $this->options->get( MainConfigNames::DisableLangConversion ) ||
196            // Note that this configuration option is misnamed.
197            $this->options->get( MainConfigNames::DisableTitleConversion );
198    }
199}
200
201/** @deprecated class alias since 1.45 */
202class_alias( LanguageConverterFactory::class, 'MediaWiki\\Languages\\LanguageConverterFactory' );