/** * Get the languages for "in other languages". That would be translation * assistant languages with defined language fallbacks additionally. * @param string $code * @return string[] List of language codes */ protected function getFallbacks($code) { global $wgTranslateLanguageFallbacks; // User preference has the final say $preference = $this->context->getUser()->getOption('translate-editlangs'); if ($preference !== 'default') { $fallbacks = array_map('trim', explode(',', $preference)); foreach ($fallbacks as $k => $v) { if ($v === $code) { unset($fallbacks[$k]); } } return $fallbacks; } // Global configuration settings $fallbacks = array(); if (isset($wgTranslateLanguageFallbacks[$code])) { $fallbacks = (array) $wgTranslateLanguageFallbacks[$code]; } $list = Language::getFallbacksFor($code); array_pop($list); // Get 'en' away from the end $fallbacks = array_merge($list, $fallbacks); return array_unique($fallbacks); }
public function execute() { $mwLanguages = $this->loadMediaWiki(); $gtLanguages = $this->loadGettext(); $clLanguages = $this->loadCLDR(); $all = Language::fetchLanguageNames(null, 'all'); $allkeys = array_keys($all + $mwLanguages + $gtLanguages + $clLanguages); sort($allkeys); $this->output(sprintf("%12s %3s %3s %4s\n", 'Code', 'MW', 'Get', 'CLDR')); foreach ($allkeys as $code) { $mw = isset($mwLanguages[$code]) ? '+' : ''; $gt = isset($gtLanguages[$code]) ? '+' : ''; $cl = isset($clLanguages[$code]) ? '+' : ''; if ($mw === '') { $fallbacks = Language::getFallbacksFor($code); foreach ($fallbacks as $fcode) { if ($fcode !== 'en' && isset($mwLanguages[$fcode])) { $mw = '.'; } } } $error = ''; if (substr_count(sprintf('%s%s%s', $mw, $gt, $cl), '+') > 1) { $error = $this->tryMatch($code, $mw, $gtLanguages, $clLanguages); } $this->output(sprintf("%12s %-3s %-3s %-4s %s\n", $code, $mw, $gt, $cl, $error)); } }
/** * Get localized time units for a particular language, using fallback languages for missing * items. The time units are returned as an associative array. The keys are of the form: * <unit>-<tense>-<ordinality> (for example, 'hour-future-two'). The values include a placeholder * for the number (for example, '{0} months ago'). * * @param string $code The language to return the list in * @return array an associative array of time unit codes and localized time units */ public static function getUnits($code) { // Load time units localized for the requested language $units = self::loadLanguage($code); if ($units) { return $units; } // Load missing time units from fallback languages if (is_callable(array('Language', 'getFallbacksFor'))) { // MediaWiki 1.19 $fallbacks = Language::getFallbacksFor($code); foreach ($fallbacks as $fallback) { if ($units) { break; } // Get time units from a fallback language $units = self::loadLanguage($fallback); } } else { // MediaWiki 1.18 or earlier $fallback = $code; while ($fallback = Language::getFallbackFor($fallback)) { if ($units) { break; } // Get time units from a fallback language $units = self::loadLanguage($fallback); } } return $units; }
function getFallbacksFor($code) { $this->checkType('getFallbacksFor', 1, $code, 'string'); $ret = Language::getFallbacksFor($code); // Make 1-based if (count($ret)) { $ret = array_combine(range(1, count($ret)), $ret); } return array($ret); }
/** * Get localized language names for a particular language, using fallback languages for missing * items. * * @param $code string * @param $fbMethod int * @param $list int * @throws Exception * @return array an associative array of language codes and localized language names */ public static function getNames($code, $fbMethod = self::FALLBACK_NATIVE, $list = self::LIST_MW) { $xx = self::loadLanguage($code); $native = Language::fetchLanguageNames(null, $list === self::LIST_MW_SUPPORTED ? 'mwfile' : 'mw'); if ($fbMethod === self::FALLBACK_NATIVE) { $names = array_merge($native, $xx); } elseif ($fbMethod === self::FALLBACK_NORMAL) { // Load missing language names from fallback languages $fb = $xx; if (is_callable(array('Language', 'getFallbacksFor'))) { // MediaWiki 1.19 $fallbacks = Language::getFallbacksFor($code); foreach ($fallbacks as $fallback) { // Overwrite the things in fallback with what we have already $fb = array_merge(self::loadLanguage($fallback), $fb); } } else { // MediaWiki 1.18 or earlier $fallback = $code; while ($fallback = Language::getFallbackFor($fallback)) { // Overwrite the things in fallback with what we have already $fb = array_merge(self::loadLanguage($fallback), $fb); } } /* Add native names for codes that are not in cldr */ $names = array_merge($native, $fb); /* As a last resort, try the native name in Names.php */ if (!isset($names[$code]) && isset($native[$code])) { $names[$code] = $native[$code]; } } else { throw new Exception("Invalid value for 2:\$fallback in " . __METHOD__); } switch ($list) { case self::LIST_MW: case self::LIST_MW_SUPPORTED: /* Remove entries that are not in fb */ $names = array_intersect_key($names, $native); /* And fall to the return */ /* And fall to the return */ case self::LIST_MW_AND_CLDR: return $names; default: throw new Exception("Invalid value for 3:\$list in " . __METHOD__); } }
public function stage(GatewayType $adapter, $normalized, &$stagedData) { // FIXME: Document the upstream source for this reference data. $supported_countries = array('AU', 'AT', 'BE', 'BR', 'CA', 'CH', 'CN', 'DE', 'ES', 'GB', 'FR', 'IT', 'NL', 'PL', 'PT', 'RU', 'US'); $supported_full_locales = array('da_DK', 'he_IL', 'id_ID', 'jp_JP', 'no_NO', 'pt_BR', 'ru_RU', 'sv_SE', 'th_TH', 'tr_TR', 'zh_CN', 'zh_HK', 'zh_TW'); if (in_array($normalized['country'], $supported_countries)) { $stagedData['locale'] = $normalized['country']; } $fallbacks = Language::getFallbacksFor($normalized['language']); array_unshift($fallbacks, $normalized['language']); foreach ($fallbacks as $lang) { $locale = "{$lang}_{$normalized['country']}"; if (in_array($locale, $supported_full_locales)) { $stagedData['locale'] = $locale; return; } } }
/** * Get localized country names for a particular language, using fallback languages for missing * items. * * @param string $code The language to return the list in * @param int $fbMethod The fallback method * @return an associative array of country codes and localized country names */ public static function getNames($code) { // Load country names localized for the requested language $names = self::loadLanguage($code); // Load missing country names from fallback languages if (is_callable(array('Language', 'getFallbacksFor'))) { // MediaWiki 1.19 $fallbacks = Language::getFallbacksFor($code); foreach ($fallbacks as $fallback) { // Overwrite the things in fallback with what we have already $names = array_merge(self::loadLanguage($fallback), $names); } } else { // MediaWiki 1.18 or earlier $fallback = $code; while ($fallback = Language::getFallbackFor($fallback)) { // Overwrite the things in fallback with what we have already $names = array_merge(self::loadLanguage($fallback), $names); } } return $names; }
public function execute() { $template = <<<XML <?xml version="1.0" encoding="UTF-8"?> <graphml \txmlns="http://graphml.graphdrawing.org/xmlns" \txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \txsi:schemaLocation="http://graphml.graphdrawing.org/xmlns \t\thttp://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd" \txmlns:y="http://www.yworks.com/xml/graphml"> \t<key id="code" for="node" yfiles.type="nodegraphics"/> \t<graph id="G" edgedefault="directed"> \$1 \t</graph> </graphml> XML; $langs = Language::fetchLanguageNames(null, 'mw'); $nodes = $edges = array(); foreach ($langs as $code => $name) { $fallbacks = Language::getFallbacksFor($code); if ($fallbacks === array('en')) { continue; } $nodes[$code] = $this->createNode($code); $prev = $code; foreach ($fallbacks as $fb) { $nodes[$fb] = $this->createNode($fb); $edges[$fb . $prev] = Xml::element('edge', array('source' => $prev, 'target' => $fb)); $prev = $fb; } } $output = array_merge($nodes, $edges); $output = "\t\t" . implode("\n\t\t", $output); echo str_replace('$1', $output, $template); }
/** * Get the set of language scripts for the given language, * possibly using a fallback language. * * @param string $lang * @return array */ private function getLanguageScripts($lang) { $scripts = self::tryForKey($this->languageScripts, $lang); if ($scripts) { return $scripts; } $fallbacks = Language::getFallbacksFor($lang); foreach ($fallbacks as $lang) { $scripts = self::tryForKey($this->languageScripts, $lang); if ($scripts) { return $scripts; } } return []; }
/** * Get the plural rule types for the language * @since 1.22 * @return array Associative array with plural form number and plural rule type as key-value pairs */ public function getPluralRuleTypes() { $pluralRuleTypes = self::$dataCache->getItem(strtolower($this->mCode), 'pluralRuleTypes'); $fallbacks = Language::getFallbacksFor($this->mCode); if (!$pluralRuleTypes) { foreach ($fallbacks as $fallbackCode) { $pluralRuleTypes = self::$dataCache->getItem(strtolower($fallbackCode), 'pluralRuleTypes'); if ($pluralRuleTypes) { break; } } } return $pluralRuleTypes; }
/** * @param $code string * @return array */ protected static function getFallbacks($code) { global $wgUser, $wgTranslateLanguageFallbacks; // User preference has the final say $preference = $wgUser->getOption('translate-editlangs'); if ($preference !== 'default') { $fallbacks = array_map('trim', explode(',', $preference)); foreach ($fallbacks as $k => $v) { if ($v === $code) { unset($fallbacks[$k]); } } return $fallbacks; } // Global configuration settings $fallbacks = array(); if (isset($wgTranslateLanguageFallbacks[$code])) { $fallbacks = (array) $wgTranslateLanguageFallbacks[$code]; } // BC <1.19 if (method_exists('Language', 'getFallbacksFor')) { $list = Language::getFallbacksFor($code); array_pop($list); // Get 'en' away from the end $fallbacks = array_merge($list, $fallbacks); } else { $realFallback = $code ? Language::getFallbackFor($code) : false; if ($realFallback && $realFallback !== 'en') { $fallbacks = array_merge(array($realFallback), $fallbacks); } } return array_unique($fallbacks); }
static function getLanguageFallbacks($language) { return Language::getFallbacksFor($language); }
/** * Given a language, try and fetch messages from that language and its fallbacks. * * @see MessageCache::get * @param Language|StubObject $lang Preferred language * @param string $lckey Lowercase key for the message (as for localisation cache) * @param bool $useDB Whether to include messages from the wiki database * @param bool[] $alreadyTried Contains true for each language that has been tried already * @return string|bool The message, or false if not found */ private function getMessageForLang($lang, $lckey, $useDB, &$alreadyTried) { global $wgContLang; $langcode = $lang->getCode(); // Try checking the database for the requested language if ($useDB) { $uckey = $wgContLang->ucfirst($lckey); if (!isset($alreadyTried[$langcode])) { $message = $this->getMsgFromNamespace($this->getMessagePageName($langcode, $uckey), $langcode); if ($message !== false) { return $message; } $alreadyTried[$langcode] = true; } } else { $uckey = null; } // Check the CDB cache $message = $lang->getMessage($lckey); if ($message !== null) { return $message; } // Try checking the database for all of the fallback languages if ($useDB) { $fallbackChain = Language::getFallbacksFor($langcode); foreach ($fallbackChain as $code) { if (isset($alreadyTried[$code])) { continue; } $message = $this->getMsgFromNamespace($this->getMessagePageName($code, $uckey), $code); if ($message !== false) { return $message; } $alreadyTried[$code] = true; } } return false; }
public function getData(&$group, $savedData) { $defs = $this->readVariable($group, 'en'); $code = $this->language; $current = $savedData + $this->readVariable($group, $code); // Clean up duplicates to definitions from saved data $current = $this->cleanData($defs, $current); $chain = $current; if ($this->chainable) { foreach (Language::getFallbacksFor($code) as $code) { $fbdata = $this->readVariable($group, $code); if ($this->firstMagic) { $fbdata = $this->cleanData($defs, $fbdata); } $chain = array_merge_recursive($chain, $fbdata); } } if ($this->firstMagic) { $chain = $this->mergeMagic($defs, $chain); } $data = $group['data'] = array($defs, $chain, $current); return $data; }
/** * Create a language object for a given language code * @param $code String * @return Language */ protected static function newFromCode($code) { // Protect against path traversal below if (!Language::isValidCode($code) || strcspn($code, ":/\\") !== strlen($code)) { throw new MWException("Invalid language code \"{$code}\""); } if (!Language::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(); $lang->setCode($code); return $lang; } // Check if there is a language class for the code $class = self::classFromCode($code); self::preloadLanguageClass($class); if (MWInit::classExists($class)) { $lang = new $class(); return $lang; } // Keep trying the fallback list until we find an existing class $fallbacks = Language::getFallbacksFor($code); foreach ($fallbacks as $fallbackCode) { if (!Language::isValidBuiltInCode($fallbackCode)) { throw new MWException("Invalid fallback '{$fallbackCode}' in fallback sequence for '{$code}'"); } $class = self::classFromCode($fallbackCode); self::preloadLanguageClass($class); if (MWInit::classExists($class)) { $lang = Language::newFromCode($fallbackCode); $lang->setCode($code); return $lang; } } throw new MWException("Invalid fallback sequence for language '{$code}'"); }
/** * Get provided message in plain and HTML versions using language as priority * * @author Inez, Marooned * @return array containing 4 items: * - the plaintext message * - the rich-text message * - an int which is non-zero if the plaintext message fell back to the fallback language? (not sure this is the intention) * - an int which is non-zero if the rich-text message fell back to the fallback language? (not sure this is the intention) */ function wfMsgHTMLwithLanguage($key, $lang, $options = array(), $params = array(), $wantHTML = true) { global $wgContLanguageCode; wfProfileIn(__METHOD__); //remove 'content' option and pick proper language if (isset($options['content'])) { $lang = $wgContLanguageCode; unset($options['content']); } $options = array_merge($options, array('parsemag', 'language' => $lang)); //TODO: check if this ok or do we need to use $msgPlainRaw plus parsing $msgPlain = wfMsgExt($key, $options, $params); $msgPlainFallbacked = $msgRichFallbacked = 0; if ($lang == $wgContLanguageCode) { $fullKey = false; $langKey = $key; } else { $fullKey = true; $langKey = "{$key}/{$lang}"; } $msgPlainRaw = MessageCache::singleton()->get($langKey, true, $lang, $fullKey); $msgPlainRawEmpty = wfEmptyMsg($langKey, $msgPlainRaw); $found = false; foreach (Language::getFallbacksFor($lang) as $fallbackLang) { if ($fallbackLang == $wgContLanguageCode) { $fullKey = false; $langKey2 = $key; } else { $fullKey = true; $langKey2 = "{$key}/{$fallbackLang}"; } $msgPlainRawLang = MessageCache::singleton()->get($langKey2, true, $fallbackLang, $fullKey); $msgPlainRawLangEmpty = wfEmptyMsg($langKey2, $msgPlainRawLang); //if main message is empty and fallbacked is not, get fallbacked one if (wfEmptyMsg($langKey, $msgPlainRaw) && !$msgPlainRawLangEmpty) { //TODO: check if this ok or do we need to use $msgPlainRaw plus parsing $msgPlain = wfMsgExt($key, array_merge($options, array('language' => $fallbackLang)), $params); $msgPlainFallbacked++; } if ($msgPlainRaw != $msgPlainRawLang && !$msgPlainRawEmpty && !$msgPlainRawLangEmpty) { $found = true; break; } } // notify wfMsgHTMLwithLanguageAndAlternative() that we didn't get a match if (!$found) { $msgPlainFallbacked++; } if ($wantHTML) { $keyHTML = $key . '-HTML'; //TODO: check if this ok or do we need to use $msgRichRaw plus parsing $msgRich = wfMsgExt($keyHTML, $options, $params); if ($lang == $wgContLanguageCode) { $fullKey = false; $langKeyHTML = $keyHTML; } else { $fullKey = true; $langKeyHTML = "{$keyHTML}/{$lang}"; } $msgRichRaw = MessageCache::singleton()->get($langKeyHTML, true, $lang, $fullKey); $msgRichRawEmpty = wfEmptyMsg($langKeyHTML, $msgRichRaw); $found = false; foreach (Language::getFallbacksFor($lang) as $fallbackLang) { if ($fallbackLang == $wgContLanguageCode) { $fullKey = false; $langKeyHTML2 = $key; } else { $fullKey = true; $langKeyHTML2 = "{$keyHTML}/{$fallbackLang}"; } $msgRichRawLang = MessageCache::singleton()->get($langKeyHTML2, true, $fallbackLang, true); $msgRichRawLangEmpty = wfEmptyMsg($langKeyHTML2, $msgRichRawLang); if (wfEmptyMsg($langKeyHTML, $msgRich) && !$msgRichRawLangEmpty) { //TODO: check if this ok or do we need to use $msgRichRaw plus parsing $msgRich = wfMsgExt($keyHTML, array_merge($options, array('language' => $fallbackLang)), $params); $msgRichFallbacked++; } if ($msgRichRaw != $msgRichRawLang && !$msgRichRawEmpty && !wfEmptyMsg($keyHTML, $msgRichRawLang)) { $found = true; break; } } // notify wfMsgHTMLwithLanguageAndAlternative() that we didn't get a match if (!$found) { $msgRichFallbacked++; } if ($msgRichFallbacked > $msgPlainFallbacked || wfEmptyMsg($keyHTML, $msgRich)) { $msgRich = null; } } else { $msgRich = null; } wfProfileOut(__METHOD__); return array($msgPlain, $msgRich, $msgPlainFallbacked, $msgRichFallbacked); }
protected function getLocalizedText($dir) { $langCode = $this->getConfig()->get('LanguageCode'); $fallbacks = Language::getFallbacksFor($langCode); array_unshift($fallbacks, $langCode); foreach ($fallbacks as $code) { if (file_exists("{$dir}/{$code}.txt")) { return trim(file_get_contents("{$dir}/{$code}.txt")); } } $this->error("Could not find a valid localized file for {$langCode}.", 1); }