protected function showLanguage($code, $users)
 {
     $out = $this->getOutput();
     $lang = $this->getLanguage();
     $usernames = array_keys($users);
     $userStats = $this->getUserStats($usernames);
     // Information to be used inside the foreach loop.
     $linkInfo = array();
     $linkInfo['rc']['title'] = SpecialPage::getTitleFor('Recentchanges');
     $linkInfo['rc']['msg'] = $this->msg('supportedlanguages-recenttranslations')->escaped();
     $linkInfo['stats']['title'] = SpecialPage::getTitleFor('LanguageStats');
     $linkInfo['stats']['msg'] = $this->msg('languagestats')->escaped();
     $local = Language::fetchLanguageName($code, $lang->getCode(), 'all');
     $native = Language::fetchLanguageName($code, null, 'all');
     if ($local !== $native) {
         $headerText = $this->msg('supportedlanguages-portallink')->params($code, $local, $native)->escaped();
     } else {
         // No CLDR, so a less localised header and link title.
         $headerText = $this->msg('supportedlanguages-portallink-nocldr')->params($code, $native)->escaped();
     }
     $out->addHtml(Html::rawElement('h2', array('id' => $code), $headerText));
     // Add useful links for language stats and recent changes for the language.
     $links = array();
     $links[] = Linker::link($linkInfo['stats']['title'], $linkInfo['stats']['msg'], array(), array('code' => $code, 'suppresscomplete' => '1'), array('known', 'noclasses'));
     $links[] = Linker::link($linkInfo['rc']['title'], $linkInfo['rc']['msg'], array(), array('translations' => 'only', 'trailer' => "/" . $code), array('known', 'noclasses'));
     $linkList = $lang->listToText($links);
     $out->addHTML("<p>" . $linkList . "</p>\n");
     $this->makeUserList($users, $userStats);
 }
 private function makeLanguageLinks()
 {
     global $wgWRLanguageLinksShowOnly, $wgWRLanguageLinksShowTitles;
     // Language links - ripped from SkinTemplate.php and then mangled badly
     $parserLanguageLinks = $this->mParser->getOutput()->getLanguageLinks();
     $language_urls = array();
     $showOnly = array();
     if ($wgWRLanguageLinksShowOnly != null) {
         $showOnly = explode(',', $wgWRLanguageLinksShowOnly);
     }
     foreach ($parserLanguageLinks as $languageLinkText) {
         $languageLinkTitle = Title::newFromText($languageLinkText);
         if ($languageLinkTitle) {
             $ilInterwikiCode = $languageLinkTitle->getInterwiki();
             if (is_null($wgWRLanguageLinksShowOnly) || in_array($ilInterwikiCode, $showOnly)) {
                 $ilLangName = Language::fetchLanguageName($ilInterwikiCode);
                 if (strval($ilLangName) === '') {
                     $ilLangName = $languageLinkText;
                 }
                 $ilArticleName = $languageLinkTitle->getText();
                 $language_urls[] = array('href' => $languageLinkTitle->getFullURL(), 'text' => $wgWRLanguageLinksShowTitles ? $ilArticleName : $ilLangName, 'title' => $wgWRLanguageLinksShowTitles ? $ilLangName : $ilArticleName, 'class' => "wr-languagelinks-{$ilInterwikiCode}", 'lang' => $ilInterwikiCode);
             }
         }
     }
     return $language_urls;
 }
Beispiel #3
0
function wfGlobalInterwikis($prefix, &$iwData)
{
    global $wgInterwikiCentralDB;
    // docs/hooks.txt says: Return true without providing an interwiki to continue interwiki search.
    if ($wgInterwikiCentralDB === null || $wgInterwikiCentralDB === wfWikiId()) {
        // No global set or this is global, nothing to add
        return true;
    }
    if (!Language::fetchLanguageName($prefix)) {
        // Check if prefix exists locally and skip
        foreach (Interwiki::getAllPrefixes(null) as $id => $localPrefixInfo) {
            if ($prefix === $localPrefixInfo['iw_prefix']) {
                return true;
            }
        }
        $dbr = wfGetDB(DB_SLAVE, array(), $wgInterwikiCentralDB);
        $res = $dbr->selectRow('interwiki', '*', array('iw_prefix' => $prefix), __METHOD__);
        if (!$res) {
            return true;
        }
        // Excplicitly make this an array since it's expected to be one
        $iwData = (array) $res;
        // At this point, we can safely return false because we know that we have something
        return false;
    }
    return true;
}
 public function __construct($name = null, array $data = array(), $dataName = '', $engineName = null)
 {
     parent::__construct($name, $data, $dataName, $engineName);
     // Skip certain tests if something isn't providing translated language names
     // (bug 67343)
     if (Language::fetchLanguageName('en', 'fr') === 'English') {
         $msg = 'Language name translations are unavailable; ' . 'install Extension:CLDR or something similar';
         $this->skipTests += array('fetchLanguageName (en,ru)' => $msg, 'fetchLanguageName (ru,en)' => $msg, 'fetchLanguageNames (de)' => $msg, 'fetchLanguageNames ([[bogus]])' => $msg);
     }
 }
 /**
  * Fetches appropriate HTML for the tutorial portion of the wizard.
  * Looks up an image on the current wiki. This will work as is on Commons, and will also work
  * on test wikis that enable instantCommons.
  * @param String|null $campaign Upload Wizard campaign for which the tutorial should be displayed.
  * @return String html that will display the tutorial.
  */
 public static function getHtml($campaign = null)
 {
     global $wgLang;
     $error = null;
     $errorHtml = '';
     $tutorialHtml = '';
     $langCode = $wgLang->getCode();
     $tutorial = UploadWizardConfig::getSetting('tutorial', $campaign);
     // getFile returns false if it can't find the right file
     $tutorialFile = self::getFile($langCode, $tutorial);
     if ($tutorialFile === false) {
         $error = 'localized-file-missing';
         foreach ($wgLang->getFallbackLanguages() as $langCode) {
             $tutorialFile = self::getFile($langCode, $tutorial);
             if ($tutorialFile !== false) {
                 // $langCode remains as the code where a file is found.
                 break;
             }
         }
     }
     // at this point, we have one of the following situations:
     // $error is null, and tutorialFile is the right one for this language
     // $error notes we couldn't find the tutorialFile for your language, and $tutorialFile is the english one
     // $error notes we couldn't find the tutorialFile for your language, and $tutorialFile is still false (major file failure)
     if ($tutorialFile) {
         // XXX TODO if the client can handle SVG, we could also just send it the unscaled thumb, client-scaled into a DIV or something.
         // if ( client can handle SVG ) {
         //   $tutorialThumbnailImage->getUnscaledThumb();
         // }
         // put it into a div of appropriate dimensions.
         // n.b. File::transform() returns false if failed, MediaTransformOutput otherwise
         $thumbnailImage = $tutorialFile->transform(array('width' => $tutorial['width']));
         if ($thumbnailImage) {
             $tutorialHtml = self::getImageHtml($thumbnailImage, $tutorial);
         } else {
             $error = 'cannot-transform';
         }
     } else {
         $error = 'file-missing';
     }
     if ($error !== null) {
         // Messages:
         // mwe-upwiz-tutorial-error-localized-file-missing, mwe-upwiz-tutorial-error-file-missing,
         // mwe-upwiz-tutorial-error-cannot-transform
         $errorMsg = wfMessage('mwe-upwiz-tutorial-error-' . $error);
         if ($error === 'localized-file-missing') {
             $errorMsg->params(Language::fetchLanguageName($langCode, $wgLang->getCode()));
         }
         $errorHtml = Html::element('p', array('class' => 'errorbox', 'style' => 'float: none;'), $errorMsg->text());
     }
     return $errorHtml . $tutorialHtml;
 }
 /**
  * Takes a language code, and attempt to obtain a better variant of it,
  * checks the MediaWiki language codes for a match, otherwise checks the
  * Babel language codes CDB (preferring ISO 639-1 over ISO 639-3).
  *
  * @param $code String: Code to try and get a "better" code for.
  * @return String (language code) or false (invalid language code).
  */
 public static function getCode($code)
 {
     wfProfileIn(__METHOD__);
     global $wgBabelLanguageCodesCdb;
     $mediawiki = Language::fetchLanguageName($code);
     if ($mediawiki !== '') {
         wfProfileOut(__METHOD__);
         return $code;
     }
     $codesCdb = CdbReader::open($wgBabelLanguageCodesCdb);
     $codes = $codesCdb->get($code);
     wfProfileOut(__METHOD__);
     return $codes;
 }
 /**
  * Returns a WikitextContent object representing a redirect to the given destination page.
  *
  * @param Title $destination The page to redirect to.
  * @param string $text Text to include in the redirect, if possible.
  *
  * @return Content
  *
  * @see ContentHandler::makeRedirectContent
  */
 public function makeRedirectContent(Title $destination, $text = '')
 {
     $optionalColon = '';
     if ($destination->getNamespace() == NS_CATEGORY) {
         $optionalColon = ':';
     } else {
         $iw = $destination->getInterwiki();
         if ($iw && Language::fetchLanguageName($iw, null, 'mw')) {
             $optionalColon = ':';
         }
     }
     $mwRedir = MagicWord::get('redirect');
     $redirectText = $mwRedir->getSynonym(0) . ' [[' . $optionalColon . $destination->getFullText() . ']]';
     if ($text != '') {
         $redirectText .= "\n" . $text;
     }
     return new WikitextContent($redirectText);
 }
 /**
  * Takes a language code, and attempt to obtain a better variant of it,
  * checks the MediaWiki language codes for a match, otherwise checks the
  * Babel language codes CDB (preferring ISO 639-1 over ISO 639-3).
  *
  * @param $code String: Code to try and get a "better" code for.
  * @return String (language code) or false (invalid language code).
  */
 public static function getCode($code)
 {
     wfProfileIn(__METHOD__);
     global $wgBabelLanguageCodesCdb;
     $mediawiki = Language::fetchLanguageName($code);
     if ($mediawiki !== '') {
         wfProfileOut(__METHOD__);
         return $code;
     }
     $codes = false;
     try {
         $codesCdb = CdbReader::open($wgBabelLanguageCodesCdb);
         $codes = $codesCdb->get($code);
     } catch (CdbException $e) {
         wfDebug(__METHOD__ . ": CdbException caught, error message was " . $e->getMessage());
     }
     wfProfileOut(__METHOD__);
     return $codes;
 }
 function heading()
 {
     global $wgDummyLanguageCodes;
     $version = SpecialVersion::getVersion('nodb');
     echo "'''Statistics are based on:''' <code>" . $version . "</code>\n\n";
     echo "'''Note:''' These statistics can be generated by running " . "<code>php maintenance/language/transstat.php</code>.\n\n";
     echo "For additional information on specific languages (the message names, the actual " . "problems, etc.), run <code>php maintenance/language/checkLanguage.php --lang=foo</code>.\n\n";
     echo 'English (en) is excluded because it is the default localization';
     if (is_array($wgDummyLanguageCodes)) {
         $dummyCodes = array();
         foreach ($wgDummyLanguageCodes as $dummyCode => $correctCode) {
             $dummyCodes[] = Language::fetchLanguageName($dummyCode) . ' (' . $dummyCode . ')';
         }
         echo ', as well as the following languages that are not intended for ' . 'system message translations, usually because they redirect to other ' . 'language codes: ' . implode(', ', $dummyCodes);
     }
     echo ".\n\n";
     # dot to end sentence
     echo '{| class="sortable wikitable" border="2" style="background-color: #F9F9F9; ' . 'border: 1px #AAAAAA solid; border-collapse: collapse; clear:both; width:100%;"' . "\n";
 }
