/**
  * 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 [];
 }
示例#10
0
 /**
  * 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;
 }
示例#11
0
 /**
  * @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);
 }
示例#13
0
 /**
  * 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;
 }
示例#15
0
 /**
  * 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}'");
 }
示例#16
0
/**
 * 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);
 }