*/
use CLDRPluralRuleParser\Evaluator;
+use MediaWiki\Languages\LanguageNameUtils;
use MediaWiki\MediaWikiServices;
-use Wikimedia\Assert\Assert;
/**
* Internationalisation code
/**
* Return autonyms in fetchLanguageName(s).
* @since 1.32
+ * @deprecated since 1.34, LanguageNameUtils::AUTONYMS
*/
- const AS_AUTONYMS = null;
+ const AS_AUTONYMS = LanguageNameUtils::AUTONYMS;
/**
* Return all known languages in fetchLanguageName(s).
* @since 1.32
+ * @deprecated since 1.34, use LanguageNameUtils::ALL
*/
- const ALL = 'all';
+ const ALL = LanguageNameUtils::ALL;
/**
* Return in fetchLanguageName(s) only the languages for which we have at
* least some localisation.
* @since 1.32
+ * @deprecated since 1.34, use LanguageNameUtils::SUPPORTED
*/
- const SUPPORTED = 'mwfile';
+ const SUPPORTED = LanguageNameUtils::SUPPORTED;
/**
* @var LanguageConverter
/** @var LocalisationCache */
private $localisationCache;
+ /** @var LanguageNameUtils */
+ private $langNameUtils;
+
public static $mLangObjCache = [];
/**
*/
const STRICT_FALLBACKS = 1;
+ // TODO Make these const once we drop HHVM support (T192166)
public static $mWeekdayMsgs = [
'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
'friday', 'saturday'
*/
private static $grammarTransformations;
- /**
- * Cache for language names
- * @var HashBagOStuff|null
- */
- private static $languageNameCache;
-
/**
* Unicode directional formatting characters, for embedBidi()
*/
* @return Language
*/
protected static function newFromCode( $code, $fallback = false ) {
- if ( !self::isValidCode( $code ) ) {
+ $langNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
+ if ( !$langNameUtils->isValidCode( $code ) ) {
throw new MWException( "Invalid language code \"$code\"" );
}
- if ( !self::isValidBuiltInCode( $code ) ) {
+ if ( !$langNameUtils->isValidBuiltInCode( $code ) ) {
// It's not possible to customise this code with class files, so
// just return a Language object. This is to support uselang= hacks.
$lang = new Language;
// Keep trying the fallback list until we find an existing class
$fallbacks = self::getFallbacksFor( $code );
foreach ( $fallbacks as $fallbackCode ) {
- if ( !self::isValidBuiltInCode( $fallbackCode ) ) {
+ if ( !$langNameUtils->isValidBuiltInCode( $fallbackCode ) ) {
throw new MWException( "Invalid fallback '$fallbackCode' in fallback sequence for '$code'" );
}
}
if ( !defined( 'MEDIAWIKI_INSTALL' ) ) {
MediaWikiServices::getInstance()->resetServiceForTesting( 'LocalisationCache' );
+ MediaWikiServices::getInstance()->resetServiceForTesting( 'LanguageNameUtils' );
}
self::$mLangObjCache = [];
self::$fallbackLanguageCache = [];
self::$grammarTransformations = null;
- self::$languageNameCache = null;
}
/**
* Checks whether any localisation is available for that language tag
* in MediaWiki (MessagesXx.php exists).
*
+ * @deprecated since 1.34, use LanguageNameUtils
* @param string $code Language tag (in lower case)
* @return bool Whether language is supported
* @since 1.21
*/
public static function isSupportedLanguage( $code ) {
- if ( !self::isValidBuiltInCode( $code ) ) {
- return false;
- }
-
- if ( $code === 'qqq' ) {
- return false;
- }
-
- return is_readable( self::getMessagesFileName( $code ) ) ||
- is_readable( self::getJsonMessagesFileName( $code ) );
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->isSupportedLanguage( $code );
}
/**
* not it exists. This includes codes which are used solely for
* customisation via the MediaWiki namespace.
*
+ * @deprecated since 1.34, use LanguageNameUtils
+ *
* @param string $code
*
* @return bool
*/
public static function isValidCode( $code ) {
- static $cache = [];
- Assert::parameterType( 'string', $code, '$code' );
- if ( !isset( $cache[$code] ) ) {
- // People think language codes are html safe, so enforce it.
- // Ideally we should only allow a-zA-Z0-9-
- // but, .+ and other chars are often used for {{int:}} hacks
- // see bugs T39564, T39587, T38938
- $cache[$code] =
- // Protect against path traversal
- strcspn( $code, ":/\\\000&<>'\"" ) === strlen( $code )
- && !preg_match( MediaWikiTitleCodec::getTitleInvalidRegex(), $code );
- }
- return $cache[$code];
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()->isValidCode( $code );
}
/**
* Returns true if a language code is of a valid form for the purposes of
* internal customisation of MediaWiki, via Messages*.php or *.json.
*
+ * @deprecated since 1.34, use LanguageNameUtils
+ *
* @param string $code
*
* @since 1.18
* @return bool
*/
public static function isValidBuiltInCode( $code ) {
- Assert::parameterType( 'string', $code, '$code' );
-
- return (bool)preg_match( '/^[a-z0-9-]{2,}$/', $code );
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->isValidBuiltInCode( $code );
}
/**
* Returns true if a language code is an IETF tag known to MediaWiki.
*
+ * @deprecated since 1.34, use LanguageNameUtils
+ *
* @param string $tag
*
* @since 1.21
* @return bool
*/
public static function isKnownLanguageTag( $tag ) {
- // Quick escape for invalid input to avoid exceptions down the line
- // when code tries to process tags which are not valid at all.
- if ( !self::isValidBuiltInCode( $tag ) ) {
- return false;
- }
-
- if ( isset( MediaWiki\Languages\Data\Names::$names[$tag] )
- || self::fetchLanguageName( $tag, $tag ) !== ''
- ) {
- return true;
- }
-
- return false;
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->isKnownLanguageTag( $tag );
}
/**
} else {
$this->mCode = str_replace( '_', '-', strtolower( substr( static::class, 8 ) ) );
}
- $this->localisationCache = MediaWikiServices::getInstance()->getLocalisationCache();
+ $services = MediaWikiServices::getInstance();
+ $this->localisationCache = $services->getLocalisationCache();
+ $this->langNameUtils = $services->getLanguageNameUtils();
}
/**
if ( $usemsg && wfMessage( $msg )->exists() ) {
return $this->getMessageFromDB( $msg );
}
- $name = self::fetchLanguageName( $code );
+ $name = $this->langNameUtils->getLanguageName( $code );
if ( $name ) {
return $name; # if it's defined as a language name, show that
} else {
/**
* Get an array of language names, indexed by code.
+ *
+ * @deprecated since 1.34, use LanguageNameUtils::getLanguageNames
* @param null|string $inLanguage Code of language in which to return the names
* Use self::AS_AUTONYMS for autonyms (native names)
* @param string $include One of:
* @since 1.20
*/
public static function fetchLanguageNames( $inLanguage = self::AS_AUTONYMS, $include = 'mw' ) {
- $cacheKey = $inLanguage === self::AS_AUTONYMS ? 'null' : $inLanguage;
- $cacheKey .= ":$include";
- if ( self::$languageNameCache === null ) {
- self::$languageNameCache = new HashBagOStuff( [ 'maxKeys' => 20 ] );
- }
-
- $ret = self::$languageNameCache->get( $cacheKey );
- if ( !$ret ) {
- $ret = self::fetchLanguageNamesUncached( $inLanguage, $include );
- self::$languageNameCache->set( $cacheKey, $ret );
- }
- return $ret;
- }
-
- /**
- * Uncached helper for fetchLanguageNames
- * @param null|string $inLanguage Code of language in which to return the names
- * Use self::AS_AUTONYMS for autonyms (native names)
- * @param string $include One of:
- * self::ALL all available languages
- * 'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
- * self::SUPPORTED only if the language is in 'mw' *and* has a message file
- * @return array Language code => language name (sorted by key)
- */
- private static function fetchLanguageNamesUncached(
- $inLanguage = self::AS_AUTONYMS,
- $include = 'mw'
- ) {
- global $wgExtraLanguageNames, $wgUsePigLatinVariant;
-
- // If passed an invalid language code to use, fallback to en
- if ( $inLanguage !== self::AS_AUTONYMS && !self::isValidCode( $inLanguage ) ) {
- $inLanguage = 'en';
- }
-
- $names = [];
-
- if ( $inLanguage ) {
- # TODO: also include when $inLanguage is null, when this code is more efficient
- Hooks::run( 'LanguageGetTranslatedLanguageNames', [ &$names, $inLanguage ] );
- }
-
- $mwNames = $wgExtraLanguageNames + MediaWiki\Languages\Data\Names::$names;
- if ( $wgUsePigLatinVariant ) {
- // Pig Latin (for variant development)
- $mwNames['en-x-piglatin'] = 'Igpay Atinlay';
- }
-
- foreach ( $mwNames as $mwCode => $mwName ) {
- # - Prefer own MediaWiki native name when not using the hook
- # - For other names just add if not added through the hook
- if ( $mwCode === $inLanguage || !isset( $names[$mwCode] ) ) {
- $names[$mwCode] = $mwName;
- }
- }
-
- if ( $include === self::ALL ) {
- ksort( $names );
- return $names;
- }
-
- $returnMw = [];
- $coreCodes = array_keys( $mwNames );
- foreach ( $coreCodes as $coreCode ) {
- $returnMw[$coreCode] = $names[$coreCode];
- }
-
- if ( $include === self::SUPPORTED ) {
- $namesMwFile = [];
- # We do this using a foreach over the codes instead of a directory
- # loop so that messages files in extensions will work correctly.
- foreach ( $returnMw as $code => $value ) {
- if ( is_readable( self::getMessagesFileName( $code ) )
- || is_readable( self::getJsonMessagesFileName( $code ) )
- ) {
- $namesMwFile[$code] = $names[$code];
- }
- }
-
- ksort( $namesMwFile );
- return $namesMwFile;
- }
-
- ksort( $returnMw );
- # 'mw' option; default if it's not one of the other two options (all/mwfile)
- return $returnMw;
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->getLanguageNames( $inLanguage, $include );
}
/**
+ * @deprecated since 1.34, use LanguageNameUtils::getLanguageName
* @param string $code The code of the language for which to get the name
* @param null|string $inLanguage Code of language in which to return the name
* (SELF::AS_AUTONYMS for autonyms)
$inLanguage = self::AS_AUTONYMS,
$include = self::ALL
) {
- $code = strtolower( $code );
- $array = self::fetchLanguageNames( $inLanguage, $include );
- return !array_key_exists( $code, $array ) ? '' : $array[$code];
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->getLanguageName( $code, $inLanguage, $include );
}
/**
/**
* Get the name of a file for a certain language code
+ *
+ * @deprecated since 1.34, use LanguageNameUtils
* @param string $prefix Prepend this to the filename
* @param string $code Language code
* @param string $suffix Append this to the filename
* @return string $prefix . $mangledCode . $suffix
*/
public static function getFileName( $prefix, $code, $suffix = '.php' ) {
- if ( !self::isValidBuiltInCode( $code ) ) {
- throw new MWException( "Invalid language code \"$code\"" );
- }
-
- return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->getFileName( $prefix, $code, $suffix );
}
/**
+ * @deprecated since 1.34, use LanguageNameUtils
* @param string $code
* @return string
*/
public static function getMessagesFileName( $code ) {
- global $IP;
- $file = self::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
- Hooks::run( 'Language::getMessagesFileName', [ $code, &$file ] );
- return $file;
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->getMessagesFileName( $code );
}
/**
+ * @deprecated since 1.34, use LanguageNameUtils
* @param string $code
* @return string
* @throws MWException
* @since 1.23
*/
public static function getJsonMessagesFileName( $code ) {
- global $IP;
-
- if ( !self::isValidBuiltInCode( $code ) ) {
- throw new MWException( "Invalid language code \"$code\"" );
- }
-
- return "$IP/languages/i18n/$code.json";
+ return MediaWikiServices::getInstance()->getLanguageNameUtils()
+ ->getJsonMessagesFileName( $code );
}
/**