MediaWiki  master
LanguageFactory.php
Go to the documentation of this file.
1 <?php
25 namespace MediaWiki\Languages;
26 
27 use Language;
30 use MapCacheLRU;
33 use MWException;
34 
44  private $options;
45 
48 
50  private $langNameUtils;
51 
53  private $langFallback;
54 
57 
59  private $hookContainer;
60 
62  private $langObjCache;
63 
65  private $parentLangCache = [];
66 
70  public const CONSTRUCTOR_OPTIONS = [
71  'DummyLanguageCodes',
72  ];
73 
75  private const LANG_CACHE_SIZE = 10;
76 
85  public function __construct(
92  ) {
93  $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
94 
95  $this->options = $options;
96  $this->localisationCache = $localisationCache;
97  $this->langNameUtils = $langNameUtils;
98  $this->langFallback = $langFallback;
99  $this->langConverterFactory = $langConverterFactory;
100  $this->hookContainer = $hookContainer;
101  $this->langObjCache = new MapCacheLRU( self::LANG_CACHE_SIZE );
102  }
103 
111  public function getLanguage( $code ): Language {
112  $code = $this->options->get( 'DummyLanguageCodes' )[$code] ?? $code;
113  $langObj = $this->langObjCache->get( $code );
114 
115  if ( !$langObj ) {
116  $langObj = $this->newFromCode( $code );
117  $this->langObjCache->set( $code, $langObj );
118  }
119 
120  return $langObj;
121  }
122 
130  private function newFromCode( $code, $fallback = false ): Language {
131  if ( !$this->langNameUtils->isValidCode( $code ) ) {
132  throw new MWException( "Invalid language code \"$code\"" );
133  }
134 
135  $constructorArgs = [
136  $code,
142  ];
143 
144  if ( !$this->langNameUtils->isValidBuiltInCode( $code ) ) {
145  // It's not possible to customise this code with class files, so
146  // just return a Language object. This is to support uselang= hacks.
147  return new Language( ...$constructorArgs );
148  }
149 
150  // Check if there is a language class for the code
151  $class = $this->classFromCode( $code, $fallback );
152  // LanguageCode does not inherit Language
153  if ( class_exists( $class ) && is_a( $class, 'Language', true ) ) {
154  return new $class( ...$constructorArgs );
155  }
156 
157  // Keep trying the fallback list until we find an existing class
158  $fallbacks = $this->langFallback->getAll( $code );
159  foreach ( $fallbacks as $fallbackCode ) {
160  $class = $this->classFromCode( $fallbackCode );
161  if ( class_exists( $class ) ) {
162  // TODO allow additional dependencies to be injected for subclasses somehow
163  return new $class( ...$constructorArgs );
164  }
165  }
166 
167  throw new MWException( "Invalid fallback sequence for language '$code'" );
168  }
169 
175  private function classFromCode( $code, $fallback = true ) {
176  if ( $fallback && $code == 'en' ) {
177  return 'Language';
178  } else {
179  return 'Language' . str_replace( '-', '_', ucfirst( $code ) );
180  }
181  }
182 
191  public function getParentLanguage( $code ) {
192  // We deliberately use array_key_exists() instead of isset() because we cache null.
193  if ( !array_key_exists( $code, $this->parentLangCache ) ) {
194  $codeBase = explode( '-', $code )[0];
195  if ( !in_array( $codeBase, LanguageConverter::$languagesWithVariants ) ) {
196  $this->parentLangCache[$code] = null;
197  return null;
198  }
199 
200  $lang = $this->getLanguage( $codeBase );
201  $converter = $this->langConverterFactory->getLanguageConverter( $lang );
202  if ( !$converter->hasVariant( $code ) ) {
203  $this->parentLangCache[$code] = null;
204  return null;
205  }
206 
207  $this->parentLangCache[$code] = $lang;
208  }
209 
210  return $this->parentLangCache[$code];
211  }
212 }
MediaWiki\Languages
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
$fallback
$fallback
Definition: MessagesAb.php:11
MediaWiki\Languages\LanguageFactory
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: LanguageFactory.php:42
MediaWiki\Languages\LanguageFactory\$langConverterFactory
LanguageConverterFactory $langConverterFactory
Definition: LanguageFactory.php:56
MediaWiki\Languages\LanguageFallback
Definition: LanguageFallback.php:31
MediaWiki\Languages\LanguageFactory\$parentLangCache
array $parentLangCache
Definition: LanguageFactory.php:65
MediaWiki\Languages\LanguageFactory\$langNameUtils
LanguageNameUtils $langNameUtils
Definition: LanguageFactory.php:50
MediaWiki\Languages\LanguageFactory\$options
ServiceOptions $options
Definition: LanguageFactory.php:44
MediaWiki\Languages\LanguageFactory\__construct
__construct(ServiceOptions $options, LocalisationCache $localisationCache, LanguageNameUtils $langNameUtils, LanguageFallback $langFallback, LanguageConverterFactory $langConverterFactory, HookContainer $hookContainer)
Definition: LanguageFactory.php:85
MediaWiki\Languages\LanguageConverterFactory
An interface for creating language converters.
Definition: LanguageConverterFactory.php:46
MediaWiki\Languages\LanguageFactory\$langObjCache
MapCacheLRU $langObjCache
Definition: LanguageFactory.php:62
MediaWiki\Languages\LanguageNameUtils
A service that provides utilities to do with language names and codes.
Definition: LanguageNameUtils.php:42
MediaWiki\Languages\LanguageFactory\newFromCode
newFromCode( $code, $fallback=false)
Create a language object for a given language code.
Definition: LanguageFactory.php:130
MWException
MediaWiki exception.
Definition: MWException.php:29
MediaWiki\Config\ServiceOptions
A class for passing options to services.
Definition: ServiceOptions.php:27
MapCacheLRU
Handles a simple LRU key/value map with a maximum number of entries.
Definition: MapCacheLRU.php:36
MediaWiki\Languages\LanguageFactory\$localisationCache
LocalisationCache $localisationCache
Definition: LanguageFactory.php:47
MediaWiki\Languages\LanguageFactory\$langFallback
LanguageFallback $langFallback
Definition: LanguageFactory.php:53
MediaWiki\Languages\LanguageFactory\getLanguage
getLanguage( $code)
Get a cached or new language object for a given language code.
Definition: LanguageFactory.php:111
LocalisationCache
Class for caching the contents of localisation files, Messages*.php and *.i18n.php.
Definition: LocalisationCache.php:43
MediaWiki\Languages\LanguageFactory\LANG_CACHE_SIZE
const LANG_CACHE_SIZE
How many distinct Language objects to retain at most in memory (T40439).
Definition: LanguageFactory.php:75
MediaWiki\Languages\LanguageFactory\getParentLanguage
getParentLanguage( $code)
Get the "parent" language which has a converter to convert a "compatible" language (in another varian...
Definition: LanguageFactory.php:191
LanguageConverter\$languagesWithVariants
static array $languagesWithVariants
languages supporting variants
Definition: LanguageConverter.php:44
MediaWiki\Languages\LanguageFactory\$hookContainer
HookContainer $hookContainer
Definition: LanguageFactory.php:59
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
LanguageConverter
Base class for multi-variant language conversion.
Definition: LanguageConverter.php:36
MediaWiki\Languages\LanguageFactory\classFromCode
classFromCode( $code, $fallback=true)
Definition: LanguageFactory.php:175
MediaWiki\Languages\LanguageFactory\CONSTRUCTOR_OPTIONS
const CONSTRUCTOR_OPTIONS
Definition: LanguageFactory.php:70
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:42
MediaWiki\Config\ServiceOptions\assertRequiredOptions
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Definition: ServiceOptions.php:71