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  return $this->langObjCache->getWithSetCallback(
114  $code,
115  function () use ( $code ) {
116  return $this->newFromCode( $code );
117  }
118  );
119  }
120 
128  private function newFromCode( $code, $fallback = false ): Language {
129  if ( !$this->langNameUtils->isValidCode( $code ) ) {
130  throw new MWException( "Invalid language code \"$code\"" );
131  }
132 
133  $constructorArgs = [
134  $code,
140  ];
141 
142  if ( !$this->langNameUtils->isValidBuiltInCode( $code ) ) {
143  // It's not possible to customise this code with class files, so
144  // just return a Language object. This is to support uselang= hacks.
145  return new Language( ...$constructorArgs );
146  }
147 
148  // Check if there is a language class for the code
149  $class = $this->classFromCode( $code, $fallback );
150  // LanguageCode does not inherit Language
151  if ( class_exists( $class ) && is_a( $class, 'Language', true ) ) {
152  return new $class( ...$constructorArgs );
153  }
154 
155  // Keep trying the fallback list until we find an existing class
156  $fallbacks = $this->langFallback->getAll( $code );
157  foreach ( $fallbacks as $fallbackCode ) {
158  $class = $this->classFromCode( $fallbackCode );
159  if ( class_exists( $class ) ) {
160  // TODO allow additional dependencies to be injected for subclasses somehow
161  return new $class( ...$constructorArgs );
162  }
163  }
164 
165  throw new MWException( "Invalid fallback sequence for language '$code'" );
166  }
167 
173  private function classFromCode( $code, $fallback = true ) {
174  if ( $fallback && $code == 'en' ) {
175  return 'Language';
176  } else {
177  return 'Language' . str_replace( '-', '_', ucfirst( $code ) );
178  }
179  }
180 
189  public function getParentLanguage( $code ) {
190  // We deliberately use array_key_exists() instead of isset() because we cache null.
191  if ( !array_key_exists( $code, $this->parentLangCache ) ) {
192  if ( !$this->langNameUtils->isValidBuiltInCode( $code ) ) {
193  $this->parentLangCache[$code] = null;
194  return null;
195  }
196  foreach ( LanguageConverter::$languagesWithVariants as $mainCode ) {
197  $lang = $this->getLanguage( $mainCode );
198  $converter = $this->langConverterFactory->getLanguageConverter( $lang );
199  if ( $converter->hasVariant( $code ) ) {
200  $this->parentLangCache[$code] = $lang;
201  return $lang;
202  }
203  }
204  $this->parentLangCache[$code] = null;
205  }
206 
207  return $this->parentLangCache[$code];
208  }
209 }
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:43
MediaWiki\Languages\LanguageFactory\newFromCode
newFromCode( $code, $fallback=false)
Create a language object for a given language code.
Definition: LanguageFactory.php:128
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:189
LanguageConverter\$languagesWithVariants
static array $languagesWithVariants
languages supporting variants
Definition: LanguageConverter.php:45
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:37
MediaWiki\Languages\LanguageFactory\classFromCode
classFromCode( $code, $fallback=true)
Definition: LanguageFactory.php:173
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