Beispiel #10
0
 public function execute()
 {
     $dbw = wfGetDB(DB_SLAVE);
     // Get all Athena logs
     $res = $dbw->select(array('athena_page_details'), array('al_id', 'apd_language', 'apd_content'), array(), __METHOD__, array(), array());
     foreach ($res as $row) {
         echo "\n----------------------------------------------\n";
         echo "al_id is {$row->al_id} \n";
         echo "apd_language is {$row->apd_language} \n";
         $content = $row->apd_content;
         if (strlen($content) == 0) {
             $code = null;
         } else {
             file_put_contents("temp", $content);
             $code = system("franc < temp");
         }
         $code = AthenaHelper::convertISOCode($code);
         echo "Language code is {$code}\n";
         $str = $dbw->strencode(Language::fetchLanguageName($code));
         echo "Language name is {$str} \n";
         $dbw->update('athena_page_details', array('apd_language' => $str), array('al_id' => $row->al_id), __METHOD__, null);
         echo "\n----------------------------------------------\n";
     }
 }
 protected function getMessageParameters()
 {
     // Get the user language for displaying language names
     $userLang = $this->context->getLanguage()->getCode();
     $params = parent::getMessageParameters();
     // Get the language codes from log
     $oldLang = $params[3];
     $kOld = strrpos($oldLang, '[');
     if ($kOld) {
         $oldLang = substr($oldLang, 0, $kOld);
     }
     $newLang = $params[4];
     $kNew = strrpos($newLang, '[');
     if ($kNew) {
         $newLang = substr($newLang, 0, $kNew);
     }
     // Convert language codes to names in user language
     $logOld = Language::fetchLanguageName($oldLang, $userLang) . ' (' . $oldLang . ')';
     $logNew = Language::fetchLanguageName($newLang, $userLang) . ' (' . $newLang . ')';
     // Add the default message to languages if required
     $params[3] = !$kOld ? $logOld : $logOld . ' [' . $this->msg('default') . ']';
     $params[4] = !$kNew ? $logNew : $logNew . ' [' . $this->msg('default') . ']';
     return $params;
 }
 public function execute()
 {
     global $wgTranslateFuzzyBotName, $wgSitename;
     $days = (int) $this->getOption('days', 30);
     $hours = $days * 24;
     $top = (int) $this->getOption('top', -1);
     $bots = $this->hasOption('bots');
     $namespaces = array();
     if ($this->hasOption('ns')) {
         $input = explode(',', $this->getOption('ns'));
         foreach ($input as $namespace) {
             if (is_numeric($namespace)) {
                 $namespaces[] = $namespace;
             }
         }
     }
     // Select set of edits to report on
     // Fetch some extrac fields that normally TranslateUtils::translationChanges wont
     $extraFields = array('rc_old_len', 'rc_new_len');
     $rows = TranslateUtils::translationChanges($hours, $bots, $namespaces, $extraFields);
     // Get counts for edits per language code after filtering out edits by FuzzyBot
     $codes = array();
     foreach ($rows as $_) {
         // Filter out edits by $wgTranslateFuzzyBotName
         if ($_->rc_user_text === $wgTranslateFuzzyBotName) {
             continue;
         }
         $handle = new MessageHandle(Title::newFromText($_->rc_title));
         $code = $handle->getCode();
         if (!isset($codes[$code])) {
             $codes[$code] = 0;
         }
         if ($this->hasOption('diff')) {
             $diff = abs($_->rc_new_len - $_->rc_old_len);
         } else {
             $diff = $_->rc_new_len;
         }
         $codes[$code] += $diff;
     }
     // Sort counts and report descending up to $top rows.
     arsort($codes);
     $i = 0;
     $total = 0;
     $this->output("Character edit stats for last {$days} days in {$wgSitename}\n");
     $this->output("code\tname\tedit\n");
     $this->output("-----------------------\n");
     foreach ($codes as $code => $num) {
         if ($i++ === $top) {
             break;
         }
         $language = Language::fetchLanguageName($code);
         if (!$language) {
             // this will be very rare, but avoid division by zero in next line
             continue;
         }
         $charRatio = mb_strlen($language, 'UTF-8') / strlen($language);
         $num = intval($num * $charRatio);
         $total += $num;
         $this->output("{$code}\t{$language}\t{$num}\n");
     }
     $this->output("-----------------------\n");
     $this->output("Total\t\t{$total}\n");
 }
 public function execute()
 {
     if ($this->getPageSet()->getGoodTitleCount() == 0) {
         return;
     }
     $params = $this->extractRequestParams();
     $prop = array_flip((array) $params['prop']);
     if (isset($params['title']) && !isset($params['lang'])) {
         $this->dieUsageMsg(array('missingparam', 'lang'));
     }
     // Handle deprecated param
     $this->requireMaxOneParameter($params, 'url', 'prop');
     if ($params['url']) {
         $prop = array('url' => 1);
     }
     $this->addFields(array('ll_from', 'll_lang', 'll_title'));
     $this->addTables('langlinks');
     $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles()));
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $op = $params['dir'] == 'descending' ? '<' : '>';
         $llfrom = intval($cont[0]);
         $lllang = $this->getDB()->addQuotes($cont[1]);
         $this->addWhere("ll_from {$op} {$llfrom} OR " . "(ll_from = {$llfrom} AND " . "ll_lang {$op}= {$lllang})");
     }
     // FIXME: (follow-up) To allow extensions to add to the language links, we need
     //       to load them all, add the extra links, then apply paging.
     //       Should not be terrible, it's not going to be more than a few hundred links.
     // Note that, since (ll_from, ll_lang) is a unique key, we don't need
     // to sort by ll_title to ensure deterministic ordering.
     $sort = $params['dir'] == 'descending' ? ' DESC' : '';
     if (isset($params['lang'])) {
         $this->addWhereFld('ll_lang', $params['lang']);
         if (isset($params['title'])) {
             $this->addWhereFld('ll_title', $params['title']);
         }
         $this->addOption('ORDER BY', 'll_from' . $sort);
     } else {
         // Don't order by ll_from if it's constant in the WHERE clause
         if (count($this->getPageSet()->getGoodTitles()) == 1) {
             $this->addOption('ORDER BY', 'll_lang' . $sort);
         } else {
             $this->addOption('ORDER BY', array('ll_from' . $sort, 'll_lang' . $sort));
         }
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $res = $this->select(__METHOD__);
     $count = 0;
     foreach ($res as $row) {
         if (++$count > $params['limit']) {
             // We've reached the one extra which shows that
             // there are additional pages to be had. Stop here...
             $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}");
             break;
         }
         $entry = array('lang' => $row->ll_lang);
         if (isset($prop['url'])) {
             $title = Title::newFromText("{$row->ll_lang}:{$row->ll_title}");
             if ($title) {
                 $entry['url'] = wfExpandUrl($title->getFullURL(), PROTO_CURRENT);
             }
         }
         if (isset($prop['langname'])) {
             $entry['langname'] = Language::fetchLanguageName($row->ll_lang, $params['inlanguagecode']);
         }
         if (isset($prop['autonym'])) {
             $entry['autonym'] = Language::fetchLanguageName($row->ll_lang);
         }
         ApiResult::setContentValue($entry, 'title', $row->ll_title);
         $fit = $this->addPageSubItem($row->ll_from, $entry);
         if (!$fit) {
             $this->setContinueEnumParameter('continue', "{$row->ll_from}|{$row->ll_lang}");
             break;
         }
     }
 }
 /**
  * Generates array of language links for the current page
  *
  * @return array
  */
 public function getLanguages()
 {
     global $wgHideInterlanguageLinks;
     if ($wgHideInterlanguageLinks) {
         return array();
     }
     $userLang = $this->getLanguage();
     $languageLinks = array();
     foreach ($this->getOutput()->getLanguageLinks() as $languageLinkText) {
         $languageLinkParts = explode(':', $languageLinkText, 2);
         $class = 'interlanguage-link interwiki-' . $languageLinkParts[0];
         unset($languageLinkParts);
         $languageLinkTitle = Title::newFromText($languageLinkText);
         if ($languageLinkTitle) {
             $ilInterwikiCode = $languageLinkTitle->getInterwiki();
             $ilLangName = Language::fetchLanguageName($ilInterwikiCode);
             if (strval($ilLangName) === '') {
                 $ilDisplayTextMsg = wfMessage("interlanguage-link-{$ilInterwikiCode}");
                 if (!$ilDisplayTextMsg->isDisabled()) {
                     // Use custom MW message for the display text
                     $ilLangName = $ilDisplayTextMsg->text();
                 } else {
                     // Last resort: fallback to the language link target
                     $ilLangName = $languageLinkText;
                 }
             } else {
                 // Use the language autonym as display text
                 $ilLangName = $this->formatLanguageName($ilLangName);
             }
             // CLDR extension or similar is required to localize the language name;
             // otherwise we'll end up with the autonym again.
             $ilLangLocalName = Language::fetchLanguageName($ilInterwikiCode, $userLang->getCode());
             $languageLinkTitleText = $languageLinkTitle->getText();
             if ($ilLangLocalName === '') {
                 $ilFriendlySiteName = wfMessage("interlanguage-link-sitename-{$ilInterwikiCode}");
                 if (!$ilFriendlySiteName->isDisabled()) {
                     if ($languageLinkTitleText === '') {
                         $ilTitle = wfMessage('interlanguage-link-title-nonlangonly', $ilFriendlySiteName->text())->text();
                     } else {
                         $ilTitle = wfMessage('interlanguage-link-title-nonlang', $languageLinkTitleText, $ilFriendlySiteName->text())->text();
                     }
                 } else {
                     // we have nothing friendly to put in the title, so fall back to
                     // displaying the interlanguage link itself in the title text
                     // (similar to what is done in page content)
                     $ilTitle = $languageLinkTitle->getInterwiki() . ":{$languageLinkTitleText}";
                 }
             } elseif ($languageLinkTitleText === '') {
                 $ilTitle = wfMessage('interlanguage-link-title-langonly', $ilLangLocalName)->text();
             } else {
                 $ilTitle = wfMessage('interlanguage-link-title', $languageLinkTitleText, $ilLangLocalName)->text();
             }
             $ilInterwikiCodeBCP47 = wfBCP47($ilInterwikiCode);
             $languageLink = array('href' => $languageLinkTitle->getFullURL(), 'text' => $ilLangName, 'title' => $ilTitle, 'class' => $class, 'lang' => $ilInterwikiCodeBCP47, 'hreflang' => $ilInterwikiCodeBCP47);
             Hooks::run('SkinTemplateGetLanguageLink', array(&$languageLink, $languageLinkTitle, $this->getTitle(), $this->getOutput()));
             $languageLinks[] = $languageLink;
         }
     }
     return $languageLinks;
 }
 /**
  * Returns page information in an easily-manipulated format. Array keys are used so extensions
  * may add additional information in arbitrary positions. Array values are arrays with one
  * element to be rendered as a header, arrays with two elements to be rendered as a table row.
  *
  * @return array
  */
 protected function pageInfo()
 {
     global $wgContLang, $wgRCMaxAge;
     $user = $this->getUser();
     $lang = $this->getLanguage();
     $title = $this->getTitle();
     $id = $title->getArticleID();
     // Get page information that would be too "expensive" to retrieve by normal means
     $pageCounts = self::pageCounts($title, $user);
     // Get page properties
     $dbr = wfGetDB(DB_SLAVE);
     $result = $dbr->select('page_props', array('pp_propname', 'pp_value'), array('pp_page' => $id), __METHOD__);
     $pageProperties = array();
     foreach ($result as $row) {
         $pageProperties[$row->pp_propname] = $row->pp_value;
     }
     // Basic information
     $pageInfo = array();
     $pageInfo['header-basic'] = array();
     // Display title
     $displayTitle = $title->getPrefixedText();
     if (!empty($pageProperties['displaytitle'])) {
         $displayTitle = $pageProperties['displaytitle'];
     }
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-display-title'), $displayTitle);
     // Is it a redirect? If so, where to?
     if ($title->isRedirect()) {
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-redirectsto'), Linker::link($this->page->getRedirectTarget()) . $this->msg('word-separator')->text() . $this->msg('parentheses', Linker::link($this->page->getRedirectTarget(), $this->msg('pageinfo-redirectsto-info')->escaped(), array(), array('action' => 'info')))->text());
     }
     // Default sort key
     $sortKey = $title->getCategorySortKey();
     if (!empty($pageProperties['defaultsort'])) {
         $sortKey = $pageProperties['defaultsort'];
     }
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-default-sort'), $sortKey);
     // Page length (in bytes)
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-length'), $lang->formatNum($title->getLength()));
     // Page ID (number not localised, as it's a database ID)
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-article-id'), $id);
     // Language in which the page content is (supposed to be) written
     $pageLang = $title->getPageLanguage()->getCode();
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-language'), Language::fetchLanguageName($pageLang, $lang->getCode()) . ' ' . $this->msg('parentheses', $pageLang));
     // Search engine status
     $pOutput = new ParserOutput();
     if (isset($pageProperties['noindex'])) {
         $pOutput->setIndexPolicy('noindex');
     }
     // Use robot policy logic
     $policy = $this->page->getRobotPolicy('view', $pOutput);
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-robot-policy'), $this->msg("pageinfo-robot-{$policy['index']}"));
     if (isset($pageCounts['views'])) {
         // Number of views
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-views'), $lang->formatNum($pageCounts['views']));
     }
     if (isset($pageCounts['watchers'])) {
         // Number of page watchers
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-watchers'), $lang->formatNum($pageCounts['watchers']));
     }
     // Redirects to this page
     $whatLinksHere = SpecialPage::getTitleFor('Whatlinkshere', $title->getPrefixedText());
     $pageInfo['header-basic'][] = array(Linker::link($whatLinksHere, $this->msg('pageinfo-redirects-name')->escaped(), array(), array('hidelinks' => 1, 'hidetrans' => 1)), $this->msg('pageinfo-redirects-value')->numParams(count($title->getRedirectsHere())));
     // Is it counted as a content page?
     if ($this->page->isCountable()) {
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-contentpage'), $this->msg('pageinfo-contentpage-yes'));
     }
     // Subpages of this page, if subpages are enabled for the current NS
     if (MWNamespace::hasSubpages($title->getNamespace())) {
         $prefixIndex = SpecialPage::getTitleFor('Prefixindex', $title->getPrefixedText() . '/');
         $pageInfo['header-basic'][] = array(Linker::link($prefixIndex, $this->msg('pageinfo-subpages-name')->escaped()), $this->msg('pageinfo-subpages-value')->numParams($pageCounts['subpages']['total'], $pageCounts['subpages']['redirects'], $pageCounts['subpages']['nonredirects']));
     }
     // Page protection
     $pageInfo['header-restrictions'] = array();
     // Is this page effected by the cascading protection of something which includes it?
     if ($title->isCascadeProtected()) {
         $cascadingFrom = '';
         $sources = $title->getCascadeProtectionSources();
         // Array deferencing is in PHP 5.4 :(
         foreach ($sources[0] as $sourceTitle) {
             $cascadingFrom .= Html::rawElement('li', array(), Linker::linkKnown($sourceTitle));
         }
         $cascadingFrom = Html::rawElement('ul', array(), $cascadingFrom);
         $pageInfo['header-restrictions'][] = array($this->msg('pageinfo-protect-cascading-from'), $cascadingFrom);
     }
     // Is out protection set to cascade to other pages?
     if ($title->areRestrictionsCascading()) {
         $pageInfo['header-restrictions'][] = array($this->msg('pageinfo-protect-cascading'), $this->msg('pageinfo-protect-cascading-yes'));
     }
     // Page protection
     foreach ($title->getRestrictionTypes() as $restrictionType) {
         $protectionLevel = implode(', ', $title->getRestrictions($restrictionType));
         if ($protectionLevel == '') {
             // Allow all users
             $message = $this->msg('protect-default')->escaped();
         } else {
             // Administrators only
             $message = $this->msg("protect-level-{$protectionLevel}");
             if ($message->isDisabled()) {
                 // Require "$1" permission
                 $message = $this->msg("protect-fallback", $protectionLevel)->parse();
             } else {
                 $message = $message->escaped();
             }
         }
         $pageInfo['header-restrictions'][] = array($this->msg("restriction-{$restrictionType}"), $message);
     }
     if (!$this->page->exists()) {
         return $pageInfo;
     }
     // Edit history
     $pageInfo['header-edits'] = array();
     $firstRev = $this->page->getOldestRevision();
     // Page creator
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-firstuser'), Linker::revUserTools($firstRev));
     // Date of page creation
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-firsttime'), Linker::linkKnown($title, $lang->userTimeAndDate($firstRev->getTimestamp(), $user), array(), array('oldid' => $firstRev->getId())));
     // Latest editor
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-lastuser'), Linker::revUserTools($this->page->getRevision()));
     // Date of latest edit
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-lasttime'), Linker::linkKnown($title, $lang->userTimeAndDate($this->page->getTimestamp(), $user), array(), array('oldid' => $this->page->getLatest())));
     // Total number of edits
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-edits'), $lang->formatNum($pageCounts['edits']));
     // Total number of distinct authors
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-authors'), $lang->formatNum($pageCounts['authors']));
     // Recent number of edits (within past 30 days)
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-recent-edits', $lang->formatDuration($wgRCMaxAge)), $lang->formatNum($pageCounts['recent_edits']));
     // Recent number of distinct authors
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-recent-authors'), $lang->formatNum($pageCounts['recent_authors']));
     // Array of MagicWord objects
     $magicWords = MagicWord::getDoubleUnderscoreArray();
     // Array of magic word IDs
     $wordIDs = $magicWords->names;
     // Array of IDs => localized magic words
     $localizedWords = $wgContLang->getMagicWords();
     $listItems = array();
     foreach ($pageProperties as $property => $value) {
         if (in_array($property, $wordIDs)) {
             $listItems[] = Html::element('li', array(), $localizedWords[$property][1]);
         }
     }
     $localizedList = Html::rawElement('ul', array(), implode('', $listItems));
     $hiddenCategories = $this->page->getHiddenCategories();
     $transcludedTemplates = $title->getTemplateLinksFrom();
     if (count($listItems) > 0 || count($hiddenCategories) > 0 || count($transcludedTemplates) > 0) {
         // Page properties
         $pageInfo['header-properties'] = array();
         // Magic words
         if (count($listItems) > 0) {
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-magic-words')->numParams(count($listItems)), $localizedList);
         }
         // Hidden categories
         if (count($hiddenCategories) > 0) {
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-hidden-categories')->numParams(count($hiddenCategories)), Linker::formatHiddenCategories($hiddenCategories));
         }
         // Transcluded templates
         if (count($transcludedTemplates) > 0) {
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-templates')->numParams(count($transcludedTemplates)), Linker::formatTemplates($transcludedTemplates));
         }
     }
     return $pageInfo;
 }
 /**
  * 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);
 }
Beispiel #17
0
 private function formatLangLinks($links)
 {
     $result = array();
     foreach ($links as $link) {
         $entry = array();
         $bits = explode(':', $link, 2);
         $title = Title::newFromText($link);
         $entry['lang'] = $bits[0];
         if ($title) {
             $entry['url'] = wfExpandUrl($title->getFullURL(), PROTO_CURRENT);
             // localised language name in 'uselang' language
             $entry['langname'] = Language::fetchLanguageName($title->getInterwiki(), $this->getLanguage()->getCode());
             // native language name
             $entry['autonym'] = Language::fetchLanguageName($title->getInterwiki());
         }
         ApiResult::setContentValue($entry, 'title', $bits[1]);
         $result[] = $entry;
     }
     return $result;
 }
 /**
  * @param string $key
  * @return array
  */
 public function figureMessage($key)
 {
     global $wgLanguageCode;
     $pieces = explode('/', $key);
     if (count($pieces) < 2) {
         return array($key, $wgLanguageCode);
     }
     $lang = array_pop($pieces);
     if (!Language::fetchLanguageName($lang, null, 'mw')) {
         return array($key, $wgLanguageCode);
     }
     $message = implode('/', $pieces);
     return array($message, $lang);
 }
