/** * test @see wfBCP47(). * Please note the BCP 47 explicitly state that language codes are case * insensitive, there are some exceptions to the rule :) * This test is used to verify our formatting against all lower and * all upper cases language code. * * @see http://tools.ietf.org/html/bcp47 * @dataProvider provideLanguageCodes() */ public function testBCP47($code, $expected) { $code = strtolower($code); $this->assertEquals($expected, wfBCP47($code), "Applying BCP47 standard to lower case '{$code}'"); $code = strtoupper($code); $this->assertEquals($expected, wfBCP47($code), "Applying BCP47 standard to upper case '{$code}'"); }
static function onBeforePageDisplay(OutputPage &$out, Skin &$skin) { $languageLinks = $out->getLanguageLinks(); if (empty($languageLinks)) { return true; } // this is partly a ripoff from SkinTemplate::getLanguages() foreach ($languageLinks as $langLink) { $languageLinkTitle = Title::newFromText($langLink); $interwikiCode = $languageLinkTitle->getInterwiki(); $out->addLink(array('rel' => 'alternate', 'hreflang' => wfBCP47($interwikiCode), 'href' => wfExpandIRI($languageLinkTitle->getFullURL()))); } // We also must add the current language $currentPageLangCode = $out->getLanguage()->getCode(); $currentPageTitle = $out->getTitle(); $out->addLink(array('rel' => 'alternate', 'hreflang' => wfBCP47($currentPageLangCode), 'href' => wfExpandIRI($currentPageTitle->getFullURL()))); return true; }
public static function onBeforePageDisplay(OutputPage $out, SkinTemplate $sk) { $config = $out->getConfig(); if (self::canOutputHreflang($config)) { # Generate hreflang tags $languageLinks = $out->getLanguageLinks(); if (empty($languageLinks)) { // shortcut - if we don't have any language links, don't bother return; } $addedLink = false; $pages = $config->get("HreflangPages"); if (!$pages) { $pages = array(); $foundPage = true; } else { $pages = array_flip($pages); $pageName = $out->getLanguage()->getHtmlCode() . ":" . $out->getTitle()->getBaseText(); $foundPage = isset($pages[$pageName]); } foreach ($languageLinks as $languageLinkText) { $languageLinkTitle = Title::newFromText($languageLinkText); if (!$languageLinkTitle) { continue; } $ilInterwikiCode = $languageLinkTitle->getInterwiki(); if (!Language::isKnownLanguageTag($ilInterwikiCode)) { continue; } $foundPage = $foundPage || isset($pages[$languageLinkText]); $tags[] = Html::element('link', array('rel' => 'alternate', 'hreflang' => wfBCP47($ilInterwikiCode), 'href' => $languageLinkTitle->getFullURL())); $addedLink = true; } // Only add current language link if we had any other links if ($addedLink) { $tags[] = Html::element('link', array('rel' => 'alternate', 'hreflang' => $out->getLanguage()->getHtmlCode(), 'href' => $out->getTitle()->getFullURL())); } } if ($foundPage && $tags) { $out->addHeadItem("hreflang:tags", join("\n", $tags)); } }
/** * Returns an array of language variants that the page is available in * @return array */ private function getLanguageVariants() { $pageLang = $this->title->getPageLanguage(); $variants = $pageLang->getVariants(); if (count($variants) > 1) { $pageLangCode = $pageLang->getCode(); $output = array(); // Loops over each variant foreach ($variants as $code) { // Gets variant name from language code $varname = $pageLang->getVariantname($code); // Don't list the current variant if ($varname !== $pageLangCode) { // Appends variant link $output[] = array('langname' => $varname, 'url' => $this->title->getLocalURL(array('variant' => $code)), 'lang' => wfBCP47($code)); } } return $output; } else { // No variants return array(); } }
protected function mapCode($code) { return str_replace('-', '_', wfBCP47($code)); }
/** * Outputs a form to edit the story with. Code based on <storysubmission>. * * @param $story */ private function showStoryForm($story) { global $wgOut, $wgLang, $wgRequest, $wgUser, $wgScriptPath, $wgContLanguageCode; global $egStoryboardScriptPath, $egStorysubmissionWidth, $egStoryboardMaxStoryLen, $egStoryboardMinStoryLen; $wgOut->setPageTitle($story->story_title); efStoryboardAddJSLocalisation(); $wgOut->addStyle($egStoryboardScriptPath . '/storyboard.css'); $wgOut->includeJQuery(); $wgOut->addScriptFile($egStoryboardScriptPath . '/jquery/jquery.validate.js'); $wgOut->addScriptFile($egStoryboardScriptPath . '/storyboard.js'); $fieldSize = 50; $width = $egStorysubmissionWidth; $maxLen = $wgRequest->getVal('maxlength'); if (!is_int($maxLen)) { $maxLen = $egStoryboardMaxStoryLen; } $minLen = $wgRequest->getVal('minlength'); if (!is_int($minLen)) { $minLen = $egStoryboardMinStoryLen; } $formBody = "<table width=\"{$width}\">"; // The current value will be selected on page load with jQuery. $formBody .= '<tr>' . '<td width="100%"><label for="storystate">' . htmlspecialchars(wfMsg('storyboard-storystate')) . '</label></td><td>' . Html::rawElement('select', array('name' => 'storystate', 'id' => 'storystate'), '<option value="' . Storyboard_STORY_UNPUBLISHED . '">' . htmlspecialchars(wfMsg('storyboard-option-unpublished')) . '</option>' . '<option value="' . Storyboard_STORY_PUBLISHED . '">' . htmlspecialchars(wfMsg('storyboard-option-published')) . '</option>' . '<option value="' . Storyboard_STORY_HIDDEN . '">' . htmlspecialchars(wfMsg('storyboard-option-hidden')) . '</option>') . '</td></tr>'; $languages = Language::getLanguageNames(false); $currentLang = array_key_exists($story->story_lang_code, $languages) ? $story->story_lang_code : $wgContLanguageCode; $options = array(); ksort($languages); foreach ($languages as $code => $name) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } $languageSelector = new HTMLSelectField(array('name' => 'language', 'options' => $options)); $formBody .= '<tr>' . Html::element('td', array('width' => '100%'), wfMsg('storyboard-language')) . '<td>' . $languageSelector->getInputHTML($currentLang) . '</td></tr>'; $formBody .= '<tr>' . Html::element('td', array('width' => '100%'), wfMsg('storyboard-authorname')) . '<td>' . Html::input('name', $story->story_author_name, 'text', array('size' => $fieldSize, 'class' => 'required', 'minlength' => 2, 'maxlength' => 255)) . '</td></tr>'; $formBody .= '<tr>' . Html::element('td', array('width' => '100%'), wfMsg('storyboard-authorlocation')) . '<td>' . Html::input('location', $story->story_author_location, 'text', array('size' => $fieldSize, 'maxlength' => 255, 'minlength' => 2)) . '</td></tr>'; $formBody .= '<tr>' . Html::element('td', array('width' => '100%'), wfMsg('storyboard-authoroccupation')) . '<td>' . Html::input('occupation', $story->story_author_occupation, 'text', array('size' => $fieldSize, 'maxlength' => 255, 'minlength' => 4)) . '</td></tr>'; $formBody .= '<tr>' . Html::element('td', array('width' => '100%'), wfMsg('storyboard-authoremail')) . '<td>' . Html::input('email', $story->story_author_email, 'text', array('size' => $fieldSize, 'maxlength' => 255, 'class' => 'required email')) . '</td></tr>'; $formBody .= '<tr>' . '<td width="100%"><label for="storytitle">' . htmlspecialchars(wfMsg('storyboard-storytitle')) . '</label></td><td>' . Html::input('storytitle', $story->story_title, 'text', array('size' => $fieldSize, 'maxlength' => 255, 'minlength' => 2, 'id' => 'storytitle', 'class' => 'required storytitle', 'remote' => "{$wgScriptPath}/api.php?format=json&action=storyexists¤tid={$story->story_id}")) . '</td></tr>'; $formBody .= '<tr><td colspan="2">' . wfMsg('storyboard-thestory') . Html::element('div', array('class' => 'storysubmission-charcount', 'id' => 'storysubmission-charlimitinfo'), wfMsgExt('storyboard-charsneeded', 'parsemag', $minLen)) . '<br />' . Html::element('textarea', array('id' => 'storytext', 'name' => 'storytext', 'rows' => 7, 'class' => 'required', 'onkeyup' => "stbValidateStory( this, {$minLen}, {$maxLen}, 'storysubmission-charlimitinfo', 'storysubmission-button' )"), $story->story_text) . '</td></tr>'; $returnTo = $wgRequest->getVal('returnto'); $query = "id={$story->story_id}"; if ($returnTo) { $query .= "&returnto={$returnTo}"; } $formBody .= '<tr><td colspan="2">' . Html::input('', wfMsg('htmlform-submit'), 'submit', array('id' => 'storysubmission-button')) . "  <span class='editHelp'>" . Html::element('a', array('href' => $this->getTitle()->getLocalURL($query)), wfMsgExt('cancel', array('parseinline'))) . '</span>' . '</td></tr>'; $formBody .= '</table>'; $formBody .= Html::hidden('wpEditToken', $wgUser->editToken()); $formBody .= Html::hidden('storyId', $story->story_id); $formBody = '<fieldset><legend>' . htmlspecialchars(wfMsgExt('storyboard-createdandmodified', 'parsemag', $wgLang->time($story->story_created), $wgLang->date($story->story_created), $wgLang->time($story->story_modified), $wgLang->date($story->story_modified))) . '</legend>' . $formBody . '</fieldset>'; $query = "id={$story->story_id}"; if ($returnTo) { $query .= "&returnto={$returnTo}"; } $formBody = Html::rawElement('form', array('id' => 'storyform', 'name' => 'storyform', 'method' => 'post', 'action' => $this->getTitle()->getLocalURL($query)), $formBody); $wgOut->addHTML($formBody); $state = htmlspecialchars($story->story_state); $wgOut->addInlineScript(<<<EOT jQuery(document).ready(function() { \tjQuery('#storystate option[value="{$state}"]').attr('selected', 'selected'); \tjQuery("#storyform").validate({ \t\tmessages: { \t\t\tstorytitle: { \t\t\t\tremote: jQuery.validator.format( stbMsg( 'storyboard-alreadyexistschange' ) ) \t\t\t} \t\t} \t}); }); \$( \tfunction() { \t\tstbValidateStory( document.getElementById('storytext'), {$minLen}, {$maxLen}, 'storysubmission-charlimitinfo', 'storysubmission-button' ) \t} ); jQuery(document).ready(function(){ \tjQuery("#storyform").validate(); }); EOT ); }
public function execute($par) { global $wgLanguageCode; $this->setHeaders(); $this->checkPermissions(); $server = TTMServer::primary(); if (!$server instanceof SearchableTTMServer) { throw new ErrorPageError('tux-sst-nosolr-title', 'tux-sst-nosolr-body'); } $out = $this->getOutput(); $out->addModuleStyles('jquery.uls.grid'); $out->addModuleStyles('ext.translate.special.searchtranslations.styles'); $out->addModuleStyles('ext.translate.special.translate.styles'); $out->addModules('ext.translate.special.searchtranslations'); $out->addModules('ext.translate.special.searchtranslations.operatorsuggest'); TranslateUtils::addSpecialHelpLink($out, 'Help:Extension:Translate#searching'); $this->opts = $opts = new FormOptions(); $opts->add('query', ''); $opts->add('sourcelanguage', $wgLanguageCode); $opts->add('language', ''); $opts->add('group', ''); $opts->add('grouppath', ''); $opts->add('filter', ''); $opts->add('match', ''); $opts->add('case', ''); $opts->add('limit', $this->limit); $opts->add('offset', 0); $opts->fetchValuesFromRequest($this->getRequest()); $queryString = $opts->getValue('query'); if ($queryString === '') { $this->showEmptySearch(); return; } $params = $opts->getAllValues(); $filter = $opts->getValue('filter'); try { $translationSearch = new CrossLanguageTranslationSearchQuery($params, $server); if (in_array($filter, $translationSearch->getAvailableFilters())) { if ($opts->getValue('language') === '') { $params['language'] = $this->getLanguage()->getCode(); $opts->setValue('language', $params['language']); } $documents = $translationSearch->getDocuments(); $total = $translationSearch->getTotalHits(); $resultset = $translationSearch->getResultSet(); } else { $resultset = $server->search($queryString, $params, $this->hl); $documents = $server->getDocuments($resultset); $total = $server->getTotalHits($resultset); } } catch (TTMServerException $e) { error_log('Translation search server unavailable:' . $e->getMessage()); throw new ErrorPageError('tux-sst-solr-offline-title', 'tux-sst-solr-offline-body'); } // Part 1: facets $facets = $server->getFacets($resultset); $facetHtml = ''; if (count($facets['language']) > 0) { if ($filter !== '') { $facets['language'] = array_merge($facets['language'], array($opts->getValue('language') => $total)); } $facetHtml = Html::element('div', array('class' => 'row facet languages', 'data-facets' => FormatJson::encode($this->getLanguages($facets['language'])), 'data-language' => $opts->getValue('language')), $this->msg('tux-sst-facet-language')); } if (count($facets['group']) > 0) { $facetHtml .= Html::element('div', array('class' => 'row facet groups', 'data-facets' => FormatJson::encode($this->getGroups($facets['group'])), 'data-group' => $opts->getValue('group')), $this->msg('tux-sst-facet-group')); } // Part 2: results $resultsHtml = ''; $title = Title::newFromText($queryString); if ($title && !in_array($filter, $translationSearch->getAvailableFilters())) { $handle = new MessageHandle($title); $code = $handle->getCode(); $language = $opts->getValue('language'); if ($handle->isValid() && $code !== '' && $code !== $language) { $groupId = $handle->getGroup()->getId(); $helpers = new TranslationHelpers($title, $groupId); $document['wiki'] = wfWikiId(); $document['localid'] = $handle->getTitleForBase()->getPrefixedText(); $document['content'] = $helpers->getTranslation(); $document['language'] = $handle->getCode(); array_unshift($documents, $document); $total++; } } foreach ($documents as $document) { $text = $document['content']; $text = TranslateUtils::convertWhiteSpaceToHTML($text); list($pre, $post) = $this->hl; $text = str_replace($pre, '<strong class="tux-search-highlight">', $text); $text = str_replace($post, '</strong>', $text); $title = Title::newFromText($document['localid'] . '/' . $document['language']); if (!$title) { // Should not ever happen but who knows... continue; } $resultAttribs = array('class' => 'row tux-message', 'data-title' => $title->getPrefixedText(), 'data-language' => $document['language']); $handle = new MessageHandle($title); if ($handle->isValid()) { $groupId = $handle->getGroup()->getId(); $helpers = new TranslationHelpers($title, $groupId); $resultAttribs['data-definition'] = $helpers->getDefinition(); $resultAttribs['data-translation'] = $helpers->getTranslation(); $resultAttribs['data-group'] = $groupId; $uri = $title->getLocalUrl(array('action' => 'edit')); $link = Html::element('a', array('href' => $uri), $this->msg('tux-sst-edit')->text()); } else { $url = wfParseUrl($document['uri']); $domain = $url['host']; $link = Html::element('a', array('href' => $document['uri']), $this->msg('tux-sst-view-foreign', $domain)->text()); } $access = Html::rawElement('div', array('class' => 'row tux-edit tux-message-item'), $link); $titleText = $title->getPrefixedText(); $titleAttribs = array('class' => 'row tux-title', 'dir' => 'ltr'); $textAttribs = array('class' => 'row tux-text', 'lang' => wfBCP47($document['language']), 'dir' => Language::factory($document['language'])->getDir()); $resultsHtml = $resultsHtml . Html::openElement('div', $resultAttribs) . Html::rawElement('div', $textAttribs, $text) . Html::element('div', $titleAttribs, $titleText) . $access . Html::closeElement('div'); } $resultsHtml .= Html::rawElement('hr', array('class' => 'tux-pagination-line')); $prev = $next = ''; $offset = $this->opts->getValue('offset'); $params = $this->opts->getChangedValues(); if ($total - $offset > $this->limit) { $newParams = array('offset' => $offset + $this->limit) + $params; $attribs = array('class' => 'mw-ui-button pager-next', 'href' => $this->getPageTitle()->getLocalUrl($newParams)); $next = Html::element('a', $attribs, $this->msg('tux-sst-next')->text()); } if ($offset) { $newParams = array('offset' => max(0, $offset - $this->limit)) + $params; $attribs = array('class' => 'mw-ui-button pager-prev', 'href' => $this->getPageTitle()->getLocalUrl($newParams)); $prev = Html::element('a', $attribs, $this->msg('tux-sst-prev')->text()); } $resultsHtml .= Html::rawElement('div', array('class' => 'tux-pagination-links'), "{$prev} {$next}"); $search = $this->getSearchInput($queryString); $count = $this->msg('tux-sst-count')->numParams($total); $this->showSearch($search, $count, $facetHtml, $resultsHtml, $total); }
/** * @return array Array in format "link name or number => 'link html'". */ public function getHeadLinksArray() { global $wgVersion; $tags = array(); $config = $this->getConfig(); $canonicalUrl = $this->mCanonicalUrl; $tags['meta-generator'] = Html::element('meta', array('name' => 'generator', 'content' => "MediaWiki {$wgVersion}")); if ($config->get('ReferrerPolicy') !== false) { $tags['meta-referrer'] = Html::element('meta', array('name' => 'referrer', 'content' => $config->get('ReferrerPolicy'))); } $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}"; if ($p !== 'index,follow') { // http://www.robotstxt.org/wc/meta-user.html // Only show if it's different from the default robots policy $tags['meta-robots'] = Html::element('meta', array('name' => 'robots', 'content' => $p)); } foreach ($this->mMetatags as $tag) { if (0 == strcasecmp('http:', substr($tag[0], 0, 5))) { $a = 'http-equiv'; $tag[0] = substr($tag[0], 5); } else { $a = 'name'; } $tagName = "meta-{$tag[0]}"; if (isset($tags[$tagName])) { $tagName .= $tag[1]; } $tags[$tagName] = Html::element('meta', array($a => $tag[0], 'content' => $tag[1])); } foreach ($this->mLinktags as $tag) { $tags[] = Html::element('link', $tag); } # Universal edit button if ($config->get('UniversalEditButton') && $this->isArticleRelated()) { $user = $this->getUser(); if ($this->getTitle()->quickUserCan('edit', $user) && ($this->getTitle()->exists() || $this->getTitle()->quickUserCan('create', $user))) { // Original UniversalEditButton $msg = $this->msg('edit')->text(); $tags['universal-edit-button'] = Html::element('link', array('rel' => 'alternate', 'type' => 'application/x-wiki', 'title' => $msg, 'href' => $this->getTitle()->getEditURL())); // Alternate edit link $tags['alternative-edit'] = Html::element('link', array('rel' => 'edit', 'title' => $msg, 'href' => $this->getTitle()->getEditURL())); } } # Generally the order of the favicon and apple-touch-icon links # should not matter, but Konqueror (3.5.9 at least) incorrectly # uses whichever one appears later in the HTML source. Make sure # apple-touch-icon is specified first to avoid this. if ($config->get('AppleTouchIcon') !== false) { $tags['apple-touch-icon'] = Html::element('link', array('rel' => 'apple-touch-icon', 'href' => $config->get('AppleTouchIcon'))); } if ($config->get('Favicon') !== false) { $tags['favicon'] = Html::element('link', array('rel' => 'shortcut icon', 'href' => $config->get('Favicon'))); } # OpenSearch description link $tags['opensearch'] = Html::element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml', 'href' => wfScript('opensearch_desc'), 'title' => $this->msg('opensearch-desc')->inContentLanguage()->text())); if ($config->get('EnableAPI')) { # Real Simple Discovery link, provides auto-discovery information # for the MediaWiki API (and potentially additional custom API # support such as WordPress or Twitter-compatible APIs for a # blogging extension, etc) $tags['rsd'] = Html::element('link', array('rel' => 'EditURI', 'type' => 'application/rsd+xml', 'href' => wfExpandUrl(wfAppendQuery(wfScript('api'), array('action' => 'rsd')), PROTO_RELATIVE))); } # Language variants if (!$config->get('DisableLangConversion')) { $lang = $this->getTitle()->getPageLanguage(); if ($lang->hasVariants()) { $variants = $lang->getVariants(); foreach ($variants as $_v) { $tags["variant-{$_v}"] = Html::element('link', array('rel' => 'alternate', 'hreflang' => wfBCP47($_v), 'href' => $this->getTitle()->getLocalURL(array('variant' => $_v)))); } } # x-default link per https://support.google.com/webmasters/answer/189077?hl=en $tags["variant-x-default"] = Html::element('link', array('rel' => 'alternate', 'hreflang' => 'x-default', 'href' => $this->getTitle()->getLocalURL())); } # Copyright if ($this->copyrightUrl !== null) { $copyright = $this->copyrightUrl; } else { $copyright = ''; if ($config->get('RightsPage')) { $copy = Title::newFromText($config->get('RightsPage')); if ($copy) { $copyright = $copy->getLocalURL(); } } if (!$copyright && $config->get('RightsUrl')) { $copyright = $config->get('RightsUrl'); } } if ($copyright) { $tags['copyright'] = Html::element('link', array('rel' => 'copyright', 'href' => $copyright)); } # Feeds if ($config->get('Feed')) { foreach ($this->getSyndicationLinks() as $format => $link) { # Use the page name for the title. In principle, this could # lead to issues with having the same name for different feeds # corresponding to the same page, but we can't avoid that at # this low a level. $tags[] = $this->feedLink($format, $link, $this->msg("page-{$format}-feed", $this->getTitle()->getPrefixedText())->text()); } # Recent changes feed should appear on every page (except recentchanges, # that would be redundant). Put it after the per-page feed to avoid # changing existing behavior. It's still available, probably via a # menu in your browser. Some sites might have a different feed they'd # like to promote instead of the RC feed (maybe like a "Recent New Articles" # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined. # If so, use it instead. $sitename = $config->get('Sitename'); if ($config->get('OverrideSiteFeed')) { foreach ($config->get('OverrideSiteFeed') as $type => $feedUrl) { // Note, this->feedLink escapes the url. $tags[] = $this->feedLink($type, $feedUrl, $this->msg("site-{$type}-feed", $sitename)->text()); } } elseif (!$this->getTitle()->isSpecial('Recentchanges')) { $rctitle = SpecialPage::getTitleFor('Recentchanges'); foreach ($config->get('AdvertisedFeedTypes') as $format) { $tags[] = $this->feedLink($format, $rctitle->getLocalURL(array('feed' => $format)), $this->msg("site-{$format}-feed", $sitename)->text()); } } } # Canonical URL if ($config->get('EnableCanonicalServerLink')) { if ($canonicalUrl !== false) { $canonicalUrl = wfExpandUrl($canonicalUrl, PROTO_CANONICAL); } else { if ($this->isArticleRelated()) { // This affects all requests where "setArticleRelated" is true. This is // typically all requests that show content (query title, curid, oldid, diff), // and all wikipage actions (edit, delete, purge, info, history etc.). // It does not apply to File pages and Special pages. // 'history' and 'info' actions address page metadata rather than the page // content itself, so they may not be canonicalized to the view page url. // TODO: this ought to be better encapsulated in the Action class. $action = Action::getActionName($this->getContext()); if (in_array($action, array('history', 'info'))) { $query = "action={$action}"; } else { $query = ''; } $canonicalUrl = $this->getTitle()->getCanonicalURL($query); } else { $reqUrl = $this->getRequest()->getRequestURL(); $canonicalUrl = wfExpandUrl($reqUrl, PROTO_CANONICAL); } } } if ($canonicalUrl !== false) { $tags[] = Html::element('link', array('rel' => 'canonical', 'href' => $canonicalUrl)); } return $tags; }
/** * Get the code in Bcp47 format which we can use * inside of html lang="" tags. * * NOTE: The return value of this function is NOT HTML-safe and must be escaped with * htmlspecialchars() or similar. * * @since 1.19 * @return string */ public function getHtmlCode() { if (is_null($this->mHtmlCode)) { $this->mHtmlCode = wfBCP47($this->getCode()); } return $this->mHtmlCode; }
protected function doGettextHeader(MessageCollection $collection, $template, &$pluralCount) { global $wgSitename; $code = $collection->code; $name = TranslateUtils::getLanguageName($code); $native = TranslateUtils::getLanguageName($code, $code); $authors = $this->doAuthors($collection); if (isset($this->extra['header'])) { $extra = "# --\n" . $this->extra['header']; } else { $extra = ''; } $output = <<<PHP # Translation of {$this->group->getLabel()} to {$name} ({$native}) # Exported from {$wgSitename} # {$authors}{$extra} PHP; // Make sure there is no empty line before msgid $output = trim($output) . "\n"; $specs = isset($template['HEADERS']) ? $template['HEADERS'] : array(); $timestamp = wfTimestampNow(); $specs['PO-Revision-Date'] = self::formatTime($timestamp); if ($this->offlineMode) { $specs['POT-Creation-Date'] = self::formatTime($timestamp); } elseif ($this->group instanceof MessageGroupBase) { $specs['X-POT-Import-Date'] = self::formatTime(wfTimestamp(TS_MW, $this->getPotTime())); } $specs['Content-Type'] = 'text/plain; charset=UTF-8'; $specs['Content-Transfer-Encoding'] = '8bit'; $specs['Language'] = wfBCP47($this->group->mapCode($code)); Hooks::run('Translate:GettextFFS:headerFields', array(&$specs, $this->group, $code)); $specs['X-Generator'] = $this->getGenerator(); if ($this->offlineMode) { $specs['X-Language-Code'] = $code; $specs['X-Message-Group'] = $this->group->getId(); } $plural = self::getPluralRule($code); if ($plural) { $specs['Plural-Forms'] = $plural; } elseif (!isset($specs['Plural-Forms'])) { $specs['Plural-Forms'] = 'nplurals=2; plural=(n != 1);'; } $match = array(); preg_match('/nplurals=(\\d+);/', $specs['Plural-Forms'], $match); $pluralCount = $match[1]; $output .= 'msgid ""' . "\n"; $output .= 'msgstr ""' . "\n"; $output .= '""' . "\n"; foreach ($specs as $k => $v) { $output .= self::escape("{$k}: {$v}\n") . "\n"; } $output .= "\n"; return $output; }
/** * @param $msg string * @param $code string * @param $title Title * @param $makelink * @return string */ protected function doBox($msg, $code, $title = false, $makelink = false) { global $wgUser, $wgLang; $name = TranslateUtils::getLanguageName($code, false, $wgLang->getCode()); $code = wfBCP47($code); $skin = $wgUser->getSkin(); $attributes = array(); if (!$title) { $attributes['class'] = 'mw-sp-translate-in-other-big'; } elseif ($code === 'en') { $attributes['class'] = 'mw-sp-translate-edit-definition'; } else { $attributes['class'] = 'mw-sp-translate-edit-committed'; } if (mb_strlen($msg) < 100 && !$title) { $attributes['class'] = 'mw-sp-translate-in-other-small'; } $msg = TranslateUtils::convertWhiteSpaceToHTML($msg); if (!$title) { $title = "{$name} ({$code})"; } if ($makelink) { $linkTitle = Title::newFromText($makelink); $title = $skin->link($linkTitle, htmlspecialchars($title), array(), array('action' => 'edit')); } return TranslateUtils::fieldset($title, Html::element('span', null, $msg), $attributes); }
/** * @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; ## User info ##################################### // Information panel $defaultPreferences['username'] = array('type' => 'info', 'label-message' => 'username', 'default' => $user->getName(), 'section' => 'personal/info'); $defaultPreferences['userid'] = array('type' => 'info', 'label-message' => 'uid', '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, $user->getName()); $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))->parse(), 'default' => $context->msg('prefs-memberingroups-type', $lang->commaList($userGroups), $lang->commaList($userMembers))->plain(), 'raw' => true, 'section' => 'personal/info'); $defaultPreferences['editcount'] = array('type' => 'info', 'label-message' => 'prefs-edits', 'default' => $lang->formatNum($user->getEditCount()), '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'); } // Actually changeable stuff $defaultPreferences['realname'] = array('type' => $wgAuth->allowPropChange('realname') ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname'); $defaultPreferences['gender'] = array('type' => 'select', 'section' => 'personal/info', 'options' => array($context->msg('gender-male')->text() => 'male', $context->msg('gender-female')->text() => 'female', $context->msg('gender-unknown')->text() => 'unknown'), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender'); if ($wgAuth->allowPasswordChange()) { $link = Linker::link(SpecialPage::getTitleFor('ChangePassword'), $context->msg('prefs-resetpass')->escaped(), array(), array('returnto' => SpecialPage::getTitleFor('Preferences'))); $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'); } // Language /** WIKIA CHANGE BEGIN **/ $languages = wfGetFixedLanguageNames(); /** WIKIA CHANGE END **/ 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'); /* see if there are multiple language variants to choose from*/ $variantArray = array(); if (!$wgDisableLangConversion) { $variants = $wgContLang->getVariants(); foreach ($variants as $v) { $v = str_replace('_', '-', strtolower($v)); $variantArray[$v] = $wgContLang->getVariantname($v, false); } $options = array(); foreach ($variantArray as $code => $name) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } if (count($variantArray) > 1) { $defaultPreferences['variant'] = array('label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n', 'help-message' => 'prefs-help-variant'); } } if (count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) { $defaultPreferences['noconvertlink'] = array('type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink'); } // 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', 'section' => 'personal/signature'); ## Email stuff if ($wgEnableEmail) { $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'; } $link = Linker::link(SpecialPage::getTitleFor('ChangeEmail'), $context->msg($user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail')->escaped(), array(), array('returnto' => SpecialPage::getTitleFor('Preferences'))); $emailAddress = $user->getEmail() ? htmlspecialchars($user->getEmail()) : ''; if ($wgAuth->allowPropChange('emailaddress')) { $emailAddress .= $emailAddress == '' ? $link : " ({$link})"; } $defaultPreferences['emailaddress'] = array('type' => 'info', 'raw' => true, 'default' => $emailAddress, 'label-message' => 'youremail', 'section' => 'personal/email', 'help-messages' => $helpMessages); $disableEmailPrefs = false; if ($wgEmailAuthentication) { /* Wikia change - begin */ $emailauthenticated = ''; wfRunHooks('PreferencesGetEmailAuthentication', array(&$user, $context, &$disableEmailPrefs, &$emailauthenticated)); if (empty($emailauthenticated)) { /* Wikia change - end */ 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; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg('emailnotauthenticated')->parse() . '<br />' . Linker::linkKnown(SpecialPage::getTitleFor('Confirmemail'), $context->msg('emailconfirmlink')->escaped()) . '<br />'; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg('noemailprefs')->escaped(); } } $defaultPreferences['emailauthentication'] = array('type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated); } 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); } } /* Wikia change begin - @author: Inez */ $defaultPreferences['marketingallowed'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-marketingallowed'); /* Wikia change end */ } }
/** * @see IETF language tag / BCP 47 standards * * @since 2.4 * * @param string $languageCode * * @return string */ public static function asBCP47FormattedLanguageCode($languageCode) { return wfBCP47($languageCode); }
/** * bug 21672: Add Accept-Language to Vary and XVO headers * if there's no 'variant' parameter existed in GET. * * For example: * /w/index.php?title=Main_page should always be served; but * /w/index.php?title=Main_page&variant=zh-cn should never be served. */ function addAcceptLanguage() { $lang = $this->getTitle()->getPageLanguage(); if (!$this->getRequest()->getCheck('variant') && $lang->hasVariants()) { $variants = $lang->getVariants(); $aloption = array(); foreach ($variants as $variant) { if ($variant === $lang->getCode()) { continue; } else { $aloption[] = 'string-contains=' . $variant; // IE and some other browsers use BCP 47 standards in // their Accept-Language header, like "zh-CN" or "zh-Hant". // We should handle these too. $variantBCP47 = wfBCP47($variant); if ($variantBCP47 !== $variant) { $aloption[] = 'string-contains=' . $variantBCP47; } } } $this->addVaryHeader('Accept-Language', $aloption); } }
public function getOtherLanguagesBox() { $code = $this->handle->getCode(); $page = $this->handle->getKey(); $ns = $this->handle->getTitle()->getNamespace(); $boxes = array(); foreach (self::getFallbacks($code) as $fbcode) { $text = TranslateUtils::getMessageContent($page, $fbcode, $ns); if ($text === null) { continue; } $context = RequestContext::getMain(); $label = TranslateUtils::getLanguageName($fbcode, $context->getLanguage()->getCode()) . $context->msg('word-separator')->text() . $context->msg('parentheses', wfBCP47($fbcode))->text(); $target = Title::makeTitleSafe($ns, "{$page}/{$fbcode}"); if ($target) { $label = self::ajaxEditLink($target, htmlspecialchars($label)); } $dialogID = $this->dialogID(); $id = Sanitizer::escapeId("other-{$fbcode}-{$dialogID}"); $params = array('class' => 'mw-translate-edit-item'); $display = TranslateUtils::convertWhiteSpaceToHTML($text); $display = Html::rawElement('div', array('lang' => $fbcode, 'dir' => Language::factory($fbcode)->getDir()), $display); $contents = self::legend($label) . "\n" . $this->adder($id, $fbcode) . $display . self::clear(); $boxes[] = Html::rawElement('div', $params, $contents) . $this->wrapInsert($id, $text); } if (count($boxes)) { $sep = Html::element('hr', array('class' => 'mw-translate-sep')); return TranslateUtils::fieldset(wfMessage('translate-edit-in-other-languages', $page)->escaped(), implode("{$sep}\n", $boxes), array('class' => 'mw-sp-translate-edit-inother')); } return null; }
/** * @param string $languageCode Any non-standard or canonical language code * * @return string Canonical language code */ public function getCanonicalLanguageCode($languageCode) { // First we check the case since most languages will be cached very quickly if (isset(self::$canonicalLanguageCodeCache[$languageCode])) { return self::$canonicalLanguageCodeCache[$languageCode]; } // Wikibase list goes first in case we want to override // Like "simple" goes to en-x-simple not en if (isset($this->canonicalLanguageCodes[$languageCode])) { return $this->canonicalLanguageCodes[$languageCode]; } self::$canonicalLanguageCodeCache[$languageCode] = wfBCP47($languageCode); return self::$canonicalLanguageCodeCache[$languageCode]; }
/** * @return array in format "link name or number => 'link html'". */ public function getHeadLinksArray() { global $wgUniversalEditButton, $wgFavicon, $wgAppleTouchIcon, $wgEnableAPI, $wgSitename, $wgVersion, $wgFeed, $wgOverrideSiteFeed, $wgAdvertisedFeedTypes, $wgDisableLangConversion, $wgCanonicalLanguageLinks, $wgRightsPage, $wgRightsUrl; $tags = array(); $canonicalUrl = $this->mCanonicalUrl; $tags['meta-generator'] = Html::element('meta', array('name' => 'generator', 'content' => "MediaWiki {$wgVersion}")); // JRS 12/11/13 explicitly set robot policy $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}"; $tags['meta-robots'] = Html::element('meta', array('name' => 'robots', 'content' => $p)); $tags['meta-robots'] .= "<!--{$this->mRobotPolicyDebug}-->"; //$p = "{$this->mIndexPolicy},{$this->mFollowPolicy}"; //if ( $p !== 'index,follow' ) { // // http://www.robotstxt.org/wc/meta-user.html // // Only show if it's different from the default robots policy // $tags['meta-robots'] = Html::element( 'meta', array( // 'name' => 'robots', // 'content' => $p, // ) ); //} foreach ($this->mMetatags as $tag) { if (0 == strcasecmp('http:', substr($tag[0], 0, 5))) { $a = 'http-equiv'; $tag[0] = substr($tag[0], 5); } else { $a = 'name'; } $tagName = "meta-{$tag[0]}"; if (isset($tags[$tagName])) { $tagName .= $tag[1]; } $tags[$tagName] = Html::element('meta', array($a => $tag[0], 'content' => $tag[1])); } foreach ($this->mLinktags as $tag) { $tags[] = Html::element('link', $tag); } # Universal edit button if ($wgUniversalEditButton && $this->isArticleRelated()) { $user = $this->getUser(); if ($this->getTitle()->quickUserCan('edit', $user) && ($this->getTitle()->exists() || $this->getTitle()->quickUserCan('create', $user))) { // Original UniversalEditButton $msg = $this->msg('edit')->text(); $tags['universal-edit-button'] = Html::element('link', array('rel' => 'alternate', 'type' => 'application/x-wiki', 'title' => $msg, 'href' => $this->getTitle()->getLocalURL('action=edit'))); // Alternate edit link $tags['alternative-edit'] = Html::element('link', array('rel' => 'edit', 'title' => $msg, 'href' => $this->getTitle()->getLocalURL('action=edit'))); } } # Generally the order of the favicon and apple-touch-icon links # should not matter, but Konqueror (3.5.9 at least) incorrectly # uses whichever one appears later in the HTML source. Make sure # apple-touch-icon is specified first to avoid this. if ($wgAppleTouchIcon !== false) { $tags['apple-touch-icon'] = Html::element('link', array('rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon)); } if ($wgFavicon !== false) { $tags['favicon'] = Html::element('link', array('rel' => 'shortcut icon', 'href' => $wgFavicon)); } # OpenSearch description link $tags['opensearch'] = Html::element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml', 'href' => wfScript('opensearch_desc'), 'title' => $this->msg('opensearch-desc')->inContentLanguage()->text())); if ($wgEnableAPI) { # Real Simple Discovery link, provides auto-discovery information # for the MediaWiki API (and potentially additional custom API # support such as WordPress or Twitter-compatible APIs for a # blogging extension, etc) $tags['rsd'] = Html::element('link', array('rel' => 'EditURI', 'type' => 'application/rsd+xml', 'href' => wfExpandUrl(wfAppendQuery(wfScript('api'), array('action' => 'rsd')), PROTO_RELATIVE))); } # Language variants if (!$wgDisableLangConversion && $wgCanonicalLanguageLinks) { $lang = $this->getTitle()->getPageLanguage(); if ($lang->hasVariants()) { $urlvar = $lang->getURLVariant(); if (!$urlvar) { $variants = $lang->getVariants(); foreach ($variants as $_v) { $tags["variant-{$_v}"] = Html::element('link', array('rel' => 'alternate', 'hreflang' => wfBCP47($_v), 'href' => $this->getTitle()->getLocalURL(array('variant' => $_v)))); } } else { $canonicalUrl = $this->getTitle()->getLocalURL(); } } } # Copyright $copyright = ''; if ($wgRightsPage) { $copy = Title::newFromText($wgRightsPage); if ($copy) { $copyright = $copy->getLocalURL(); } } if (!$copyright && $wgRightsUrl) { $copyright = $wgRightsUrl; } if ($copyright) { $tags['copyright'] = Html::element('link', array('rel' => 'copyright', 'href' => $copyright)); } # Feeds if ($wgFeed) { foreach ($this->getSyndicationLinks() as $format => $link) { # Use the page name for the title. In principle, this could # lead to issues with having the same name for different feeds # corresponding to the same page, but we can't avoid that at # this low a level. $tags[] = $this->feedLink($format, $link, $this->msg("page-{$format}-feed", $this->getTitle()->getPrefixedText())->text()); } # Recent changes feed should appear on every page (except recentchanges, # that would be redundant). Put it after the per-page feed to avoid # changing existing behavior. It's still available, probably via a # menu in your browser. Some sites might have a different feed they'd # like to promote instead of the RC feed (maybe like a "Recent New Articles" # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined. # If so, use it instead. if ($wgOverrideSiteFeed) { foreach ($wgOverrideSiteFeed as $type => $feedUrl) { // Note, this->feedLink escapes the url. $tags[] = $this->feedLink($type, $feedUrl, $this->msg("site-{$type}-feed", $wgSitename)->text()); } } elseif (!$this->getTitle()->isSpecial('Recentchanges')) { $rctitle = SpecialPage::getTitleFor('Recentchanges'); foreach ($wgAdvertisedFeedTypes as $format) { $tags[] = $this->feedLink($format, $rctitle->getLocalURL(array('feed' => $format)), $this->msg("site-{$format}-feed", $wgSitename)->text()); } } } # Canonical URL global $wgEnableCanonicalServerLink; if ($wgEnableCanonicalServerLink) { if ($canonicalUrl !== false) { $canonicalUrl = wfExpandUrl($canonicalUrl, PROTO_CANONICAL); } else { $reqUrl = $this->getRequest()->getRequestURL(); $canonicalUrl = wfExpandUrl($reqUrl, PROTO_CANONICAL); } } if ($canonicalUrl !== false) { $tags[] = Html::element('link', array('rel' => 'canonical', 'href' => $canonicalUrl)); } return $tags; }
function getCellAttrs($field, $value) { if ($this->mCurrentRow->am_customised && $field === 'am_title') { return array('rowspan' => '2', 'class' => $field); } elseif ($field === 'am_title') { return array('class' => $field); } else { return array('lang' => wfBCP47($this->langcode), 'dir' => $this->lang->getDir(), 'class' => $field); } }
/** * @param $user User * @param $defaultPreferences * @return void */ static function profilePreferences($user, &$defaultPreferences) { global $wgLang, $wgUser; ## User info ##################################### // Information panel $defaultPreferences['username'] = array('type' => 'info', 'label-message' => 'username', 'default' => $user->getName(), 'section' => 'personal/info'); $defaultPreferences['userid'] = array('type' => 'info', 'label-message' => 'uid', '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); $userMembers[] = User::makeGroupLinkHTML($ueg, $memberName); } asort($userGroups); asort($userMembers); $defaultPreferences['usergroups'] = array('type' => 'info', 'label' => wfMsgExt('prefs-memberingroups', 'parseinline', $wgLang->formatNum(count($userGroups))), 'default' => wfMsgExt('prefs-memberingroups-type', array(), $wgLang->commaList($userGroups), $wgLang->commaList($userMembers)), 'raw' => true, 'section' => 'personal/info'); $defaultPreferences['editcount'] = array('type' => 'info', 'label-message' => 'prefs-edits', 'default' => $wgLang->formatNum($user->getEditCount()), 'section' => 'personal/info'); if ($user->getRegistration()) { $defaultPreferences['registrationdate'] = array('type' => 'info', 'label-message' => 'prefs-registration', 'default' => wfMsgExt('prefs-registration-date-time', 'parsemag', $wgLang->timeanddate($user->getRegistration(), true), $wgLang->date($user->getRegistration(), true), $wgLang->time($user->getRegistration(), true)), 'section' => 'personal/info'); } // Actually changeable stuff global $wgAuth; $defaultPreferences['realname'] = array('type' => $wgAuth->allowPropChange('realname') ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname'); $defaultPreferences['gender'] = array('type' => 'select', 'section' => 'personal/info', 'options' => array(wfMsg('gender-male') => 'male', wfMsg('gender-female') => 'female', wfMsg('gender-unknown') => 'unknown'), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender'); if ($wgAuth->allowPasswordChange()) { $link = $wgUser->getSkin()->link(SpecialPage::getTitleFor('ChangePassword'), wfMsgHtml('prefs-resetpass'), array(), array('returnto' => SpecialPage::getTitleFor('Preferences'))); $defaultPreferences['password'] = array('type' => 'info', 'raw' => true, 'default' => $link, 'label-message' => 'yourpassword', 'section' => 'personal/info'); } global $wgCookieExpiration; if ($wgCookieExpiration > 0) { $defaultPreferences['rememberpassword'] = array('type' => 'toggle', 'label' => wfMsgExt('tog-rememberpassword', array('parsemag'), $wgLang->formatNum(ceil($wgCookieExpiration / (3600 * 24)))), 'section' => 'personal/info'); } // Language global $wgLanguageCode; $languages = Language::getLanguageNames(false); 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'); global $wgContLang, $wgDisableLangConversion; global $wgDisableTitleConversion; /* see if there are multiple language variants to choose from*/ $variantArray = array(); if (!$wgDisableLangConversion) { $variants = $wgContLang->getVariants(); $languages = Language::getLanguageNames(true); foreach ($variants as $v) { $v = str_replace('_', '-', strtolower($v)); if (array_key_exists($v, $languages)) { // If it doesn't have a name, we'll pretend it doesn't exist $variantArray[$v] = $languages[$v]; } } $options = array(); foreach ($variantArray as $code => $name) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } if (count($variantArray) > 1) { $defaultPreferences['variant'] = array('label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n'); } } if (count($variantArray) > 1 && !$wgDisableLangConversion && !$wgDisableTitleConversion) { $defaultPreferences['noconvertlink'] = array('type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink'); } global $wgMaxSigChars, $wgOut, $wgParser; // show a preview of the old signature first $oldsigWikiText = $wgParser->preSaveTransform("~~~", new Title(), $user, new ParserOptions()); $oldsigHTML = $wgOut->parseInline($oldsigWikiText); $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', 'section' => 'personal/signature'); ## Email stuff global $wgEnableEmail; if ($wgEnableEmail) { global $wgEmailConfirmToEdit; global $wgEnableUserEmail; $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'; } $defaultPreferences['emailaddress'] = array('type' => $wgAuth->allowPropChange('emailaddress') ? 'email' : 'info', 'default' => $user->getEmail(), 'section' => 'personal/email', 'label-message' => 'youremail', 'help-messages' => $helpMessages, 'validation-callback' => array('Preferences', 'validateEmail')); global $wgEmailAuthentication; $disableEmailPrefs = false; if ($wgEmailAuthentication) { 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 $time = $wgLang->timeAndDate($user->getEmailAuthenticationTimestamp(), true); $d = $wgLang->date($user->getEmailAuthenticationTimestamp(), true); $t = $wgLang->time($user->getEmailAuthenticationTimestamp(), true); $emailauthenticated = wfMsgExt('emailauthenticated', 'parseinline', array($time, $d, $t)) . '<br />'; $disableEmailPrefs = false; } else { $disableEmailPrefs = true; $skin = $wgUser->getSkin(); $emailauthenticated = wfMsgExt('emailnotauthenticated', 'parseinline') . '<br />' . $skin->link(SpecialPage::getTitleFor('Confirmemail'), wfMsg('emailconfirmlink'), array(), array(), array('known', 'noclasses')) . '<br />'; } } else { $disableEmailPrefs = true; $emailauthenticated = wfMsgHtml('noemailprefs'); } $defaultPreferences['emailauthentication'] = array('type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated); } 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); } global $wgEnotifWatchlist; if ($wgEnotifWatchlist) { $defaultPreferences['enotifwatchlistpages'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifwatchlistpages', 'disabled' => $disableEmailPrefs); } global $wgEnotifUserTalk; 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); global $wgEnotifRevealEditorAddress; if ($wgEnotifRevealEditorAddress) { $defaultPreferences['enotifrevealaddr'] = array('type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifrevealaddr', 'disabled' => $disableEmailPrefs); } } } }
/** * @return string[] */ public function getHeadAttribs() { return array('dir' => $this->getDir(), 'lang' => wfBCP47($this->getLanguageCode())); }
/** * a structured array of links usually used for the tabs in a skin * * There are 4 standard sections * namespaces: Used for namespace tabs like special, page, and talk namespaces * views: Used for primary page views like read, edit, history * actions: Used for most extra page actions like deletion, protection, etc... * variants: Used to list the language variants for the page * * Each section's value is a key/value array of links for that section. * The links themselves have these common keys: * - class: The css classes to apply to the tab * - text: The text to display on the tab * - href: The href for the tab to point to * - rel: An optional rel= for the tab's link * - redundant: If true the tab will be dropped in skins using content_actions * this is useful for tabs like "Read" which only have meaning in skins that * take special meaning from the grouped structure of content_navigation * * Views also have an extra key which can be used: * - primary: If this is not true skins like vector may try to hide the tab * when the user has limited space in their browser window * * content_navigation using code also expects these ids to be present on the * links, however these are usually automatically generated by SkinTemplate * itself and are not necessary when using a hook. The only things these may * matter to are people modifying content_navigation after it's initial creation: * - id: A "preferred" id, most skins are best off outputting this preferred * id for best compatibility. * - tooltiponly: This is set to true for some tabs in cases where the system * believes that the accesskey should not be added to the tab. * * @return array */ protected function buildContentNavigationUrls() { global $wgDisableLangConversion; // Display tabs for the relevant title rather than always the title itself $title = $this->getRelevantTitle(); $onPage = $title->equals($this->getTitle()); $out = $this->getOutput(); $request = $this->getRequest(); $user = $this->getUser(); $content_navigation = array('namespaces' => array(), 'views' => array(), 'actions' => array(), 'variants' => array()); // parameters $action = $request->getVal('action', 'view'); $userCanRead = $title->quickUserCan('read', $user); $preventActiveTabs = false; Hooks::run('SkinTemplatePreventOtherActiveTabs', array(&$this, &$preventActiveTabs)); // Checks if page is some kind of content if ($title->canExist()) { // Gets page objects for the related namespaces $subjectPage = $title->getSubjectPage(); $talkPage = $title->getTalkPage(); // Determines if this is a talk page $isTalk = $title->isTalkPage(); // Generates XML IDs from namespace names $subjectId = $title->getNamespaceKey(''); if ($subjectId == 'main') { $talkId = 'talk'; } else { $talkId = "{$subjectId}_talk"; } $skname = $this->skinname; // Adds namespace links $subjectMsg = array("nstab-{$subjectId}"); if ($subjectPage->isMainPage()) { array_unshift($subjectMsg, 'mainpage-nstab'); } $content_navigation['namespaces'][$subjectId] = $this->tabAction($subjectPage, $subjectMsg, !$isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$subjectId]['context'] = 'subject'; $content_navigation['namespaces'][$talkId] = $this->tabAction($talkPage, array("nstab-{$talkId}", 'talk'), $isTalk && !$preventActiveTabs, '', $userCanRead); $content_navigation['namespaces'][$talkId]['context'] = 'talk'; if ($userCanRead) { $isForeignFile = $title->inNamespace(NS_FILE) && $this->canUseWikiPage() && $this->getWikiPage() instanceof WikiFilePage && !$this->getWikiPage()->isLocal(); // Adds view view link if ($title->exists() || $isForeignFile) { $content_navigation['views']['view'] = $this->tabAction($isTalk ? $talkPage : $subjectPage, array("{$skname}-view-view", 'view'), $onPage && ($action == 'view' || $action == 'purge'), '', true); // signal to hide this from simple content_actions $content_navigation['views']['view']['redundant'] = true; } // If it is a non-local file, show a link to the file in its own repository if ($isForeignFile) { $file = $this->getWikiPage()->getFile(); $content_navigation['views']['view-foreign'] = array('class' => '', 'text' => wfMessageFallback("{$skname}-view-foreign", 'view-foreign')->setContext($this->getContext())->params($file->getRepo()->getDisplayName())->text(), 'href' => $file->getDescriptionUrl(), 'primary' => false); } // Checks if user can edit the current page if it exists or create it otherwise if ($title->quickUserCan('edit', $user) && ($title->exists() || $title->quickUserCan('create', $user))) { // Builds CSS class for talk page links $isTalkClass = $isTalk ? ' istalk' : ''; // Whether the user is editing the page $isEditing = $onPage && ($action == 'edit' || $action == 'submit'); // Whether to show the "Add a new section" tab // Checks if this is a current rev of talk page and is not forced to be hidden $showNewSection = !$out->forceHideNewSectionLink() && ($isTalk && $this->isRevisionCurrent() || $out->showNewSectionLink()); $section = $request->getVal('section'); if ($title->exists() || $title->getNamespace() == NS_MEDIAWIKI && $title->getDefaultMessageText() !== false) { $msgKey = $isForeignFile ? 'edit-local' : 'edit'; } else { $msgKey = $isForeignFile ? 'create-local' : 'create'; } $content_navigation['views']['edit'] = array('class' => ($isEditing && ($section !== 'new' || !$showNewSection) ? 'selected' : '') . $isTalkClass, 'text' => wfMessageFallback("{$skname}-view-{$msgKey}", $msgKey)->setContext($this->getContext())->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => !$isForeignFile); // section link if ($showNewSection) { // Adds new section link //$content_navigation['actions']['addsection'] $content_navigation['views']['addsection'] = array('class' => $isEditing && $section == 'new' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-addsection", 'addsection')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=edit§ion=new')); } // Checks if the page has some kind of viewable content } elseif ($title->hasSourceText()) { // Adds view source view link $content_navigation['views']['viewsource'] = array('class' => $onPage && $action == 'edit' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-viewsource", 'viewsource')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL($this->editUrlOptions()), 'primary' => true); } // Checks if the page exists if ($title->exists()) { // Adds history view link $content_navigation['views']['history'] = array('class' => $onPage && $action == 'history' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-view-history", 'history_short')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=history')); if ($title->quickUserCan('delete', $user)) { $content_navigation['actions']['delete'] = array('class' => $onPage && $action == 'delete' ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-delete", 'delete')->setContext($this->getContext())->text(), 'href' => $title->getLocalURL('action=delete')); } if ($title->quickUserCan('move', $user)) { $moveTitle = SpecialPage::getTitleFor('Movepage', $title->getPrefixedDBkey()); $content_navigation['actions']['move'] = array('class' => $this->getTitle()->isSpecial('Movepage') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-move", 'move')->setContext($this->getContext())->text(), 'href' => $moveTitle->getLocalURL()); } } else { // article doesn't exist or is deleted if ($user->isAllowed('deletedhistory')) { $n = $title->isDeleted(); if ($n) { $undelTitle = SpecialPage::getTitleFor('Undelete', $title->getPrefixedDBkey()); // If the user can't undelete but can view deleted // history show them a "View .. deleted" tab instead. $msgKey = $user->isAllowed('undelete') ? 'undelete' : 'viewdeleted'; $content_navigation['actions']['undelete'] = array('class' => $this->getTitle()->isSpecial('Undelete') ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$msgKey}", "{$msgKey}_short")->setContext($this->getContext())->numParams($n)->text(), 'href' => $undelTitle->getLocalURL()); } } } if ($title->quickUserCan('protect', $user) && $title->getRestrictionTypes() && MWNamespace::getRestrictionLevels($title->getNamespace(), $user) !== array('')) { $mode = $title->isProtected() ? 'unprotect' : 'protect'; $content_navigation['actions'][$mode] = array('class' => $onPage && $action == $mode ? 'selected' : false, 'text' => wfMessageFallback("{$skname}-action-{$mode}", $mode)->setContext($this->getContext())->text(), 'href' => $title->getLocalURL("action={$mode}")); } // Checks if the user is logged in if ($this->loggedin && $user->isAllowedAll('viewmywatchlist', 'editmywatchlist')) { /** * The following actions use messages which, if made particular to * the any specific skins, would break the Ajax code which makes this * action happen entirely inline. OutputPage::getJSVars * defines a set of messages in a javascript object - and these * messages are assumed to be global for all skins. Without making * a change to that procedure these messages will have to remain as * the global versions. */ $mode = $user->isWatched($title) ? 'unwatch' : 'watch'; $token = WatchAction::getWatchToken($title, $user, $mode); $content_navigation['actions'][$mode] = array('class' => $onPage && ($action == 'watch' || $action == 'unwatch') ? 'selected' : false, 'text' => $this->msg($mode)->text(), 'href' => $title->getLocalURL(array('action' => $mode, 'token' => $token))); } } Hooks::run('SkinTemplateNavigation', array(&$this, &$content_navigation)); if ($userCanRead && !$wgDisableLangConversion) { $pageLang = $title->getPageLanguage(); // Gets list of language variants $variants = $pageLang->getVariants(); // Checks that language conversion is enabled and variants exist // And if it is not in the special namespace if (count($variants) > 1) { // Gets preferred variant (note that user preference is // only possible for wiki content language variant) $preferred = $pageLang->getPreferredVariant(); if (Action::getActionName($this) === 'view') { $params = $request->getQueryValues(); unset($params['title']); } else { $params = array(); } // Loops over each variant foreach ($variants as $code) { // Gets variant name from language code $varname = $pageLang->getVariantname($code); // Appends variant link $content_navigation['variants'][] = array('class' => $code == $preferred ? 'selected' : false, 'text' => $varname, 'href' => $title->getLocalURL(array('variant' => $code) + $params), 'lang' => wfBCP47($code), 'hreflang' => wfBCP47($code)); } } } } else { // If it's not content, it's got to be a special page $content_navigation['namespaces']['special'] = array('class' => 'selected', 'text' => $this->msg('nstab-special')->text(), 'href' => $request->getRequestURL(), 'context' => 'subject'); Hooks::run('SkinTemplateNavigation::SpecialPage', array(&$this, &$content_navigation)); } // Equiv to SkinTemplateContentActions Hooks::run('SkinTemplateNavigation::Universal', array(&$this, &$content_navigation)); // Setup xml ids and tooltip info foreach ($content_navigation as $section => &$links) { foreach ($links as $key => &$link) { $xmlID = $key; if (isset($link['context']) && $link['context'] == 'subject') { $xmlID = 'ca-nstab-' . $xmlID; } elseif (isset($link['context']) && $link['context'] == 'talk') { $xmlID = 'ca-talk'; } elseif ($section == 'variants') { $xmlID = 'ca-varlang-' . $xmlID; } else { $xmlID = 'ca-' . $xmlID; } $link['id'] = $xmlID; } } # We don't want to give the watch tab an accesskey if the # page is being edited, because that conflicts with the # accesskey on the watch checkbox. We also don't want to # give the edit tab an accesskey, because that's fairly # superfluous and conflicts with an accesskey (Ctrl-E) often # used for editing in Safari. if (in_array($action, array('edit', 'submit'))) { if (isset($content_navigation['views']['edit'])) { $content_navigation['views']['edit']['tooltiponly'] = true; } if (isset($content_navigation['actions']['watch'])) { $content_navigation['actions']['watch']['tooltiponly'] = true; } if (isset($content_navigation['actions']['unwatch'])) { $content_navigation['actions']['unwatch']['tooltiponly'] = true; } } return $content_navigation; }
/** * Generate a babel box for the given language and level. * * @param $code String: Language code to use. * @param $level String or Integer: Level of ability to use. * @return String: A single babel box, in wikitext format. */ protected static function mGenerateBox($code, $level) { $lang = wfBCP47($code); $portal = wfMessage('babel-portal', $code)->inContentLanguage()->plain(); if ($portal !== '') { $portal = "[[{$portal}|{$lang}]]"; } else { $portal = $lang; } $header = "{$portal}<span class=\"mw-babel-box-level-{$level}\">-{$level}</span>"; $code = strtolower($code); $name = BabelLanguageCodes::getName($code); $code = BabelLanguageCodes::getCode($code); $text = self::mGetText($name, $code, $level); $dir_current = Language::factory($code)->getDir(); $cellspacing = Babel::mHtmlAttrib('cellspacing', 'babel-cellspacing'); $cellpadding = Babel::mHtmlAttrib('cellpadding', 'babel-cellpadding'); $dir_head = self::$title->getPageLanguage()->getDir(); $box = <<<EOT <div class="mw-babel-box mw-babel-box-{$level}" dir="{$dir_head}"> {|{$cellspacing}{$cellpadding} ! dir="{$dir_head}" | {$header} | dir="{$dir_current}" | {$text} |} </div> EOT; return $box; }
/** * Returns a list of languages that can be translated to. * * @since 1.2 * * @param string $currentLang * * @return array */ public static function getLanguages($currentLang) { global $wgUser, $wgLanguageCode, $egLiveTranslateLanguages; $allowedLanguages = array_merge($egLiveTranslateLanguages, array($currentLang)); $targetLang = $wgLanguageCode; $languages = Language::getLanguageNames(false); if ($wgUser->isLoggedIn()) { $userLang = $wgUser->getOption('language'); if (array_key_exists($userLang, $languages) && in_array($userLang, $allowedLanguages)) { $targetLang = $userLang; } } $options = array(); ksort($languages); foreach ($languages as $code => $name) { if (in_array($code, $allowedLanguages) && $code != $currentLang) { $display = wfBCP47($code) . ' - ' . $name; $options[$display] = $code; } } return $options; }
function wfLanguageSelectorHTML(Title $title, $style = null, $class = null, $selectorstyle = null, $buttonstyle = null, $showCode = null) { global $wgLang, $wgContLang, $wgScript, $wgLanguageSelectorShowCode; if ($showCode === null) { $showCode = $wgLanguageSelectorShowCode; } static $id = 0; $id += 1; $code = $wgLang->getCode(); $html = ''; $html .= Xml::openElement('span', array('id' => 'languageselector-box-' . $id, 'class' => 'languageselector ' . $class, 'style' => $style)); $html .= Xml::openElement('form', array('name' => 'languageselector-form-' . $id, 'id' => 'languageselector-form-' . $id, 'method' => 'get', 'action' => $wgScript, 'style' => 'display:inline;')); $html .= Html::Hidden('title', $title->getPrefixedDBKey()); $html .= Xml::openElement('select', array('name' => 'setlang', 'id' => 'languageselector-select-' . $id, 'style' => $selectorstyle)); foreach (wfGetLanguageSelectorLanguages() as $ln) { $name = $wgContLang->getLanguageName($ln); if ($showCode) { $name = wfBCP47($ln) . ' - ' . $name; } $html .= Xml::option($name, $ln, $ln == $code); } $html .= Xml::closeElement('select'); $html .= Xml::submitButton(wfMsg('languageselector-setlang'), array('id' => 'languageselector-commit-' . $id, 'style' => $buttonstyle)); $html .= Xml::closeElement('form'); $html .= Xml::closeElement('span'); return $html; }
/** * Output a drop-down box for language options for the file * * @param Array $langChoices Array of string language codes * @param String $curLang Language code file is being viewed in. * @param String $defaultLang Language code that image is rendered in by default * @return String HTML to insert underneath image. */ protected function doRenderLangOpt(array $langChoices, $curLang, $defaultLang) { global $wgScript; sort($langChoices); $curLang = wfBCP47($curLang); $defaultLang = wfBCP47($defaultLang); $opts = ''; $haveCurrentLang = false; $haveDefaultLang = false; // We make a list of all the language choices in the file. // Additionally if the default language to render this file // is not included as being in this file (for example, in svgs // usually the fallback content is the english content) also // include a choice for that. Last of all, if we're viewing // the file in a language not on the list, add it as a choice. foreach ($langChoices as $lang) { $code = wfBCP47($lang); $name = Language::fetchLanguageName($code, $this->getContext()->getLanguage()->getCode()); if ($name !== '') { $display = wfMessage('img-lang-opt', $code, $name)->text(); } else { $display = $code; } $opts .= "\n" . Xml::option($display, $code, $curLang === $code); if ($curLang === $code) { $haveCurrentLang = true; } if ($defaultLang === $code) { $haveDefaultLang = true; } } if (!$haveDefaultLang) { // Its hard to know if the content is really in the default language, or // if its just unmarked content that could be in any language. $opts = Xml::option(wfMessage('img-lang-default')->text(), $defaultLang, $defaultLang === $curLang) . $opts; } if (!$haveCurrentLang && $defaultLang !== $curLang) { $name = Language::fetchLanguageName($curLang, $this->getContext()->getLanguage()->getCode()); if ($name !== '') { $display = wfMessage('img-lang-opt', $curLang, $name)->text(); } else { $display = $curLang; } $opts = Xml::option($display, $curLang, true) . $opts; } $select = Html::rawElement('select', array('id' => 'mw-imglangselector', 'name' => 'lang'), $opts); $submit = Xml::submitButton(wfMessage('img-lang-go')->text()); $formContents = wfMessage('img-lang-info')->rawParams($select, $submit)->parse() . Html::hidden('title', $this->getTitle()->getPrefixedDBkey()); $langSelectLine = Html::rawElement('div', array('id' => 'mw-imglangselector-line'), Html::rawElement('form', array('action' => $wgScript), $formContents)); return $langSelectLine; }
/** * Gives language names. * @param $parser Parser * @param $code String Language code * @param $language String Language code * @return String */ static function language($parser, $code = '', $language = '') { global $wgContLang; $code = strtolower($code); $language = strtolower($language); if ($language !== '') { $names = Language::getTranslatedLanguageNames($language); return isset($names[$code]) ? $names[$code] : wfBCP47($code); } $lang = $wgContLang->getLanguageName($code); return $lang !== '' ? $lang : wfBCP47($code); }
/** * Gives language names. * @param Parser $parser * @param string $code Language code (of which to get name) * @param string $inLanguage Language code (in which to get name) * @return string */ public static function language($parser, $code = '', $inLanguage = '') { $code = strtolower($code); $inLanguage = strtolower($inLanguage); $lang = Language::fetchLanguageName($code, $inLanguage); return $lang !== '' ? $lang : wfBCP47($code); }
/** * Generate a babel box for the given language and level. * * @param $code String: Language code to use. * @param $level String or Integer: Level of ability to use. * @return String: A single babel box, in wikitext format. */ protected static function mGenerateBox($code, $level) { wfProfileIn(__METHOD__); $lang = wfBCP47($code); $portal = wfMessage('babel-portal', $code)->inContentLanguage()->plain(); if ($portal !== '') { $portal = "[[{$portal}|{$lang}]]"; } else { $portal = $lang; } $header = "{$portal}<span class=\"mw-babel-box-level-{$level}\">-{$level}</span>"; $code = strtolower($code); $name = BabelLanguageCodes::getName($code); $code = BabelLanguageCodes::getCode($code); $text = self::mGetText($name, $code, $level); $dir_current = Language::factory($code)->getDir(); $spacing = Babel::mCssAttrib('border-spacing', 'babel-cellspacing', true); $padding = Babel::mCssAttrib('padding', 'babel-cellpadding', true); $style = ''; if ($spacing === '') { $style = $padding === '' ? '' : 'style="' . $padding . '"'; } else { $style = $padding === '' ? 'style="' . $spacing . '"' : 'style="' . $padding . ' ' . $spacing . '"'; } $dir_head = self::$title->getPageLanguage()->getDir(); $box = <<<EOT <div class="mw-babel-box mw-babel-box-{$level}" dir="{$dir_head}"> {|{$style} ! dir="{$dir_head}" | {$header} | dir="{$dir_current}" lang="{$lang}" | {$text} |} </div> EOT; wfProfileOut(__METHOD__); return $box; }
/** * @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, ); } } } }
/** * Get the language of this item * * @return string */ public function getLanguage() { global $wgLanguageCode; return wfBCP47($wgLanguageCode); }