static function getDoubleUnderscoreRegex() { if ( WOMMagicWordParser::$mwa === null ) { WOMMagicWordParser::$mwa = MagicWord::getDoubleUnderscoreArray(); foreach ( WOMMagicWordParser::$mwa->names as $name ) { $magic = MagicWord::get( $name ); $case = intval( $magic->isCaseSensitive() ); foreach ( $magic->getSynonyms() as $i => $syn ) { $group = '(' . preg_quote( $syn, '/' ) . ')'; if ( WOMMagicWordParser::$underscores[$case] === '' ) { WOMMagicWordParser::$underscores[$case] = $group; } else { WOMMagicWordParser::$underscores[$case] .= '|' . $group; } } } if ( WOMMagicWordParser::$underscores[0] !== '' ) { WOMMagicWordParser::$underscores[0] = "/^(" . WOMMagicWordParser::$underscores[0] . ")/i"; } if ( WOMMagicWordParser::$underscores[1] !== '' ) { WOMMagicWordParser::$underscores[1] = "/^(" . WOMMagicWordParser::$underscores[1] . ")/"; } } return WOMMagicWordParser::$underscores; }
/** * Strip double-underscore items like __NOGALLERY__ and __NOTOC__ * Fills $this->mDoubleUnderscores, returns the modified text * * @param $text string * * @return string */ function doDoubleUnderscore($text) { wfProfileIn(__METHOD__); # The position of __TOC__ needs to be recorded $mw = MagicWord::get('toc'); if ($mw->match($text)) { $this->mShowToc = true; $this->mForceTocPosition = true; # Set a placeholder. At the end we'll fill it in with the TOC. $text = $mw->replace('<!--MWTOC-->', $text, 1); # Only keep the first one. $text = $mw->replace('', $text); } # Now match and remove the rest of them $mwa = MagicWord::getDoubleUnderscoreArray(); $this->mDoubleUnderscores = $mwa->matchAndRemove($text); if (isset($this->mDoubleUnderscores['nogallery'])) { $this->mOutput->mNoGallery = true; } if (isset($this->mDoubleUnderscores['notoc']) && !$this->mForceTocPosition) { $this->mShowToc = false; } if (isset($this->mDoubleUnderscores['hiddencat']) && $this->mTitle->getNamespace() == NS_CATEGORY) { $this->addTrackingCategory('hidden-category-category'); } # (bug 8068) Allow control over whether robots index a page. # # @todo FIXME: Bug 14899: __INDEX__ always overrides __NOINDEX__ here! This # is not desirable, the last one on the page should win. if (isset($this->mDoubleUnderscores['noindex']) && $this->mTitle->canUseNoindex()) { $this->mOutput->setIndexPolicy('noindex'); $this->addTrackingCategory('noindex-category'); } if (isset($this->mDoubleUnderscores['index']) && $this->mTitle->canUseNoindex()) { $this->mOutput->setIndexPolicy('index'); $this->addTrackingCategory('index-category'); } # Cache all double underscores in the database foreach ($this->mDoubleUnderscores as $key => $val) { $this->mOutput->setProperty($key, ''); } wfProfileOut(__METHOD__); return $text; }
/** * Strip double-underscore items like __NOGALLERY__ and __NOTOC__ * Fills $this->mDoubleUnderscores, returns the modified text */ function doDoubleUnderscore($text) { wfProfileIn(__METHOD__); // The position of __TOC__ needs to be recorded $mw = MagicWord::get('toc'); if ($mw->match($text)) { $this->mShowToc = true; $this->mForceTocPosition = true; // Set a placeholder. At the end we'll fill it in with the TOC. $text = $mw->replace('<!--MWTOC-->', $text, 1); // Only keep the first one. $text = $mw->replace('', $text); } // Now match and remove the rest of them $mwa = MagicWord::getDoubleUnderscoreArray(); $this->mDoubleUnderscores = $mwa->matchAndRemove($text); if (isset($this->mDoubleUnderscores['nogallery'])) { $this->mOutput->mNoGallery = true; } if (isset($this->mDoubleUnderscores['notoc']) && !$this->mForceTocPosition) { $this->mShowToc = false; } if (isset($this->mDoubleUnderscores['hiddencat']) && $this->mTitle->getNamespace() == NS_CATEGORY) { $this->mOutput->setProperty('hiddencat', 'y'); $containerCategory = Title::makeTitleSafe(NS_CATEGORY, wfMsgForContent('hidden-category-category')); if ($containerCategory) { $this->mOutput->addCategory($containerCategory->getDBkey(), $this->getDefaultSort()); } else { wfDebug(__METHOD__ . ": [[MediaWiki:hidden-category-category]] is not a valid title!\n"); } } # (bug 8068) Allow control over whether robots index a page. # # FIXME (bug 14899): __INDEX__ always overrides __NOINDEX__ here! This # is not desirable, the last one on the page should win. if (isset($this->mDoubleUnderscores['noindex'])) { $this->mOutput->setIndexPolicy('noindex'); } elseif (isset($this->mDoubleUnderscores['index'])) { $this->mOutput->setIndexPolicy('index'); } wfProfileOut(__METHOD__); return $text; }
/** * 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; }
/** * Shows page information on GET request. * * @return string Page information that will be added to the output */ public function onView() { global $wgContLang, $wgDisableCounters, $wgRCMaxAge, $wgRestrictionTypes; $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 $userCanViewUnwatchedPages = $user->isAllowed('unwatchedpages'); $pageInfo = self::pageCountInfo($title, $userCanViewUnwatchedPages, $wgDisableCounters); // 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; } $content = ''; $table = ''; // Header if (!$this->msg('pageinfo-header')->isDisabled()) { $content .= $this->msg('pageinfo-header ')->parse(); } // Basic information $content = $this->addHeader($content, $this->msg('pageinfo-header-basic')->text()); // Display title $displayTitle = $title->getPrefixedText(); if (!empty($pageProperties['displaytitle'])) { $displayTitle = $pageProperties['displaytitle']; } $table = $this->addRow($table, $this->msg('pageinfo-display-title')->escaped(), $displayTitle); // Default sort key $sortKey = $title->getCategorySortKey(); if (!empty($pageProperties['defaultsort'])) { $sortKey = $pageProperties['defaultsort']; } $table = $this->addRow($table, $this->msg('pageinfo-default-sort')->escaped(), $sortKey); // Page length (in bytes) $table = $this->addRow($table, $this->msg('pageinfo-length')->escaped(), $lang->formatNum($title->getLength())); // Page ID (number not localised, as it's a database ID.) $table = $this->addRow($table, $this->msg('pageinfo-article-id')->escaped(), $id); // Search engine status $pOutput = new ParserOutput(); if (isset($pageProperties['noindex'])) { $pOutput->setIndexPolicy('noindex'); } // Use robot policy logic $policy = $this->page->getRobotPolicy('view', $pOutput); $table = $this->addRow($table, $this->msg('pageinfo-robot-policy')->escaped(), $this->msg("pageinfo-robot-{$policy['index']}")->escaped()); if (!$wgDisableCounters) { // Number of views $table = $this->addRow($table, $this->msg('pageinfo-views')->escaped(), $lang->formatNum($pageInfo['views'])); } if ($userCanViewUnwatchedPages) { // Number of page watchers $table = $this->addRow($table, $this->msg('pageinfo-watchers')->escaped(), $lang->formatNum($pageInfo['watchers'])); } // Redirects to this page $whatLinksHere = SpecialPage::getTitleFor('Whatlinkshere', $title->getPrefixedText()); $table = $this->addRow($table, Linker::link($whatLinksHere, $this->msg('pageinfo-redirects-name')->escaped(), array(), array('hidelinks' => 1, 'hidetrans' => 1)), $this->msg('pageinfo-redirects-value')->numParams(count($title->getRedirectsHere()))->escaped()); // Subpages of this page, if subpages are enabled for the current NS if (MWNamespace::hasSubpages($title->getNamespace())) { $prefixIndex = SpecialPage::getTitleFor('Prefixindex', $title->getPrefixedText() . '/'); $table = $this->addRow($table, Linker::link($prefixIndex, $this->msg('pageinfo-subpages-name')->escaped()), $this->msg('pageinfo-subpages-value')->numParams($pageInfo['subpages']['total'], $pageInfo['subpages']['redirects'], $pageInfo['subpages']['nonredirects'])->escaped()); } // Page protection $content = $this->addTable($content, $table); $content = $this->addHeader($content, $this->msg('pageinfo-header-restrictions')->text()); $table = ''; // Page protection foreach ($wgRestrictionTypes 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(); } } $table = $this->addRow($table, $this->msg('pageinfo-restriction', $this->msg("restriction-{$restrictionType}")->plain())->parse(), $message); } // Edit history $content = $this->addTable($content, $table); $content = $this->addHeader($content, $this->msg('pageinfo-header-edits')->text()); $table = ''; $firstRev = $this->page->getOldestRevision(); // Page creator $table = $this->addRow($table, $this->msg('pageinfo-firstuser')->escaped(), $firstRev->getUserText(Revision::FOR_THIS_USER, $user)); // Date of page creation $table = $this->addRow($table, $this->msg('pageinfo-firsttime')->escaped(), Linker::linkKnown($title, $lang->userTimeAndDate($firstRev->getTimestamp(), $user), array(), array('oldid' => $firstRev->getId()))); // Latest editor $table = $this->addRow($table, $this->msg('pageinfo-lastuser')->escaped(), $this->page->getUserText(Revision::FOR_THIS_USER, $user)); // Date of latest edit $table = $this->addRow($table, $this->msg('pageinfo-lasttime')->escaped(), Linker::linkKnown($title, $lang->userTimeAndDate($this->page->getTimestamp(), $user), array(), array('oldid' => $this->page->getLatest()))); // Total number of edits $table = $this->addRow($table, $this->msg('pageinfo-edits')->escaped(), $lang->formatNum($pageInfo['edits'])); // Total number of distinct authors $table = $this->addRow($table, $this->msg('pageinfo-authors')->escaped(), $lang->formatNum($pageInfo['authors'])); // Recent number of edits (within past 30 days) $table = $this->addRow($table, $this->msg('pageinfo-recent-edits', $lang->formatDuration($wgRCMaxAge))->escaped(), $lang->formatNum($pageInfo['recent_edits'])); // Recent number of distinct authors $table = $this->addRow($table, $this->msg('pageinfo-recent-authors')->escaped(), $lang->formatNum($pageInfo['recent_authors'])); $content = $this->addTable($content, $table); // 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 $content = $this->addHeader($content, $this->msg('pageinfo-header-properties')->text()); $table = ''; // Magic words if (count($listItems) > 0) { $table = $this->addRow($table, $this->msg('pageinfo-magic-words')->numParams(count($listItems))->escaped(), $localizedList); } // Hide "This page is a member of # hidden categories explanation $content .= Html::element('style', array(), '.mw-hiddenCategoriesExplanation { display: none; }'); // Hidden categories if (count($hiddenCategories) > 0) { $table = $this->addRow($table, $this->msg('pageinfo-hidden-categories')->numParams(count($hiddenCategories))->escaped(), Linker::formatHiddenCategories($hiddenCategories)); } // Hide "Templates used on this page:" explanation $content .= Html::element('style', array(), '.mw-templatesUsedExplanation { display: none; }'); // Transcluded templates if (count($transcludedTemplates) > 0) { $table = $this->addRow($table, $this->msg('pageinfo-templates')->numParams(count($transcludedTemplates))->escaped(), Linker::formatTemplates($transcludedTemplates)); } $content = $this->addTable($content, $table); } // Footer if (!$this->msg('pageinfo-footer')->isDisabled()) { $content .= $this->msg('pageinfo-footer')->parse(); } return $content; }
/** * 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; }
public function doDoubleUnderscore($text) { wfProfileIn(__METHOD__); $mwa = MagicWord::getDoubleUnderscoreArray(); $regexes = $mwa->getRegex(); foreach ($regexes as $regex) { if ($regex === '') { continue; } $text = preg_replace_callback($regex, 'RTEParser::doDoubleUnderscoreReplace', $text); } wfProfileOut(__METHOD__); return $text; }