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)); } }
public function execute() { $user = $this->getUser(); $requestParams = $this->extractRequestParams(); $group = MessageGroups::getGroup($requestParams['group']); $code = $requestParams['language']; if (!$group || MessageGroups::isDynamic($group)) { $this->dieUsageMsg(array('missingparam', 'group')); } $stateConfig = $group->getMessageGroupStates()->getStates(); if (!$stateConfig) { $this->dieUsage('Message group review not in use', 'disabled'); } if (!$user->isAllowed(self::$right)) { $this->dieUsage('Permission denied', 'permissiondenied'); } if ($user->isBlocked()) { $this->dieUsage('You have been blocked', 'blocked'); } $requestParams = $this->extractRequestParams(); $languages = Language::fetchLanguageNames(); if (!isset($languages[$code])) { $this->dieUsageMsg(array('missingparam', 'language')); } $targetState = $requestParams['state']; if (!isset($stateConfig[$targetState])) { $this->dieUsage('The requested state is invalid', 'invalidstate'); } if (is_array($stateConfig[$targetState]) && isset($stateConfig[$targetState]['right']) && !$user->isAllowed($stateConfig[$targetState]['right'])) { $this->dieUsage('Permission denied', 'permissiondenied'); } self::changeState($group, $code, $targetState, $user); $output = array('review' => array('group' => $group->getId(), 'language' => $code, 'state' => $targetState)); $this->getResult()->addValue(null, $this->getModuleName(), $output); }
public function execute() { $users = 10; // For number of translations, limited to [0,20] $mean = 15; $stddev = 20; $stash = new TranslationStashStorage(wfGetDB(DB_MASTER)); $languages = array_keys(Language::fetchLanguageNames()); for ($i = 0; $i < $users; $i++) { $username = '******' . wfRandomString(6); $password = wfRandomString(12); $email = "{$username}.{$password}@blackhole.io"; $user = TranslateSandbox::addUser($username, $password, $email); $language = $languages[rand(0, count($languages) - 1)]; $count = wfGaussMs($mean, $stddev); $count = min(20, $count); $count = max(0, $count); for ($j = 0; $j < $count; $j++) { $title = Title::makeTitle(NS_MEDIAWIKI, wfRandomString(24) . '/' . $language); $value = array('Pupu söi'); for ($k = rand(0, 20); $k > 0; $k--) { $value[] = wfRandomString(rand(1, 28)); } $value = implode("\n", $value); $translation = new StashedTranslation($user, $title, $value); $stash->addTranslation($translation); } } }
public function execute($sub) { if (!$this->userCanExecute($this->getUser())) { $this->displayRestrictionError(); return; } $out = $this->getOutput(); $out->addModules('ext.SpellingDictionary.viewByLanguage'); $out->setPageTitle($this->msg('title-view-by-language')); $out->addWikiMsg('view-by-lang-intro'); // Building a language selector // Display languages in their native name $languages = Language::fetchLanguageNames(null, 'mwfile'); ksort($languages); $options = array(); foreach ($languages as $code => $name) { $options["{$code} - {$name}"] = $code; } $formDescriptor = array('language' => array('type' => 'select', 'label-message' => 'sd-admin-select-language', 'required' => true, 'options' => $options, 'section' => 'section-chooselanguage')); $form = HTMLForm::factory('ooui', $formDescriptor, $this->getContext()); $form->setId('languageSelectionForm'); $form->setMessagePrefix('view-by-lang'); $form->setSubmitText(wfMessage('sd-admin-view-selected-language')->text()); // Callback function $form->setSubmitCallback(array($this, 'showSpellings')); $form->show(); }
/** * Take a code as input, and search a language name for it in * a given language via Language::fetchLanguageNames() or * else via the Babel language names CDB * * @param $code String: Code to get name for. * @param $language String: Code of language to attempt to get name in, * defaults to language of code. * @return String (name of language) or false (invalid language code). */ public static function getName($code, $language = null) { wfProfileIn(__METHOD__); global $wgBabelLanguageNamesCdb; // Get correct code, even though it should already be correct. $code = self::getCode($code); if ($code === false) { wfProfileOut(__METHOD__); return false; } $language = $language === null ? $code : $language; $names = Language::fetchLanguageNames($language, 'all'); if (isset($names[$code])) { wfProfileOut(__METHOD__); return $names[$code]; } $codes = false; try { $namesCdb = CdbReader::open($wgBabelLanguageNamesCdb); $codes = $namesCdb->get($code); } catch (CdbException $e) { wfDebug(__METHOD__ . ": CdbException caught, error message was " . $e->getMessage()); } wfProfileOut(__METHOD__); return $codes; }
public function validSpecialPageAliasesProvider() { $codes = array_keys(Language::fetchLanguageNames('mwfile')); $data = []; foreach ($codes as $code) { $specialPageAliases = $this->getSpecialPageAliases($code); if ($specialPageAliases !== []) { $data[] = [$code, $specialPageAliases]; } } return $data; }
/** * This is horribly inefficient. Subclasses have more efficient * implementation of this. */ public function fetchDirectory($pattern) { $files = array(); $languages = Language::fetchLanguageNames(null, 'mwfile'); foreach (array_keys($languages) as $code) { // Hack for core if (strpos($pattern, 'Messages*.php') !== false) { $code = ucfirst(strtr($code, '-', '_')); } $url = str_replace('*', $code, $pattern); $file = $this->fetchFile($url); if ($file) { $files[$url] = $file; } } return $files; }
/** * JavsScript selector for language codes. * @return JsSelectToInput */ protected static function languageSelector() { if (is_callable(array('LanguageNames', 'getNames'))) { $lang = RequestContext::getMain()->getLanguage(); $languages = LanguageNames::getNames($lang->getCode(), LanguageNames::FALLBACK_NORMAL); } else { $languages = Language::fetchLanguageNames(); } ksort($languages); $selector = new XmlSelect('mw-language-selector', 'mw-language-selector'); foreach ($languages as $code => $name) { $selector->addOption("{$code} - {$name}", $code); } $jsSelect = new JsSelectToInput($selector); $jsSelect->setSourceId('mw-language-selector'); return $jsSelect; }
/** * 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__); } }
protected function getFormFields() { // Get default from the subpage of Special page $defaultName = $this->par; $page = array(); $page['pagename'] = array('type' => 'text', 'label-message' => 'pagelang-name', 'default' => $defaultName); // Options for whether to use the default language or select language $selectoptions = array((string) $this->msg('pagelang-use-default')->escaped() => 1, (string) $this->msg('pagelang-select-lang')->escaped() => 2); $page['selectoptions'] = array('id' => 'mw-pl-options', 'type' => 'radio', 'options' => $selectoptions, 'default' => 1); // Building a language selector $userLang = $this->getLanguage()->getCode(); $languages = Language::fetchLanguageNames($userLang, 'mwfile'); ksort($languages); $options = array(); foreach ($languages as $code => $name) { $options["{$code} - {$name}"] = $code; } $page['language'] = array('id' => 'mw-pl-languageselector', 'cssclass' => 'mw-languageselector', 'type' => 'select', 'options' => $options, 'label-message' => 'pagelang-language', 'default' => $this->getConfig()->get('LanguageCode')); return $page; }
/** * Constructor * * @param Language $langobj * @param string $maincode The main language code of this language * @param array $variants The supported variants of this language * @param array $variantfallbacks The fallback language of each variant * @param array $flags Defining the custom strings that maps to the flags * @param array $manualLevel Limit for supported variants */ public function __construct($langobj, $maincode, $variants = [], $variantfallbacks = [], $flags = [], $manualLevel = []) { global $wgDisabledVariants; $this->mLangObj = $langobj; $this->mMainLanguageCode = $maincode; $this->mVariants = array_diff($variants, $wgDisabledVariants); $this->mVariantFallbacks = $variantfallbacks; $this->mVariantNames = Language::fetchLanguageNames(); $this->mCacheKey = wfMemcKey('conversiontables', $maincode); $defaultflags = ['A' => 'A', 'T' => 'T', 'R' => 'R', 'D' => 'D', '-' => '-', 'H' => 'H', 'N' => 'N']; $this->mFlags = array_merge($defaultflags, $flags); foreach ($this->mVariants as $v) { if (array_key_exists($v, $manualLevel)) { $this->mManualLevel[$v] = $manualLevel[$v]; } else { $this->mManualLevel[$v] = 'bidirectional'; } $this->mFlags[$v] = $v; } }
protected function getFormFields() { $par = $this->par; $request = $this->getRequest(); $formDescriptor = array(); $formDescriptor['dbname'] = array('label-message' => 'createwiki-label-dbname', 'type' => 'text', 'default' => $request->getVal('cwDBname') ? $request->getVal('cwDBname') : $par, 'size' => 20, 'required' => true, 'validation-callback' => array(__CLASS__, 'validateDBname'), 'name' => 'cwDBname'); $formDescriptor['founder'] = array('label-message' => 'createwiki-label-founder', 'type' => 'text', 'default' => $request->getVal('cwFounder'), 'size' => 20, 'required' => true, 'validation-callback' => array(__CLASS__, 'validateFounder'), 'name' => 'cwFounder'); $formDescriptor['sitename'] = array('label-message' => 'createwiki-label-sitename', 'type' => 'text', 'default' => $request->getVal('cwSitename'), 'size' => 20, 'name' => 'cwSitename'); // Building a language selector (attribution: // includes/specials/SpecialPageLanguage.php L68) $languages = Language::fetchLanguageNames(null, 'mwfile'); ksort($languages); $options = array(); foreach ($languages as $code => $name) { $options["{$code} - {$name}"] = $code; } $formDescriptor['language'] = array('type' => 'select', 'options' => $options, 'label-message' => 'createwiki-label-language', 'default' => $request->getVal('cwLanguage') ? $request->getVal('cwLanguage') : 'en', 'name' => 'cwLanguage'); $formDescriptor['private'] = array('type' => 'check', 'label-message' => 'createwiki-label-private', 'name' => 'cwPrivate'); $formDescriptor['reason'] = array('label-message' => 'createwiki-label-reason', 'type' => 'text', 'default' => $request->getVal('wpreason'), 'size' => 45, 'required' => true); return $formDescriptor; }
function showWikiForm($wiki) { $out = $this->getOutput(); $wiki = $this->lookupWikiDetails($wiki); if (!$wiki) { $out->addHTML('<div class="errorbox">' . wfMessage('managewiki-missing')->escaped() . '</div>'); return false; } if (!$this->getRequest()->wasPosted()) { $out->addWikiMsg('managewiki-header', $wiki->wiki_dbname); } $languages = Language::fetchLanguageNames(null, 'mwfile'); ksort($languages); $options = array(); foreach ($languages as $code => $name) { $options["{$code} - {$name}"] = $code; } $formDescriptor = array('dbname' => array('label-message' => 'managewiki-label-dbname', 'type' => 'text', 'size' => 20, 'default' => $wiki->wiki_dbname, 'disabled' => true, 'name' => 'mwDBname'), 'sitename' => array('label-message' => 'managewiki-label-sitename', 'type' => 'text', 'size' => 20, 'default' => $wiki->wiki_sitename, 'required' => true, 'name' => 'mwSitename'), 'language' => array('label-message' => 'managewiki-label-language', 'type' => 'select', 'default' => $wiki->wiki_language, 'options' => $options, 'name' => 'mwLanguage'), 'closed' => array('type' => 'check', 'label-message' => 'managewiki-label-closed', 'name' => 'cwClosed', 'default' => $wiki->wiki_closed == 1 ? 1 : 0), 'private' => array('type' => 'check', 'label-message' => 'managewiki-label-private', 'name' => 'cwPrivate', 'disabled' => !$this->getUser()->isAllowed('managewiki-restricted'), 'default' => $wiki->wiki_private == 1 ? 1 : 0), 'reason' => array('label-message' => 'managewiki-label-reason', 'type' => 'text', 'size' => 45, 'required' => true)); $htmlForm = HTMLForm::factory('ooui', $formDescriptor, $this->getContext(), 'changeForm'); $htmlForm->setMethod('post')->setSubmitCallback(array($this, 'onSubmitInput'))->prepareForm()->show(); }
/** * Take a code as input, and search a language name for it in * a given language via Language::fetchLanguageNames() or * else via the Babel language names CDB * * @param $code String: Code to get name for. * @param $language String: Code of language to attempt to get name in, * defaults to language of code. * @return String (name of language) or false (invalid language code). */ public static function getName($code, $language = null) { wfProfileIn(__METHOD__); global $wgBabelLanguageNamesCdb; // Get correct code, even though it should already be correct. $code = self::getCode($code); if ($code === false) { wfProfileOut(__METHOD__); return false; } $language = $language === null ? $code : $language; $names = Language::fetchLanguageNames($language, 'all'); if (isset($names[$code])) { wfProfileOut(__METHOD__); return $names[$code]; } $namesCdb = CdbReader::open($wgBabelLanguageNamesCdb); $codes = $namesCdb->get($code); wfProfileOut(__METHOD__); return $codes; }
/** * Shows the page to the user. * @param string $sub: The subpage string argument (if any). * [[Special:SpellingDictionary/subpage]]. */ public function execute($sub) { $out = $this->getOutput(); $out->setPageTitle($this->msg('title-special')); // Parses message from .i18n.php as wikitext and adds it to the // page output. $out->addWikiMsg('intro-paragraph'); // Building a language selector // Display languages in their native name $languages = Language::fetchLanguageNames(null, 'mwfile'); ksort($languages); $options = array(); foreach ($languages as $code => $name) { $options["{$code} - {$name}"] = $code; } $formDescriptor = array('word' => array('type' => 'text', 'label-message' => 'spell-dict-word', 'required' => true), 'language' => array('type' => 'select', 'label-message' => 'spell-dict-language', 'required' => true, 'options' => $options)); $form = HTMLForm::factory('vform', $formDescriptor, $this->getContext()); $form->setSubmitText(wfMessage('add-word-form-submit')->text()); //Callback function $form->setSubmitCallback(array('SpecialSpellingDictionary', 'store')); $form->show(); }
/** * Returns an array of languages that the page is available in * @return array */ private function getLanguages() { $api = new ApiMain(new DerivativeRequest($this->getRequest(), array('action' => 'query', 'prop' => 'langlinks', 'llprop' => 'url', 'lllimit' => 'max', 'titles' => $this->title->getPrefixedText()))); $api->execute(); if (defined('ApiResult::META_CONTENT')) { $data = (array) $api->getResult()->getResultData(array('query', 'pages'), array('Strip' => 'all')); } else { $data = $api->getResult()->getData(); // Paranoia if (!isset($data['query']['pages'])) { return array(); } $data = $data['query']['pages']; } // Silly strict php $pages = array_values($data); $page = array_shift($pages); if (isset($page['langlinks'])) { // Set the name of each lanugage based on the system list of language names $languageMap = Language::fetchLanguageNames(); $languages = $page['langlinks']; foreach ($page['langlinks'] as $code => $langObject) { if (!isset($languageMap[$langObject['lang']])) { // Bug T93500: DB might still have preantiquated rows with bogus languages unset($languages[$code]); continue; } $langObject['langname'] = $languageMap[$langObject['lang']]; $langObject['url'] = MobileContext::singleton()->getMobileUrl($langObject['url']); $languages[$code] = $langObject; } return $languages; } else { // No langlinks available return array(); } }
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); }
public function execute($par) { $out = $this->getOutput(); $lang = $this->getLanguage(); // Only for manual debugging nowdays $this->purge = false; $this->setHeaders(); $out->addModules('ext.translate.special.supportedlanguages'); TranslateUtils::addSpecialHelpLink($out, 'Help:Extension:Translate/Statistics_and_reporting#List_of_languages_and_translators'); $this->outputHeader(); $dbr = wfGetDB(DB_SLAVE); if ($dbr->getType() === 'sqlite') { $out->addWikiText('<div class=errorbox>SQLite is not supported.</div>'); return; } $out->addWikiMsg('supportedlanguages-localsummary'); $names = Language::fetchLanguageNames(null, 'all'); $languages = $this->languageCloud(); // There might be all sorts of subpages which are not languages $languages = array_intersect_key($languages, $names); $this->outputLanguageCloud($languages, $names); $out->addWikiMsg('supportedlanguages-count', $lang->formatNum(count($languages))); if ($par && Language::isKnownLanguageTag($par)) { $code = $par; $out->addWikiMsg('supportedlanguages-colorlegend', $this->getColorLegend()); $users = $this->fetchTranslators($code); if ($users === false) { // generic-pool-error is from MW core $out->wrapWikiMsg('<div class="warningbox">$1</div>', 'generic-pool-error'); return; } global $wgTranslateAuthorBlacklist; $users = $this->filterUsers($users, $code, $wgTranslateAuthorBlacklist); $this->preQueryUsers($users); $this->showLanguage($code, $users); } }
/** * Clear all stored messages. Mainly used after a mass rebuild. */ function clear() { $langs = Language::fetchLanguageNames(null, 'mw'); foreach (array_keys($langs) as $code) { # Global and local caches $this->wanCache->touchCheckKey(wfMemcKey('messages', $code)); } $this->mLoadedLanguages = array(); }
/** * Update the MediaWiki Core Messages. * * @param $verbose Boolean * * @return Integer: the amount of updated messages */ public static function updateMediawikiMessages($verbose, $coreUrl) { // Find the changed English strings (as these messages won't be updated in ANY language). $localUrl = Language::getMessagesFileName('en'); $repoUrl = str_replace('$2', 'languages/messages/MessagesEn.php', $coreUrl); $changedEnglishStrings = self::compareFiles($repoUrl, $localUrl, $verbose); // Count the changes. $changedCount = 0; $languages = Language::fetchLanguageNames(null, 'mwfile'); foreach (array_keys($languages) as $code) { $localUrl = Language::getMessagesFileName($code); // Not prefixed with $IP $filename = Language::getFilename('languages/messages/Messages', $code); $repoUrl = str_replace('$2', $filename, $coreUrl); // Compare the files. $changedCount += self::compareFiles($repoUrl, $localUrl, $verbose, $changedEnglishStrings, false, true); } // Log some nice info. self::myLog("{$changedCount} MediaWiki messages are updated"); return $changedCount; }
/** * Return a Language object from $langcode * * @param Language|string|bool $langcode Either: * - a Language object * - code of the language to get the message for, if it is * a valid code create a language for that language, if * it is a string but not a valid code then make a basic * language object * - a boolean: if it's false then use the global object for * the current user's language (as a fallback for the old parameter * functionality), or if it is true then use global object * for the wiki's content language. * @return Language */ function wfGetLangObj($langcode = false) { # Identify which language to get or create a language object for. # Using is_object here due to Stub objects. if (is_object($langcode)) { # Great, we already have the object (hopefully)! return $langcode; } global $wgContLang, $wgLanguageCode; if ($langcode === true || $langcode === $wgLanguageCode) { # $langcode is the language code of the wikis content language object. # or it is a boolean and value is true return $wgContLang; } global $wgLang; if ($langcode === false || $langcode === $wgLang->getCode()) { # $langcode is the language code of user language object. # or it was a boolean and value is false return $wgLang; } $validCodes = array_keys(Language::fetchLanguageNames()); if (in_array($langcode, $validCodes)) { # $langcode corresponds to a valid language. return Language::factory($langcode); } # $langcode is a string, but not a valid language code; use content language. wfDebug("Invalid language code passed to wfGetLangObj, falling back to content language.\n"); return $wgContLang; }
/** * Parses list of language codes to an array. * @param string $codes Comma separated list of language codes. "*" for all. * @return string[] Language codes. */ public static function parseLanguageCodes($codes) { $langs = array_map('trim', explode(',', $codes)); if ($langs[0] === '*') { $languages = Language::fetchLanguageNames(); ksort($languages); $langs = array_keys($languages); } return $langs; }
/** * @param $context ResourceLoaderContext * @return array */ protected function getData(ResourceLoaderContext $context) { return Language::fetchLanguageNames($context->getLanguage(), 'all'); }
protected function getLangLinks($title) { $apiParams = array('action' => 'query', 'prop' => 'langlinks', 'lllimit' => 500, 'titles' => $title->getPrefixedDBkey(), 'indexpageids' => 1); $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), true); $api->execute(); if (defined('ApiResult::META_CONTENT')) { $result = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array(), 'Strip' => 'all')); } else { $result = $api->getResultData(); } if (!isset($result['query']['pages'][$title->getArticleID()]['langlinks'])) { return false; } $langlinks = $result['query']['pages'][$title->getArticleID()]['langlinks']; $langnames = Language::fetchLanguageNames(); foreach ($langlinks as $i => $lang) { $langlinks[$i]['langname'] = $langnames[$langlinks[$i]['lang']]; } return $langlinks; }
/** * Get a "<select>" for selecting languages. * * @param string $name * @param string $label * @param string $selectedCode * @param string $helpHtml * * @return string */ public function getLanguageSelector($name, $label, $selectedCode, $helpHtml = '') { global $wgDummyLanguageCodes; $output = $helpHtml; $select = new XmlSelect($name, $name, $selectedCode); $select->setAttribute('tabindex', $this->parent->nextTabIndex()); $languages = Language::fetchLanguageNames(); ksort($languages); foreach ($languages as $code => $lang) { if (isset($wgDummyLanguageCodes[$code])) { continue; } $select->addOption("{$code} - {$lang}", $code); } $output .= $select->getHTML(); return $this->parent->label($label, $name, $output); }
/** * Retrieves MediaWiki language from Accept-Language HTTP header. * * @return string */ public function getAcceptLanguage() { global $wgLanguageCode, $wgRequest; $mwLanguages = Language::fetchLanguageNames(); $headerLanguages = array_keys($wgRequest->getAcceptLang()); foreach ($headerLanguages as $lang) { if (isset($mwLanguages[$lang])) { return $lang; } } return $wgLanguageCode; }
/** * Clear all stored messages. Mainly used after a mass rebuild. */ function clear() { $langs = Language::fetchLanguageNames(null, 'mw'); foreach (array_keys($langs) as $code) { # Global cache $this->mMemc->delete(wfMemcKey('messages', $code)); # Invalidate all local caches $this->mMemc->delete(wfMemcKey('messages', $code, 'hash')); } $this->mLoadedLanguages = array(); }
/** * Construct a language selector appropriate for use in a form or preferences * * @param string $selected The language code of the selected language * @param bool $customisedOnly If true only languages which have some content are listed * @param string $inLanguage The ISO code of the language to display the select list in (optional) * @param array $overrideAttrs Override the attributes of the select tag (since 1.20) * @param Message|null $msg Label message key (since 1.20) * @return array Array containing 2 items: label HTML and select list HTML */ public static function languageSelector($selected, $customisedOnly = true, $inLanguage = null, $overrideAttrs = array(), Message $msg = null) { global $wgLanguageCode; $include = $customisedOnly ? 'mwfile' : 'mw'; $languages = Language::fetchLanguageNames($inLanguage, $include); // Make sure the site language is in the list; // a custom language code might not have a defined name... if (!array_key_exists($wgLanguageCode, $languages)) { $languages[$wgLanguageCode] = $wgLanguageCode; } ksort($languages); /** * If a bogus value is set, default to the content language. * Otherwise, no default is selected and the user ends up * with Afrikaans since it's first in the list. */ $selected = isset($languages[$selected]) ? $selected : $wgLanguageCode; $options = "\n"; foreach ($languages as $code => $name) { $options .= Xml::option("{$code} - {$name}", $code, $code == $selected) . "\n"; } $attrs = array('id' => 'wpUserLanguage', 'name' => 'wpUserLanguage'); $attrs = array_merge($attrs, $overrideAttrs); if ($msg === null) { $msg = wfMessage('yourlanguage'); } return array(Xml::label($msg->text(), $attrs['id']), Xml::tags('select', $attrs, $options)); }
/** * @param $user User * @param $context IContextSource * @param $defaultPreferences * @return void */ static function profilePreferences( $user, IContextSource $context, &$defaultPreferences ) { global $wgAuth, $wgContLang, $wgParser, $wgCookieExpiration, $wgLanguageCode, $wgDisableTitleConversion, $wgDisableLangConversion, $wgMaxSigChars, $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication, $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress, $wgSecureLogin; // retrieving user name for GENDER and misc. $userName = $user->getName(); ## User info ##################################### // Information panel $defaultPreferences['username'] = array( 'type' => 'info', 'label-message' => array( 'username', $userName ), 'default' => $userName, 'section' => 'personal/info', ); $defaultPreferences['userid'] = array( 'type' => 'info', 'label-message' => array( 'uid', $userName ), 'default' => $user->getId(), 'section' => 'personal/info', ); # Get groups to which the user belongs $userEffectiveGroups = $user->getEffectiveGroups(); $userGroups = $userMembers = array(); foreach ( $userEffectiveGroups as $ueg ) { if ( $ueg == '*' ) { // Skip the default * group, seems useless here continue; } $groupName = User::getGroupName( $ueg ); $userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName ); $memberName = User::getGroupMember( $ueg, $userName ); $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName ); } asort( $userGroups ); asort( $userMembers ); $lang = $context->getLanguage(); $defaultPreferences['usergroups'] = array( 'type' => 'info', 'label' => $context->msg( 'prefs-memberingroups' )->numParams( count( $userGroups ) )->params( $userName )->parse(), 'default' => $context->msg( 'prefs-memberingroups-type', $lang->commaList( $userGroups ), $lang->commaList( $userMembers ) )->plain(), 'raw' => true, 'section' => 'personal/info', ); $editCount = Linker::link( SpecialPage::getTitleFor( "Contributions", $userName ), $lang->formatNum( $user->getEditCount() ) ); $defaultPreferences['editcount'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'prefs-edits', 'default' => $editCount, 'section' => 'personal/info', ); if ( $user->getRegistration() ) { $displayUser = $context->getUser(); $userRegistration = $user->getRegistration(); $defaultPreferences['registrationdate'] = array( 'type' => 'info', 'label-message' => 'prefs-registration', 'default' => $context->msg( 'prefs-registration-date-time', $lang->userTimeAndDate( $userRegistration, $displayUser ), $lang->userDate( $userRegistration, $displayUser ), $lang->userTime( $userRegistration, $displayUser ) )->parse(), 'section' => 'personal/info', ); } $canViewPrivateInfo = $user->isAllowed( 'viewmyprivateinfo' ); $canEditPrivateInfo = $user->isAllowed( 'editmyprivateinfo' ); // Actually changeable stuff $defaultPreferences['realname'] = array( // (not really "private", but still shouldn't be edited without permission) 'type' => $canEditPrivateInfo && $wgAuth->allowPropChange( 'realname' ) ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname', ); if ( $canEditPrivateInfo && $wgAuth->allowPasswordChange() ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangePassword' ), $context->msg( 'prefs-resetpass' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $defaultPreferences['password'] = array( 'type' => 'info', 'raw' => true, 'default' => $link, 'label-message' => 'yourpassword', 'section' => 'personal/info', ); } if ( $wgCookieExpiration > 0 ) { $defaultPreferences['rememberpassword'] = array( 'type' => 'toggle', 'label' => $context->msg( 'tog-rememberpassword' )->numParams( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) )->text(), 'section' => 'personal/info', ); } // Only show preferhttps if secure login is turned on if ( $wgSecureLogin && wfCanIPUseHTTPS( $context->getRequest()->getIP() ) ) { $defaultPreferences['prefershttps'] = array( 'type' => 'toggle', 'label-message' => 'tog-prefershttps', 'help-message' => 'prefs-help-prefershttps', 'section' => 'personal/info' ); } // Language $languages = Language::fetchLanguageNames( null, 'mw' ); if ( !array_key_exists( $wgLanguageCode, $languages ) ) { $languages[$wgLanguageCode] = $wgLanguageCode; } ksort( $languages ); $options = array(); foreach ( $languages as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['language'] = array( 'type' => 'select', 'section' => 'personal/i18n', 'options' => $options, 'label-message' => 'yourlanguage', ); $defaultPreferences['gender'] = array( 'type' => 'radio', 'section' => 'personal/i18n', 'options' => array( $context->msg( 'parentheses', $context->msg( 'gender-unknown' )->text() )->text() => 'unknown', $context->msg( 'gender-female' )->text() => 'female', $context->msg( 'gender-male' )->text() => 'male', ), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender', ); // see if there are multiple language variants to choose from if ( !$wgDisableLangConversion ) { foreach ( LanguageConverter::$languagesWithVariants as $langCode ) { if ( $langCode == $wgContLang->getCode() ) { $variants = $wgContLang->getVariants(); if ( count( $variants ) <= 1 ) { continue; } $variantArray = array(); foreach ( $variants as $v ) { $v = str_replace( '_', '-', strtolower( $v ) ); $variantArray[$v] = $lang->getVariantname( $v, false ); } $options = array(); foreach ( $variantArray as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['variant'] = array( 'label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n', 'help-message' => 'prefs-help-variant', ); if ( !$wgDisableTitleConversion ) { $defaultPreferences['noconvertlink'] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink', ); } } else { $defaultPreferences["variant-$langCode"] = array( 'type' => 'api', ); } } } // Stuff from Language::getExtraUserToggles() // FIXME is this dead code? $extraUserToggles doesn't seem to be defined for any language $toggles = $wgContLang->getExtraUserToggles(); foreach ( $toggles as $toggle ) { $defaultPreferences[$toggle] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => "tog-$toggle", ); } // show a preview of the old signature first $oldsigWikiText = $wgParser->preSaveTransform( "~~~", $context->getTitle(), $user, ParserOptions::newFromContext( $context ) ); $oldsigHTML = $context->getOutput()->parseInline( $oldsigWikiText, true, true ); $defaultPreferences['oldsig'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'tog-oldsig', 'default' => $oldsigHTML, 'section' => 'personal/signature', ); $defaultPreferences['nickname'] = array( 'type' => $wgAuth->allowPropChange( 'nickname' ) ? 'text' : 'info', 'maxlength' => $wgMaxSigChars, 'label-message' => 'yournick', 'validation-callback' => array( 'Preferences', 'validateSignature' ), 'section' => 'personal/signature', 'filter-callback' => array( 'Preferences', 'cleanSignature' ), ); $defaultPreferences['fancysig'] = array( 'type' => 'toggle', 'label-message' => 'tog-fancysig', 'help-message' => 'prefs-help-signature', // show general help about signature at the bottom of the section 'section' => 'personal/signature' ); ## Email stuff if ( $wgEnableEmail ) { if ( $canViewPrivateInfo ) { $helpMessages[] = $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email'; if ( $wgEnableUserEmail ) { // additional messages when users can send email to each other $helpMessages[] = 'prefs-help-email-others'; } $emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : ''; if ( $canEditPrivateInfo && $wgAuth->allowPropChange( 'emailaddress' ) ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangeEmail' ), $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $emailAddress .= $emailAddress == '' ? $link : ( $context->msg( 'word-separator' )->plain() . $context->msg( 'parentheses' )->rawParams( $link )->plain() ); } $defaultPreferences['emailaddress'] = array( 'type' => 'info', 'raw' => true, 'default' => $emailAddress, 'label-message' => 'youremail', 'section' => 'personal/email', 'help-messages' => $helpMessages, # 'cssclass' chosen below ); } $disableEmailPrefs = false; if ( $wgEmailAuthentication ) { $emailauthenticationclass = 'mw-email-not-authenticated'; if ( $user->getEmail() ) { if ( $user->getEmailAuthenticationTimestamp() ) { // date and time are separate parameters to facilitate localisation. // $time is kept for backward compat reasons. // 'emailauthenticated' is also used in SpecialConfirmemail.php $displayUser = $context->getUser(); $emailTimestamp = $user->getEmailAuthenticationTimestamp(); $time = $lang->userTimeAndDate( $emailTimestamp, $displayUser ); $d = $lang->userDate( $emailTimestamp, $displayUser ); $t = $lang->userTime( $emailTimestamp, $displayUser ); $emailauthenticated = $context->msg( 'emailauthenticated', $time, $d, $t )->parse() . '<br />'; $disableEmailPrefs = false; $emailauthenticationclass = 'mw-email-authenticated'; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '<br />' . Linker::linkKnown( SpecialPage::getTitleFor( 'Confirmemail' ), $context->msg( 'emailconfirmlink' )->escaped() ) . '<br />'; $emailauthenticationclass = "mw-email-not-authenticated"; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'noemailprefs' )->escaped(); $emailauthenticationclass = 'mw-email-none'; } if ( $canViewPrivateInfo ) { $defaultPreferences['emailauthentication'] = array( 'type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated, # Apply the same CSS class used on the input to the message: 'cssclass' => $emailauthenticationclass, ); $defaultPreferences['emailaddress']['cssclass'] = $emailauthenticationclass; } } if ( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) { $defaultPreferences['disablemail'] = array( 'type' => 'toggle', 'invert' => true, 'section' => 'personal/email', 'label-message' => 'allowemail', 'disabled' => $disableEmailPrefs, ); $defaultPreferences['ccmeonemails'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-ccmeonemails', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifWatchlist ) { $defaultPreferences['enotifwatchlistpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifwatchlistpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk ) { $defaultPreferences['enotifusertalkpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifusertalkpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk || $wgEnotifWatchlist ) { $defaultPreferences['enotifminoredits'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifminoredits', 'disabled' => $disableEmailPrefs, ); if ( $wgEnotifRevealEditorAddress ) { $defaultPreferences['enotifrevealaddr'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifrevealaddr', 'disabled' => $disableEmailPrefs, ); } } } }
public function execute() { global $wgLocalisationCacheConf; $force = $this->hasOption('force'); $threads = $this->getOption('threads', 1); if ($threads < 1 || $threads != intval($threads)) { $this->output("Invalid thread count specified; running single-threaded.\n"); $threads = 1; } if ($threads > 1 && wfIsWindows()) { $this->output("Threaded rebuild is not supported on Windows; running single-threaded.\n"); $threads = 1; } if ($threads > 1 && !function_exists('pcntl_fork')) { $this->output("PHP pcntl extension is not present; running single-threaded.\n"); $threads = 1; } $conf = $wgLocalisationCacheConf; $conf['manualRecache'] = false; // Allow fallbacks to create CDB files if ($force) { $conf['forceRecache'] = true; } if ($this->hasOption('outdir')) { $conf['storeDirectory'] = $this->getOption('outdir'); } $lc = new LocalisationCacheBulkLoad($conf); $allCodes = array_keys(Language::fetchLanguageNames(null, 'mwfile')); if ($this->hasOption('lang')) { # Validate requested languages $codes = array_intersect($allCodes, explode(',', $this->getOption('lang'))); # Bailed out if nothing is left if (count($codes) == 0) { $this->error('None of the languages specified exists.', 1); } } else { # By default get all languages $codes = $allCodes; } sort($codes); // Initialise and split into chunks $numRebuilt = 0; $total = count($codes); $chunks = array_chunk($codes, ceil(count($codes) / $threads)); $pids = array(); $parentStatus = 0; foreach ($chunks as $codes) { // Do not fork for only one thread $pid = $threads > 1 ? pcntl_fork() : -1; if ($pid === 0) { // Child, reseed because there is no bug in PHP: // http://bugs.php.net/bug.php?id=42465 mt_srand(getmypid()); $this->doRebuild($codes, $lc, $force); exit(0); } elseif ($pid === -1) { // Fork failed or one thread, do it serialized $numRebuilt += $this->doRebuild($codes, $lc, $force); } else { // Main thread $pids[] = $pid; } } // Wait for all children foreach ($pids as $pid) { $status = 0; pcntl_waitpid($pid, $status); if (pcntl_wexitstatus($status)) { // Pass a fatal error code through to the caller $parentStatus = pcntl_wexitstatus($status); } } if (!$pids) { $this->output("{$numRebuilt} languages rebuilt out of {$total}\n"); if ($numRebuilt === 0) { $this->output("Use --force to rebuild the caches which are still fresh.\n"); } } if ($parentStatus) { exit($parentStatus); } }