$output->element('Translated', true);
$output->element('%', true);
$output->element('Obsolete', true);
$output->element('%', true);
$output->element('Problematic', true);
$output->element('%', true);
$output->blockend();
$wgGeneralMessages = $wgLanguages->getGeneralMessages();
$wgRequiredMessagesNumber = count($wgGeneralMessages['required']);
foreach ($wgLanguages->getLanguages() as $code) {
    # Don't check English, RTL English or dummy language codes
    if ($code == 'en' || $code == 'enRTL' || is_array($wgDummyLanguageCodes) && isset($wgDummyLanguageCodes[$code])) {
        continue;
    }
    # Calculate the numbers
    $language = Language::fetchLanguageName($code);
    $fallback = $wgLanguages->getFallback($code);
    $messages = $wgLanguages->getMessages($code);
    $messagesNumber = count($messages['translated']);
    $requiredMessagesNumber = count($messages['required']);
    $requiredMessagesPercent = $output->formatPercent($requiredMessagesNumber, $wgRequiredMessagesNumber);
    $obsoleteMessagesNumber = count($messages['obsolete']);
    $obsoleteMessagesPercent = $output->formatPercent($obsoleteMessagesNumber, $messagesNumber, true);
    $messagesWithMismatchVariables = $wgLanguages->getMessagesWithMismatchVariables($code);
    $emptyMessages = $wgLanguages->getEmptyMessages($code);
    $messagesWithWhitespace = $wgLanguages->getMessagesWithWhitespace($code);
    $nonXHTMLMessages = $wgLanguages->getNonXHTMLMessages($code);
    $messagesWithWrongChars = $wgLanguages->getMessagesWithWrongChars($code);
    $problematicMessagesNumber = count(array_unique(array_merge($messagesWithMismatchVariables, $emptyMessages, $messagesWithWhitespace, $nonXHTMLMessages, $messagesWithWrongChars)));
    $problematicMessagesPercent = $output->formatPercent($problematicMessagesNumber, $messagesNumber, true);
    # Output them
Beispiel #20
0
 /**
  * Prepare an array with the details we want to insert into the athena_page_details table
  *
  * @param $namespace int
  * @param $title string
  * @param $content string
  * @param $comment string
  * @param $user int
  * @return array
  */
 static function preparePageDetailsArray($namespace, $title, $content, $comment, $user)
 {
     $dbw = wfGetDB(DB_MASTER);
     $title = $dbw->strencode($title);
     $content = $dbw->strencode($content);
     $insertArray = array('apd_namespace' => $namespace, 'apd_title' => $title, 'apd_content' => $content, 'apd_user' => $user, 'page_id' => 'NULL', 'rev_id' => 'NULL');
     if ($comment != '') {
         $comment = $dbw->strencode($comment);
         $insertArray['apd_comment'] = $comment;
     }
     $language = AthenaHelper::getTextLanguage($content);
     $insertArray['apd_language'] = $dbw->strencode(Language::fetchLanguageName($language));
     return $insertArray;
 }
 function fetchLanguageName($code, $inLanguage)
 {
     $this->checkType('fetchLanguageName', 1, $code, 'string');
     $this->checkTypeOptional('fetchLanguageName', 2, $inLanguage, 'string', null);
     return array(Language::fetchLanguageName($code, $inLanguage));
 }
Beispiel #22
0
 /**
  * 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;
 }
Beispiel #23
0
 /**
  * @deprecated since 1.18 No modern skin generates language links this way,
  * please use language links data to generate your own HTML.
  * @param $languages array
  * @return string
  */
 private function languagesHtml($languages)
 {
     wfDeprecated(__METHOD__, '1.18');
     $this->setWarning('"action=parse&prop=languageshtml" is deprecated ' . 'and will be removed in MediaWiki 1.24. Use "prop=langlinks" ' . 'to generate your own HTML.');
     global $wgContLang, $wgHideInterlanguageLinks;
     if ($wgHideInterlanguageLinks || count($languages) == 0) {
         return '';
     }
     $s = htmlspecialchars(wfMessage('otherlanguages')->text() . wfMessage('colon-separator')->text());
     $langs = array();
     foreach ($languages as $l) {
         $nt = Title::newFromText($l);
         $text = Language::fetchLanguageName($nt->getInterwiki());
         $langs[] = Html::element('a', array('href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => 'external'), $text == '' ? $l : $text);
     }
     $s .= implode(wfMessage('pipe-separator')->escaped(), $langs);
     if ($wgContLang->isRTL()) {
         $s = Html::rawElement('span', array('dir' => 'LTR'), $s);
     }
     return $s;
 }
 function showList()
 {
     global $wgInterwikiCentralDB, $wgInterwikiViewOnly;
     $canModify = $this->canModify();
     // Build lists
     if (!method_exists('Interwiki', 'getAllPrefixes')) {
         // version 2.0 is not backwards compatible (but will still display a nice error)
         $this->error('interwiki_error');
         return;
     }
     $iwPrefixes = Interwiki::getAllPrefixes(null);
     $iwGlobalPrefixes = array();
     if ($wgInterwikiCentralDB !== null && $wgInterwikiCentralDB !== wfWikiId()) {
         // Fetch list from global table
         $dbrCentralDB = wfGetDB(DB_SLAVE, array(), $wgInterwikiCentralDB);
         $res = $dbrCentralDB->select('interwiki', '*', false, __METHOD__);
         $retval = array();
         foreach ($res as $row) {
             $row = (array) $row;
             if (!Language::fetchLanguageName($row['iw_prefix'])) {
                 $retval[] = $row;
             }
         }
         $iwGlobalPrefixes = $retval;
     }
     // Split out language links
     $iwLocalPrefixes = array();
     $iwLanguagePrefixes = array();
     foreach ($iwPrefixes as $iwPrefix) {
         if (Language::fetchLanguageName($iwPrefix['iw_prefix'])) {
             $iwLanguagePrefixes[] = $iwPrefix;
         } else {
             $iwLocalPrefixes[] = $iwPrefix;
         }
     }
     // Page intro content
     $this->getOutput()->addWikiMsg('interwiki_intro');
     // Add 'view log' link when possible
     if ($wgInterwikiViewOnly === false) {
         $logLink = Linker::link(SpecialPage::getTitleFor('Log', 'interwiki'), $this->msg('interwiki-logtext')->escaped());
         $this->getOutput()->addHTML('<p class="mw-interwiki-log">' . $logLink . '</p>');
     }
     // Add 'add' link
     if ($canModify) {
         if (count($iwGlobalPrefixes) !== 0) {
             $addtext = $this->msg('interwiki-addtext-local')->escaped();
         } else {
             $addtext = $this->msg('interwiki_addtext')->escaped();
         }
         $addlink = Linker::linkKnown($this->getPageTitle('add'), $addtext);
         $this->getOutput()->addHTML('<p class="mw-interwiki-addlink">' . $addlink . '</p>');
     }
     $this->getOutput()->addWikiMsg('interwiki-legend');
     if (!is_array($iwPrefixes) || count($iwPrefixes) === 0) {
         if (!is_array($iwGlobalPrefixes) || count($iwGlobalPrefixes) === 0) {
             // If the interwiki table(s) are empty, display an error message
             $this->error('interwiki_error');
             return;
         }
     }
     // Add the global table
     if (count($iwGlobalPrefixes) !== 0) {
         $this->getOutput()->addHTML('<h2 id="interwikitable-global">' . $this->msg('interwiki-global-links')->parse() . '</h2>');
         $this->getOutput()->addWikiMsg('interwiki-global-description');
         // $canModify is false here because this is just a display of remote data
         $this->makeTable(false, $iwGlobalPrefixes);
     }
     // Add the local table
     if (count($iwLocalPrefixes) !== 0) {
         if (count($iwGlobalPrefixes) !== 0) {
             $this->getOutput()->addHTML('<h2 id="interwikitable-local">' . $this->msg('interwiki-local-links')->parse() . '</h2>');
             $this->getOutput()->addWikiMsg('interwiki-local-description');
         } else {
             $this->getOutput()->addHTML('<h2 id="interwikitable-local">' . $this->msg('interwiki-links')->parse() . '</h2>');
             $this->getOutput()->addWikiMsg('interwiki-description');
         }
         $this->makeTable($canModify, $iwLocalPrefixes);
     }
     // Add the language table
     if (count($iwLanguagePrefixes) !== 0) {
         $this->getOutput()->addHTML('<h2 id="interwikitable-language">' . $this->msg('interwiki-language-links')->parse() . '</h2>');
         $this->getOutput()->addWikiMsg('interwiki-language-description');
         $this->makeTable($canModify, $iwLanguagePrefixes);
     }
 }
Beispiel #25
0
 /**
  * Process [[ ]] wikilinks (RIL)
  * @param $s
  * @throws MWException
  * @return LinkHolderArray
  *
  * @private
  */
 function replaceInternalLinks2(&$s)
 {
     wfProfileIn(__METHOD__);
     wfProfileIn(__METHOD__ . '-setup');
     static $tc = false, $e1, $e1_img;
     # the % is needed to support urlencoded titles as well
     if (!$tc) {
         $tc = Title::legalChars() . '#%';
         # Match a link having the form [[namespace:link|alternate]]trail
         $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
         # Match cases where there is no "]]", which might still be images
         $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
     }
     $holders = new LinkHolderArray($this);
     # split the entire text string on occurrences of [[
     $a = StringUtils::explode('[[', ' ' . $s);
     # get the first element (all text up to first [[), and remove the space we added
     $s = $a->current();
     $a->next();
     $line = $a->current();
     # Workaround for broken ArrayIterator::next() that returns "void"
     $s = substr($s, 1);
     $useLinkPrefixExtension = $this->getTargetLanguage()->linkPrefixExtension();
     $e2 = null;
     if ($useLinkPrefixExtension) {
         # Match the end of a line for a word that's not followed by whitespace,
         # e.g. in the case of 'The Arab al[[Razi]]', 'al' will be matched
         global $wgContLang;
         $charset = $wgContLang->linkPrefixCharset();
         $e2 = "/^((?>.*[^{$charset}]|))(.+)\$/sDu";
     }
     if (is_null($this->mTitle)) {
         wfProfileOut(__METHOD__ . '-setup');
         wfProfileOut(__METHOD__);
         throw new MWException(__METHOD__ . ": \$this->mTitle is null\n");
     }
     $nottalk = !$this->mTitle->isTalkPage();
     if ($useLinkPrefixExtension) {
         $m = array();
         if (preg_match($e2, $s, $m)) {
             $first_prefix = $m[2];
         } else {
             $first_prefix = false;
         }
     } else {
         $prefix = '';
     }
     $useSubpages = $this->areSubpagesAllowed();
     wfProfileOut(__METHOD__ . '-setup');
     # Loop for each link
     for (; $line !== false && $line !== null; $a->next(), $line = $a->current()) {
         # Check for excessive memory usage
         if ($holders->isBig()) {
             # Too big
             # Do the existence check, replace the link holders and clear the array
             $holders->replace($s);
             $holders->clear();
         }
         if ($useLinkPrefixExtension) {
             wfProfileIn(__METHOD__ . '-prefixhandling');
             if (preg_match($e2, $s, $m)) {
                 $prefix = $m[2];
                 $s = $m[1];
             } else {
                 $prefix = '';
             }
             # first link
             if ($first_prefix) {
                 $prefix = $first_prefix;
                 $first_prefix = false;
             }
             wfProfileOut(__METHOD__ . '-prefixhandling');
         }
         $might_be_img = false;
         wfProfileIn(__METHOD__ . "-e1");
         if (preg_match($e1, $line, $m)) {
             # page with normal text or alt
             $text = $m[2];
             # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
             # [[Image:Foo.jpg|[http://example.com desc]]] <- having three ] in a row f***s up,
             # the real problem is with the $e1 regex
             # See bug 1300.
             #
             # Still some problems for cases where the ] is meant to be outside punctuation,
             # and no image is in sight. See bug 2095.
             #
             if ($text !== '' && substr($m[3], 0, 1) === ']' && strpos($text, '[') !== false) {
                 $text .= ']';
                 # so that replaceExternalLinks($text) works later
                 $m[3] = substr($m[3], 1);
             }
             # fix up urlencoded title texts
             if (strpos($m[1], '%') !== false) {
                 # Should anchors '#' also be rejected?
                 $m[1] = str_replace(array('<', '>'), array('&lt;', '&gt;'), rawurldecode($m[1]));
             }
             $trail = $m[3];
         } elseif (preg_match($e1_img, $line, $m)) {
             # Invalid, but might be an image with a link in its caption
             $might_be_img = true;
             $text = $m[2];
             if (strpos($m[1], '%') !== false) {
                 $m[1] = rawurldecode($m[1]);
             }
             $trail = "";
         } else {
             # Invalid form; output directly
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-e1");
             continue;
         }
         wfProfileOut(__METHOD__ . "-e1");
         wfProfileIn(__METHOD__ . "-misc");
         # Don't allow internal links to pages containing
         # PROTO: where PROTO is a valid URL protocol; these
         # should be external links.
         if (preg_match('/^(?i:' . $this->mUrlProtocols . ')/', $m[1])) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-misc");
             continue;
         }
         # Make subpage if necessary
         if ($useSubpages) {
             $link = $this->maybeDoSubpageLink($m[1], $text);
         } else {
             $link = $m[1];
         }
         $noforce = substr($m[1], 0, 1) !== ':';
         if (!$noforce) {
             # Strip off leading ':'
             $link = substr($link, 1);
         }
         wfProfileOut(__METHOD__ . "-misc");
         wfProfileIn(__METHOD__ . "-title");
         $nt = Title::newFromText($this->mStripState->unstripNoWiki($link));
         if ($nt === null) {
             $s .= $prefix . '[[' . $line;
             wfProfileOut(__METHOD__ . "-title");
             continue;
         }
         $ns = $nt->getNamespace();
         $iw = $nt->getInterwiki();
         wfProfileOut(__METHOD__ . "-title");
         if ($might_be_img) {
             # if this is actually an invalid link
             wfProfileIn(__METHOD__ . "-might_be_img");
             if ($ns == NS_FILE && $noforce) {
                 # but might be an image
                 $found = false;
                 while (true) {
                     # look at the next 'line' to see if we can close it there
                     $a->next();
                     $next_line = $a->current();
                     if ($next_line === false || $next_line === null) {
                         break;
                     }
                     $m = explode(']]', $next_line, 3);
                     if (count($m) == 3) {
                         # the first ]] closes the inner link, the second the image
                         $found = true;
                         $text .= "[[{$m[0]}]]{$m[1]}";
                         $trail = $m[2];
                         break;
                     } elseif (count($m) == 2) {
                         # if there's exactly one ]] that's fine, we'll keep looking
                         $text .= "[[{$m[0]}]]{$m[1]}";
                     } else {
                         # if $next_line is invalid too, we need look no further
                         $text .= '[[' . $next_line;
                         break;
                     }
                 }
                 if (!$found) {
                     # we couldn't find the end of this imageLink, so output it raw
                     # but don't ignore what might be perfectly normal links in the text we've examined
                     $holders->merge($this->replaceInternalLinks2($text));
                     $s .= "{$prefix}[[{$link}|{$text}";
                     # note: no $trail, because without an end, there *is* no trail
                     wfProfileOut(__METHOD__ . "-might_be_img");
                     continue;
                 }
             } else {
                 # it's not an image, so output it raw
                 $s .= "{$prefix}[[{$link}|{$text}";
                 # note: no $trail, because without an end, there *is* no trail
                 wfProfileOut(__METHOD__ . "-might_be_img");
                 continue;
             }
             wfProfileOut(__METHOD__ . "-might_be_img");
         }
         $wasblank = $text == '';
         if ($wasblank) {
             $text = $link;
         } else {
             # Bug 4598 madness. Handle the quotes only if they come from the alternate part
             # [[Lista d''e paise d''o munno]] -> <a href="...">Lista d''e paise d''o munno</a>
             # [[Criticism of Harry Potter|Criticism of ''Harry Potter'']]
             #    -> <a href="Criticism of Harry Potter">Criticism of <i>Harry Potter</i></a>
             $text = $this->doQuotes($text);
         }
         # Link not escaped by : , create the various objects
         if ($noforce) {
             # Interwikis
             wfProfileIn(__METHOD__ . "-interwiki");
             if ($iw && $this->mOptions->getInterwikiMagic() && $nottalk && Language::fetchLanguageName($iw, null, 'mw')) {
                 // XXX: the above check prevents links to sites with identifiers that are not language codes
                 # Bug 24502: filter duplicates
                 if (!isset($this->mLangLinkLanguages[$iw])) {
                     $this->mLangLinkLanguages[$iw] = true;
                     $this->mOutput->addLanguageLink($nt->getFullText());
                 }
                 $s = rtrim($s . $prefix);
                 $s .= trim($trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut(__METHOD__ . "-interwiki");
                 continue;
             }
             wfProfileOut(__METHOD__ . "-interwiki");
             if ($ns == NS_FILE) {
                 wfProfileIn(__METHOD__ . "-image");
                 if (!wfIsBadImage($nt->getDBkey(), $this->mTitle)) {
                     if ($wasblank) {
                         # if no parameters were passed, $text
                         # becomes something like "File:Foo.png",
                         # which we don't want to pass on to the
                         # image generator
                         $text = '';
                     } else {
                         # recursively parse links inside the image caption
                         # actually, this will parse them in any other parameters, too,
                         # but it might be hard to fix that, and it doesn't matter ATM
                         $text = $this->replaceExternalLinks($text);
                         $holders->merge($this->replaceInternalLinks2($text));
                     }
                     # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
                     $s .= $prefix . $this->armorLinks($this->makeImage($nt, $text, $holders)) . $trail;
                 } else {
                     $s .= $prefix . $trail;
                 }
                 wfProfileOut(__METHOD__ . "-image");
                 continue;
             }
             if ($ns == NS_CATEGORY) {
                 wfProfileIn(__METHOD__ . "-category");
                 $s = rtrim($s . "\n");
                 # bug 87
                 if ($wasblank) {
                     $sortkey = $this->getDefaultSort();
                 } else {
                     $sortkey = $text;
                 }
                 $sortkey = Sanitizer::decodeCharReferences($sortkey);
                 $sortkey = str_replace("\n", '', $sortkey);
                 $sortkey = $this->getConverterLanguage()->convertCategoryKey($sortkey);
                 $this->mOutput->addCategory($nt->getDBkey(), $sortkey);
                 /**
                  * Strip the whitespace Category links produce, see bug 87
                  */
                 $s .= trim($prefix . $trail, "\n") == '' ? '' : $prefix . $trail;
                 wfProfileOut(__METHOD__ . "-category");
                 continue;
             }
         }
         # Self-link checking. For some languages, variants of the title are checked in
         # LinkHolderArray::doVariants() to allow batching the existence checks necessary
         # for linking to a different variant.
         if ($ns != NS_SPECIAL && $nt->equals($this->mTitle) && !$nt->hasFragment()) {
             $s .= $prefix . Linker::makeSelfLinkObj($nt, $text, '', $trail);
             continue;
         }
         # NS_MEDIA is a pseudo-namespace for linking directly to a file
         # @todo FIXME: Should do batch file existence checks, see comment below
         if ($ns == NS_MEDIA) {
             wfProfileIn(__METHOD__ . "-media");
             # Give extensions a chance to select the file revision for us
             $options = array();
             $descQuery = false;
             wfRunHooks('BeforeParserFetchFileAndTitle', array($this, $nt, &$options, &$descQuery));
             # Fetch and register the file (file title may be different via hooks)
             list($file, $nt) = $this->fetchFileAndTitle($nt, $options);
             # Cloak with NOPARSE to avoid replacement in replaceExternalLinks
             $s .= $prefix . $this->armorLinks(Linker::makeMediaLinkFile($nt, $file, $text)) . $trail;
             wfProfileOut(__METHOD__ . "-media");
             continue;
         }
         wfProfileIn(__METHOD__ . "-always_known");
         # Some titles, such as valid special pages or files in foreign repos, should
         # be shown as bluelinks even though they're not included in the page table
         #
         # @todo FIXME: isAlwaysKnown() can be expensive for file links; we should really do
         # batch file existence checks for NS_FILE and NS_MEDIA
         if ($iw == '' && $nt->isAlwaysKnown()) {
             $this->mOutput->addLink($nt);
             $s .= $this->makeKnownLinkHolder($nt, $text, array(), $trail, $prefix);
         } else {
             # Links will be added to the output link list after checking
             $s .= $holders->makeHolder($nt, $text, array(), $trail, $prefix);
         }
         wfProfileOut(__METHOD__ . "-always_known");
     }
     wfProfileOut(__METHOD__);
     return $holders;
 }
 function otherLanguages()
 {
     global $wgOut, $wgLang, $wgHideInterlanguageLinks;
     if ($wgHideInterlanguageLinks) {
         return '';
     }
     $a = $wgOut->getLanguageLinks();
     if (0 == count($a)) {
         return '';
     }
     $s = wfMessage('otherlanguages')->text() . wfMessage('colon-separator')->text();
     $first = true;
     if ($wgLang->isRTL()) {
         $s .= '<span dir="ltr">';
     }
     foreach ($a as $l) {
         if (!$first) {
             $s .= wfMessage('pipe-separator')->escaped();
         }
         $first = false;
         $nt = Title::newFromText($l);
         $text = Language::fetchLanguageName($nt->getInterwiki());
         $s .= Html::element('a', array('href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => "external"), $text == '' ? $l : $text);
     }
     if ($wgLang->isRTL()) {
         $s .= '</span>';
     }
     return $s;
 }
Beispiel #27
0
 /** Helper function for creating lists of translations.
  *
  * @param string $value value (this is not escaped)
  * @param string $lang lang code of item or false
  * @param $default Boolean if it is default value.
  * @param $noHtml Boolean If to avoid html (for back-compat)
  * @throws MWException
  * @return string language item (Note: despite how this looks,
  * this is treated as wikitext not html).
  */
 private static function langItem($value, $lang, $default = false, $noHtml = false)
 {
     if ($lang === false && $default === false) {
         throw new MWException('$lang and $default cannot both ' . 'be false.');
     }
     if ($noHtml) {
         $wrappedValue = $value;
     } else {
         $wrappedValue = '<span class="mw-metadata-lang-value">' . $value . '</span>';
     }
     if ($lang === false) {
         if ($noHtml) {
             return wfMessage('metadata-langitem-default', $wrappedValue)->text() . "\n\n";
         }
         /* else */
         return '<li class="mw-metadata-lang-default">' . wfMessage('metadata-langitem-default', $wrappedValue)->text() . "</li>\n";
     }
     $lowLang = strtolower($lang);
     $langName = Language::fetchLanguageName($lowLang);
     if ($langName === '') {
         //try just the base language name. (aka en-US -> en ).
         list($langPrefix) = explode('-', $lowLang, 2);
         $langName = Language::fetchLanguageName($langPrefix);
         if ($langName === '') {
             // give up.
             $langName = $lang;
         }
     }
     // else we have a language specified
     if ($noHtml) {
         return '*' . wfMessage('metadata-langitem', $wrappedValue, $langName, $lang)->text();
     }
     /* else: */
     $item = '<li class="mw-metadata-lang-code-' . $lang;
     if ($default) {
         $item .= ' mw-metadata-lang-default';
     }
     $item .= '" lang="' . $lang . '">';
     $item .= wfMessage('metadata-langitem', $wrappedValue, $langName, $lang)->text();
     $item .= "</li>\n";
     return $item;
 }
 protected function tuxLanguageSelector()
 {
     // Changes here must also be reflected when the language
     // changes on the client side
     global $wgTranslateDocumentationLanguageCode;
     if ($this->options['language'] === $wgTranslateDocumentationLanguageCode) {
         // The name will be displayed in the UI language,
         // so use for lang and dir
         $targetLangCode = $this->getLanguage()->getCode();
         $targetLangDir = $this->getLanguage()->getDir();
         $targetLangName = $this->msg('translate-documentation-language')->text();
     } else {
         $targetLangCode = $this->options['language'];
         $targetLangDir = Language::factory($this->options['language'])->getDir();
         $targetLangName = Language::fetchLanguageName($this->options['language']);
     }
     // No-break space is added for spacing after the label
     // and to ensure separation of words (in Arabic, for example)
     return Html::rawElement('div', array('class' => 'four columns ext-translate-language-selector'), Html::element('span', array('class' => 'ext-translate-language-selector-label'), $this->msg('tux-languageselector')->text()) . '&#160;' . Html::element('span', array('class' => 'uls', 'lang' => $targetLangCode, 'dir' => $targetLangDir), $targetLangName));
 }
Beispiel #29
0
 /**
  * @deprecated since 1.18 No modern skin generates language links this way, please use language links
  *                        data to generate your own HTML.
  * @param $languages array
  * @return string
  */
 private function languagesHtml($languages)
 {
     wfDeprecated(__METHOD__, '1.18');
     global $wgContLang, $wgHideInterlanguageLinks;
     if ($wgHideInterlanguageLinks || count($languages) == 0) {
         return '';
     }
     $s = htmlspecialchars(wfMessage('otherlanguages')->text() . wfMessage('colon-separator')->text());
     $langs = array();
     foreach ($languages as $l) {
         $nt = Title::newFromText($l);
         $text = Language::fetchLanguageName($nt->getInterwiki());
         $langs[] = Html::element('a', array('href' => $nt->getFullURL(), 'title' => $nt->getText(), 'class' => "external"), $text == '' ? $l : $text);
     }
     $s .= implode(wfMessage('pipe-separator')->escaped(), $langs);
     if ($wgContLang->isRTL()) {
         $s = Html::rawElement('span', array('dir' => "LTR"), $s);
     }
     return $s;
 }
Beispiel #30
0
 /**
  * Returns page information in an easily-manipulated format. Array keys are used so extensions
  * may add additional information in arbitrary positions. Array values are arrays with one
  * element to be rendered as a header, arrays with two elements to be rendered as a table row.
  *
  * @return array
  */
 protected function pageInfo()
 {
     global $wgContLang;
     $user = $this->getUser();
     $lang = $this->getLanguage();
     $title = $this->getTitle();
     $id = $title->getArticleID();
     $config = $this->context->getConfig();
     $cache = ObjectCache::getMainWANInstance();
     $memcKey = wfMemcKey('infoaction', sha1($title->getPrefixedText()), $this->page->getLatest());
     $pageCounts = $cache->get($memcKey);
     $version = isset($pageCounts['cacheversion']) ? $pageCounts['cacheversion'] : false;
     if ($pageCounts === false || $version !== self::CACHE_VERSION) {
         // Get page information that would be too "expensive" to retrieve by normal means
         $pageCounts = $this->pageCounts($title);
         $pageCounts['cacheversion'] = self::CACHE_VERSION;
         $cache->set($memcKey, $pageCounts);
     }
     // Get page properties
     $dbr = wfGetDB(DB_SLAVE);
     $result = $dbr->select('page_props', array('pp_propname', 'pp_value'), array('pp_page' => $id), __METHOD__);
     $pageProperties = array();
     foreach ($result as $row) {
         $pageProperties[$row->pp_propname] = $row->pp_value;
     }
     // Basic information
     $pageInfo = array();
     $pageInfo['header-basic'] = array();
     // Display title
     $displayTitle = $title->getPrefixedText();
     if (isset($pageProperties['displaytitle'])) {
         $displayTitle = $pageProperties['displaytitle'];
     }
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-display-title'), $displayTitle);
     // Is it a redirect? If so, where to?
     if ($title->isRedirect()) {
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-redirectsto'), Linker::link($this->page->getRedirectTarget()) . $this->msg('word-separator')->escaped() . $this->msg('parentheses')->rawParams(Linker::link($this->page->getRedirectTarget(), $this->msg('pageinfo-redirectsto-info')->escaped(), array(), array('action' => 'info')))->escaped());
     }
     // Default sort key
     $sortKey = $title->getCategorySortkey();
     if (isset($pageProperties['defaultsort'])) {
         $sortKey = $pageProperties['defaultsort'];
     }
     $sortKey = htmlspecialchars($sortKey);
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-default-sort'), $sortKey);
     // Page length (in bytes)
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-length'), $lang->formatNum($title->getLength()));
     // Page ID (number not localised, as it's a database ID)
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-article-id'), $id);
     // Language in which the page content is (supposed to be) written
     $pageLang = $title->getPageLanguage()->getCode();
     if ($config->get('PageLanguageUseDB') && $this->getTitle()->userCan('pagelang', $this->getUser())) {
         // Link to Special:PageLanguage with pre-filled page title if user has permissions
         $titleObj = SpecialPage::getTitleFor('PageLanguage', $title->getPrefixedText());
         $langDisp = Linker::link($titleObj, $this->msg('pageinfo-language')->escaped());
     } else {
         // Display just the message
         $langDisp = $this->msg('pageinfo-language')->escaped();
     }
     $pageInfo['header-basic'][] = array($langDisp, Language::fetchLanguageName($pageLang, $lang->getCode()) . ' ' . $this->msg('parentheses', $pageLang)->escaped());
     // Content model of the page
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-content-model'), htmlspecialchars(ContentHandler::getLocalizedName($title->getContentModel())));
     // Search engine status
     $pOutput = new ParserOutput();
     if (isset($pageProperties['noindex'])) {
         $pOutput->setIndexPolicy('noindex');
     }
     if (isset($pageProperties['index'])) {
         $pOutput->setIndexPolicy('index');
     }
     // Use robot policy logic
     $policy = $this->page->getRobotPolicy('view', $pOutput);
     $pageInfo['header-basic'][] = array($this->msg('pageinfo-robot-policy'), $this->msg("pageinfo-robot-{$policy['index']}"));
     $unwatchedPageThreshold = $config->get('UnwatchedPageThreshold');
     if ($user->isAllowed('unwatchedpages') || $unwatchedPageThreshold !== false && $pageCounts['watchers'] >= $unwatchedPageThreshold) {
         // Number of page watchers
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-watchers'), $lang->formatNum($pageCounts['watchers']));
         if ($config->get('ShowUpdatedMarker') && isset($pageCounts['visitingWatchers'])) {
             $minToDisclose = $config->get('UnwatchedPageSecret');
             if ($pageCounts['visitingWatchers'] > $minToDisclose || $user->isAllowed('unwatchedpages')) {
                 $pageInfo['header-basic'][] = array($this->msg('pageinfo-visiting-watchers'), $lang->formatNum($pageCounts['visitingWatchers']));
             } else {
                 $pageInfo['header-basic'][] = array($this->msg('pageinfo-visiting-watchers'), $this->msg('pageinfo-few-visiting-watchers'));
             }
         }
     } elseif ($unwatchedPageThreshold !== false) {
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-watchers'), $this->msg('pageinfo-few-watchers')->numParams($unwatchedPageThreshold));
     }
     // Redirects to this page
     $whatLinksHere = SpecialPage::getTitleFor('Whatlinkshere', $title->getPrefixedText());
     $pageInfo['header-basic'][] = array(Linker::link($whatLinksHere, $this->msg('pageinfo-redirects-name')->escaped(), array(), array('hidelinks' => 1, 'hidetrans' => 1, 'hideimages' => $title->getNamespace() == NS_FILE)), $this->msg('pageinfo-redirects-value')->numParams(count($title->getRedirectsHere())));
     // Is it counted as a content page?
     if ($this->page->isCountable()) {
         $pageInfo['header-basic'][] = array($this->msg('pageinfo-contentpage'), $this->msg('pageinfo-contentpage-yes'));
     }
     // Subpages of this page, if subpages are enabled for the current NS
     if (MWNamespace::hasSubpages($title->getNamespace())) {
         $prefixIndex = SpecialPage::getTitleFor('Prefixindex', $title->getPrefixedText() . '/');
         $pageInfo['header-basic'][] = array(Linker::link($prefixIndex, $this->msg('pageinfo-subpages-name')->escaped()), $this->msg('pageinfo-subpages-value')->numParams($pageCounts['subpages']['total'], $pageCounts['subpages']['redirects'], $pageCounts['subpages']['nonredirects']));
     }
     if ($title->inNamespace(NS_CATEGORY)) {
         $category = Category::newFromTitle($title);
         // $allCount is the total number of cat members,
         // not the count of how many members are normal pages.
         $allCount = (int) $category->getPageCount();
         $subcatCount = (int) $category->getSubcatCount();
         $fileCount = (int) $category->getFileCount();
         $pagesCount = $allCount - $subcatCount - $fileCount;
         $pageInfo['category-info'] = array(array($this->msg('pageinfo-category-total'), $lang->formatNum($allCount)), array($this->msg('pageinfo-category-pages'), $lang->formatNum($pagesCount)), array($this->msg('pageinfo-category-subcats'), $lang->formatNum($subcatCount)), array($this->msg('pageinfo-category-files'), $lang->formatNum($fileCount)));
     }
     // Page protection
     $pageInfo['header-restrictions'] = array();
     // Is this page affected by the cascading protection of something which includes it?
     if ($title->isCascadeProtected()) {
         $cascadingFrom = '';
         $sources = $title->getCascadeProtectionSources();
         // Array deferencing is in PHP 5.4 :(
         foreach ($sources[0] as $sourceTitle) {
             $cascadingFrom .= Html::rawElement('li', array(), Linker::linkKnown($sourceTitle));
         }
         $cascadingFrom = Html::rawElement('ul', array(), $cascadingFrom);
         $pageInfo['header-restrictions'][] = array($this->msg('pageinfo-protect-cascading-from'), $cascadingFrom);
     }
     // Is out protection set to cascade to other pages?
     if ($title->areRestrictionsCascading()) {
         $pageInfo['header-restrictions'][] = array($this->msg('pageinfo-protect-cascading'), $this->msg('pageinfo-protect-cascading-yes'));
     }
     // Page protection
     foreach ($title->getRestrictionTypes() as $restrictionType) {
         $protectionLevel = implode(', ', $title->getRestrictions($restrictionType));
         if ($protectionLevel == '') {
             // Allow all users
             $message = $this->msg('protect-default')->escaped();
         } else {
             // Administrators only
             // Messages: protect-level-autoconfirmed, protect-level-sysop
             $message = $this->msg("protect-level-{$protectionLevel}");
             if ($message->isDisabled()) {
                 // Require "$1" permission
                 $message = $this->msg("protect-fallback", $protectionLevel)->parse();
             } else {
                 $message = $message->escaped();
             }
         }
         $expiry = $title->getRestrictionExpiry($restrictionType);
         $formattedexpiry = $this->msg('parentheses', $this->getLanguage()->formatExpiry($expiry))->escaped();
         $message .= $this->msg('word-separator')->escaped() . $formattedexpiry;
         // Messages: restriction-edit, restriction-move, restriction-create,
         // restriction-upload
         $pageInfo['header-restrictions'][] = array($this->msg("restriction-{$restrictionType}"), $message);
     }
     if (!$this->page->exists()) {
         return $pageInfo;
     }
     // Edit history
     $pageInfo['header-edits'] = array();
     $firstRev = $this->page->getOldestRevision();
     $lastRev = $this->page->getRevision();
     $batch = new LinkBatch();
     if ($firstRev) {
         $firstRevUser = $firstRev->getUserText(Revision::FOR_THIS_USER);
         if ($firstRevUser !== '') {
             $batch->add(NS_USER, $firstRevUser);
             $batch->add(NS_USER_TALK, $firstRevUser);
         }
     }
     if ($lastRev) {
         $lastRevUser = $lastRev->getUserText(Revision::FOR_THIS_USER);
         if ($lastRevUser !== '') {
             $batch->add(NS_USER, $lastRevUser);
             $batch->add(NS_USER_TALK, $lastRevUser);
         }
     }
     $batch->execute();
     if ($firstRev) {
         // Page creator
         $pageInfo['header-edits'][] = array($this->msg('pageinfo-firstuser'), Linker::revUserTools($firstRev));
         // Date of page creation
         $pageInfo['header-edits'][] = array($this->msg('pageinfo-firsttime'), Linker::linkKnown($title, htmlspecialchars($lang->userTimeAndDate($firstRev->getTimestamp(), $user)), array(), array('oldid' => $firstRev->getId())));
     }
     if ($lastRev) {
         // Latest editor
         $pageInfo['header-edits'][] = array($this->msg('pageinfo-lastuser'), Linker::revUserTools($lastRev));
         // Date of latest edit
         $pageInfo['header-edits'][] = array($this->msg('pageinfo-lasttime'), Linker::linkKnown($title, htmlspecialchars($lang->userTimeAndDate($this->page->getTimestamp(), $user)), array(), array('oldid' => $this->page->getLatest())));
     }
     // Total number of edits
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-edits'), $lang->formatNum($pageCounts['edits']));
     // Total number of distinct authors
     if ($pageCounts['authors'] > 0) {
         $pageInfo['header-edits'][] = array($this->msg('pageinfo-authors'), $lang->formatNum($pageCounts['authors']));
     }
     // Recent number of edits (within past 30 days)
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-recent-edits', $lang->formatDuration($config->get('RCMaxAge'))), $lang->formatNum($pageCounts['recent_edits']));
     // Recent number of distinct authors
     $pageInfo['header-edits'][] = array($this->msg('pageinfo-recent-authors'), $lang->formatNum($pageCounts['recent_authors']));
     // Array of MagicWord objects
     $magicWords = MagicWord::getDoubleUnderscoreArray();
     // Array of magic word IDs
     $wordIDs = $magicWords->names;
     // Array of IDs => localized magic words
     $localizedWords = $wgContLang->getMagicWords();
     $listItems = array();
     foreach ($pageProperties as $property => $value) {
         if (in_array($property, $wordIDs)) {
             $listItems[] = Html::element('li', array(), $localizedWords[$property][1]);
         }
     }
     $localizedList = Html::rawElement('ul', array(), implode('', $listItems));
     $hiddenCategories = $this->page->getHiddenCategories();
     if (count($listItems) > 0 || count($hiddenCategories) > 0 || $pageCounts['transclusion']['from'] > 0 || $pageCounts['transclusion']['to'] > 0) {
         $options = array('LIMIT' => $config->get('PageInfoTransclusionLimit'));
         $transcludedTemplates = $title->getTemplateLinksFrom($options);
         if ($config->get('MiserMode')) {
             $transcludedTargets = array();
         } else {
             $transcludedTargets = $title->getTemplateLinksTo($options);
         }
         // Page properties
         $pageInfo['header-properties'] = array();
         // Magic words
         if (count($listItems) > 0) {
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-magic-words')->numParams(count($listItems)), $localizedList);
         }
         // Hidden categories
         if (count($hiddenCategories) > 0) {
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-hidden-categories')->numParams(count($hiddenCategories)), Linker::formatHiddenCategories($hiddenCategories));
         }
         // Transcluded templates
         if ($pageCounts['transclusion']['from'] > 0) {
             if ($pageCounts['transclusion']['from'] > count($transcludedTemplates)) {
                 $more = $this->msg('morenotlisted')->escaped();
             } else {
                 $more = null;
             }
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-templates')->numParams($pageCounts['transclusion']['from']), Linker::formatTemplates($transcludedTemplates, false, false, $more));
         }
         if (!$config->get('MiserMode') && $pageCounts['transclusion']['to'] > 0) {
             if ($pageCounts['transclusion']['to'] > count($transcludedTargets)) {
                 $more = Linker::link($whatLinksHere, $this->msg('moredotdotdot')->escaped(), array(), array('hidelinks' => 1, 'hideredirs' => 1));
             } else {
                 $more = null;
             }
             $pageInfo['header-properties'][] = array($this->msg('pageinfo-transclusions')->numParams($pageCounts['transclusion']['to']), Linker::formatTemplates($transcludedTargets, false, false, $more));
         }
     }
     return $pageInfo;
 }