/** * @param Title $rootPage The root page under which all pages should be * created */ public function __construct(Title $rootPage) { if (!MWNamespace::hasSubpages($rootPage->getNamespace())) { throw new MWException("The root page you specified, {$rootPage}, is in a " . "namespace where subpages are not allowed"); } $this->rootPage = $rootPage; }
/** * @param $title Title of page to check * @return bool */ public function canBeUsedOn(Title $title) { global $wgCollaborationHubAllowedNamespaces; $namespace = $title->getNamespace(); if (in_array($namespace, array_keys(array_filter($wgCollaborationHubAllowedNamespaces))) && MWNamespace::hasSubpages($namespace)) { return true; } return false; }
function cdbfGetMainSubpage($title) { if ($title->getNamespace() != NS_MAIN) { return true; } if (!MWNamespace::hasSubpages($title->getNamespace())) { return true; } $parts = explode('/', $title->getText()); return $parts[0]; }
private function setTitlesDefault() { $ns = $this->title->getNamespace(); $titles = array(); if (!MWNamespace::hasSubpages($ns)) { $titles[] = $this->title; } else { $explosion = explode('/', $this->title->getText()); $text = ''; foreach ($explosion as $atom) { $text .= $atom; $titles[] = Title::newFromText($text, $ns); $text .= '/'; } } $this->titles = $titles; }
/** * The GetDefaultSortkey hook. * Basically prefixes the normal sortkey with some of the subpage * parts of the current title. * * Example, if configured with "1,3..5,7" and given the * page 0/1/2/3/4/5/6/7/8 it would prefix the sortkey with * 1/3/4/5/7. Adding it to the normal sortkey, * resulting in "0/1/3/4/5/7\n0/1/2/3/4/5/6/7/8". * From there it might be further prefixed with whatever the * {{DEFUALTSORT for a page is. * * Another example: Configuration -3..-1 turns 1/2/3/4/5 -> 3/4 * and -3.. turns 1/2/3/4/5 -> 3/4/5 */ public static function onGetDefaultSortkey( $title, &$unprefixed ) { global $wgSubpageSortkeyDefault, $wgSubpageSortkeyByNamespace, $wgSubpageSortkeyIfNoSubpageUseFullName; $newSortkey = array(); $ns = $title->getNamespace(); if ( !MWNamespace::hasSubpages( $ns ) ) { // Do nothing return true; } if ( isset( $wgSubpageSortkeyByNamespace[$ns] ) ) { $descript = $wgSubpageSortkeyByNamespace[$ns]; } else { $descript = $wgSubpageSortkeyDefault; } $elms = explode( ',', $descript ); foreach( $elms as $item ) { $ranges = explode( '..', $item, 2 ); $start = intval( $ranges[0] ); if ( count( $ranges ) === 1 ) { $count = 1; } elseif ( $ranges[1] === '' ) { $count = false; } else { $count = intval( $ranges[1] ); } $newSortkey = array_merge( $newSortkey, self::getSubpage( $start, $count, $title ) ); } $newPrefix = implode( '/', $newSortkey ); // Don't prefix an extra \n if the prefix is empty. if ( $newPrefix !== '' || !$wgSubpageSortkeyIfNoSubpageUseFullName ) { $unprefixed = $newPrefix . "\n" . $unprefixed; } return true; }
public function execute() { global $wgLang, $wgParser; $provided = $this->getArg(0); $namespace = $wgLang->getNsIndex($provided); if (!$namespace) { $this->error("Invalid namespace provided: {$provided}"); return; } $namespaceName = $wgLang->getNsText($namespace); if (!MWNamespace::hasSubpages($namespace)) { $this->error("Subpages are not enabled in the {$namespaceName} namespace."); $this->error("In order to convert this namespace to Flow, you must enable subpages using:"); $this->error("\$wgNamespacesWithSubpages[{$namespace}] = true;"); return; } $noConvertTemplates = explode(',', $this->getOption('no-convert-templates', '')); if ($noConvertTemplates === array('')) { // explode( ',', '' ) returns array( '' ) $noConvertTemplates = array(); } // Convert to Title objects foreach ($noConvertTemplates as &$template) { $title = Title::newFromText($template, NS_TEMPLATE); if (!$title) { $this->error("Invalid template name: {$template}"); return; } $template = $title; } // @todo send to prod logger? $logger = new MaintenanceDebugLogger($this); $dbw = wfGetDB(DB_MASTER); $converter = new \Flow\Import\Converter($dbw, Flow\Container::get('importer'), $logger, FlowHooks::getOccupationController()->getTalkpageManager(), new Flow\Import\Wikitext\ConversionStrategy($wgParser, new Flow\Import\NullImportSourceStore(), $logger, $noConvertTemplates, $this->getOption('archive-pattern', null))); $logger->info("Starting conversion of {$namespaceName} namespace"); // Iterate over all existing pages of the namespace. $it = new NamespaceIterator($dbw, $namespace); // NamespaceIterator is an IteratorAggregate. Get an Iterator // so we can wrap that. $it = $it->getIterator(); $converter->convertAll($it); $logger->info("Finished conversion of {$namespaceName} namespace"); }
function register() { global $wgContLang, $wgNamespaceAliases, $wgNonincludableNamespaces; $lib = array('loadSiteStats' => array($this, 'loadSiteStats'), 'getNsIndex' => array($this, 'getNsIndex'), 'pagesInCategory' => array($this, 'pagesInCategory'), 'pagesInNamespace' => array($this, 'pagesInNamespace'), 'usersInGroup' => array($this, 'usersInGroup')); $info = array('siteName' => $GLOBALS['wgSitename'], 'server' => $GLOBALS['wgServer'], 'scriptPath' => $GLOBALS['wgScriptPath'], 'stylePath' => $GLOBALS['wgStylePath'], 'currentVersion' => SpecialVersion::getVersion()); if (!self::$namespacesCache) { $namespaces = array(); $namespacesByName = array(); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $canonical = MWNamespace::getCanonicalName($ns); $namespaces[$ns] = array('id' => $ns, 'name' => $title, 'canonicalName' => strtr($canonical, '_', ' '), 'hasSubpages' => MWNamespace::hasSubpages($ns), 'hasGenderDistinction' => MWNamespace::hasGenderDistinction($ns), 'isCapitalized' => MWNamespace::isCapitalized($ns), 'isContent' => MWNamespace::isContent($ns), 'isIncludable' => !($wgNonincludableNamespaces && in_array($ns, $wgNonincludableNamespaces)), 'isMovable' => MWNamespace::isMovable($ns), 'isSubject' => MWNamespace::isSubject($ns), 'isTalk' => MWNamespace::isTalk($ns), 'aliases' => array()); if ($ns >= NS_MAIN) { $namespaces[$ns]['subject'] = MWNamespace::getSubject($ns); $namespaces[$ns]['talk'] = MWNamespace::getTalk($ns); $namespaces[$ns]['associated'] = MWNamespace::getAssociated($ns); } else { $namespaces[$ns]['subject'] = $ns; } $namespacesByName[strtr($title, ' ', '_')] = $ns; if ($canonical) { $namespacesByName[$canonical] = $ns; } } $aliases = array_merge($wgNamespaceAliases, $wgContLang->getNamespaceAliases()); foreach ($aliases as $title => $ns) { if (!isset($namespacesByName[$title])) { $ct = count($namespaces[$ns]['aliases']); $namespaces[$ns]['aliases'][$ct + 1] = $title; $namespacesByName[$title] = $ns; } } $namespaces[NS_MAIN]['displayName'] = wfMessage('blanknamespace')->text(); self::$namespacesCache = $namespaces; } $info['namespaces'] = self::$namespacesCache; if (self::$siteStatsLoaded) { $stats = $this->loadSiteStats(); $info['stats'] = $stats[0]; } $this->getEngine()->registerInterface('mw.site.lua', $lib, $info); }
function register() { global $wgContLang, $wgNamespaceAliases, $wgDisableCounters; $lib = array('getNsIndex' => array($this, 'getNsIndex'), 'pagesInCategory' => array($this, 'pagesInCategory'), 'pagesInNamespace' => array($this, 'pagesInNamespace'), 'usersInGroup' => array($this, 'usersInGroup'), 'interwikiMap' => array($this, 'interwikiMap')); $info = array('siteName' => $GLOBALS['wgSitename'], 'server' => $GLOBALS['wgServer'], 'scriptPath' => $GLOBALS['wgScriptPath'], 'stylePath' => $GLOBALS['wgStylePath'], 'currentVersion' => SpecialVersion::getVersion()); if (!self::$namespacesCache || self::$namespacesCacheLang !== $wgContLang->getCode()) { $namespaces = array(); $namespacesByName = array(); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $canonical = MWNamespace::getCanonicalName($ns); $namespaces[$ns] = array('id' => $ns, 'name' => $title, 'canonicalName' => strtr($canonical, '_', ' '), 'hasSubpages' => MWNamespace::hasSubpages($ns), 'hasGenderDistinction' => MWNamespace::hasGenderDistinction($ns), 'isCapitalized' => MWNamespace::isCapitalized($ns), 'isContent' => MWNamespace::isContent($ns), 'isIncludable' => !MWNamespace::isNonincludable($ns), 'isMovable' => MWNamespace::isMovable($ns), 'isSubject' => MWNamespace::isSubject($ns), 'isTalk' => MWNamespace::isTalk($ns), 'defaultContentModel' => MWNamespace::getNamespaceContentModel($ns), 'aliases' => array()); if ($ns >= NS_MAIN) { $namespaces[$ns]['subject'] = MWNamespace::getSubject($ns); $namespaces[$ns]['talk'] = MWNamespace::getTalk($ns); $namespaces[$ns]['associated'] = MWNamespace::getAssociated($ns); } else { $namespaces[$ns]['subject'] = $ns; } $namespacesByName[strtr($title, ' ', '_')] = $ns; if ($canonical) { $namespacesByName[$canonical] = $ns; } } $aliases = array_merge($wgNamespaceAliases, $wgContLang->getNamespaceAliases()); foreach ($aliases as $title => $ns) { if (!isset($namespacesByName[$title]) && isset($namespaces[$ns])) { $ct = count($namespaces[$ns]['aliases']); $namespaces[$ns]['aliases'][$ct + 1] = $title; $namespacesByName[$title] = $ns; } } $namespaces[NS_MAIN]['displayName'] = wfMessage('blanknamespace')->inContentLanguage()->text(); self::$namespacesCache = $namespaces; self::$namespacesCacheLang = $wgContLang->getCode(); } $info['namespaces'] = self::$namespacesCache; $info['stats'] = array('pages' => (int) SiteStats::pages(), 'articles' => (int) SiteStats::articles(), 'files' => (int) SiteStats::images(), 'edits' => (int) SiteStats::edits(), 'views' => $wgDisableCounters ? null : (int) SiteStats::views(), 'users' => (int) SiteStats::users(), 'activeUsers' => (int) SiteStats::activeUsers(), 'admins' => (int) SiteStats::numberingroup('sysop')); return $this->getEngine()->registerInterface('mw.site.lua', $lib, $info); }
/** * @return string */ function subPageSubtitle() { global $wgLang; $out = $this->getOutput(); $subpages = ''; if (!wfRunHooks('SkinSubPageSubtitle', array(&$subpages, $this, $out))) { return $subpages; } if ($out->isArticle() && MWNamespace::hasSubpages($out->getTitle()->getNamespace())) { $ptext = $this->getTitle()->getPrefixedText(); if (preg_match('/\\//', $ptext)) { $links = explode('/', $ptext); array_pop($links); $c = 0; $growinglink = ''; $display = ''; foreach ($links as $link) { $growinglink .= $link; $display .= $link; $linkObj = Title::newFromText($growinglink); if (is_object($linkObj) && $linkObj->isKnown()) { $getlink = Linker::linkKnown($linkObj, htmlspecialchars($display)); $c++; if ($c > 1) { $subpages .= $wgLang->getDirMarkEntity() . $this->msg('pipe-separator')->escaped(); } else { $subpages .= '< '; } $subpages .= $getlink; $display = ''; } else { $display .= '/'; } $growinglink .= '/'; } } } return $subpages; }
/** * Move this page's subpages to be subpages of $nt * * @param $nt Title Move target * @param $auth bool Whether $wgUser's permissions should be checked * @param $reason string The reason for the move * @param $createRedirect bool Whether to create redirects from the old subpages to * the new ones Ignored if the user doesn't have the 'suppressredirect' right * @return mixed array with old page titles as keys, and strings (new page titles) or * arrays (errors) as values, or an error array with numeric indices if no pages * were moved */ public function moveSubpages($nt, $auth = true, $reason = '', $createRedirect = true) { global $wgMaximumMovedPages; // Check permissions if (!$this->userCan('move-subpages')) { return array('cant-move-subpages'); } // Do the source and target namespaces support subpages? if (!MWNamespace::hasSubpages($this->getNamespace())) { return array('namespace-nosubpages', MWNamespace::getCanonicalName($this->getNamespace())); } if (!MWNamespace::hasSubpages($nt->getNamespace())) { return array('namespace-nosubpages', MWNamespace::getCanonicalName($nt->getNamespace())); } $subpages = $this->getSubpages($wgMaximumMovedPages + 1); $retval = array(); $count = 0; foreach ($subpages as $oldSubpage) { $count++; if ($count > $wgMaximumMovedPages) { $retval[$oldSubpage->getPrefixedTitle()] = array('movepage-max-pages', $wgMaximumMovedPages); break; } // We don't know whether this function was called before // or after moving the root page, so check both // $this and $nt if ($oldSubpage->getArticleId() == $this->getArticleId() || $oldSubpage->getArticleID() == $nt->getArticleId()) { // When moving a page to a subpage of itself, // don't move it twice continue; } $newPageName = preg_replace('#^' . preg_quote($this->getDBkey(), '#') . '#', StringUtils::escapeRegexReplacement($nt->getDBkey()), $oldSubpage->getDBkey()); if ($oldSubpage->isTalkPage()) { $newNs = $nt->getTalkPage()->getNamespace(); } else { $newNs = $nt->getSubjectPage()->getNamespace(); } # Bug 14385: we need makeTitleSafe because the new page names may # be longer than 255 characters. $newSubpage = Title::makeTitleSafe($newNs, $newPageName); $success = $oldSubpage->moveTo($newSubpage, $auth, $reason, $createRedirect); if ($success === true) { $retval[$oldSubpage->getPrefixedText()] = $newSubpage->getPrefixedText(); } else { $retval[$oldSubpage->getPrefixedText()] = $success; } } return $retval; }
function showSubpages($title, $out) { global $wgLang; if (!MWNamespace::hasSubpages($title->getNamespace())) { return; } $subpages = $title->getSubpages(); $count = $subpages instanceof TitleArray ? $subpages->count() : 0; $out->wrapWikiMsg('== $1 ==', array('movesubpage', $count)); # No subpages. if ($count == 0) { $out->addWikiMsg('movenosubpage'); return; } $out->addWikiMsg('movesubpagetext', $wgLang->formatNum($count)); $skin = $this->getSkin(); $out->addHTML("<ul>\n"); foreach ($subpages as $subpage) { $link = $skin->link($subpage); $out->addHTML("<li>{$link}</li>\n"); } $out->addHTML("</ul>\n"); }
protected function showHeader() { global $wgOut, $wgUser, $wgMaxArticleSize, $wgLang; if ($this->mTitle->isTalkPage()) { $wgOut->addWikiMsg('talkpagetext'); } # Optional notices on a per-namespace and per-page basis $editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace(); $editnotice_ns_message = wfMessage($editnotice_ns)->inContentLanguage(); if ($editnotice_ns_message->exists()) { $wgOut->addWikiText($editnotice_ns_message->plain()); } if (MWNamespace::hasSubpages($this->mTitle->getNamespace())) { $parts = explode('/', $this->mTitle->getDBkey()); $editnotice_base = $editnotice_ns; while (count($parts) > 0) { $editnotice_base .= '-' . array_shift($parts); $editnotice_base_msg = wfMessage($editnotice_base)->inContentLanguage(); if ($editnotice_base_msg->exists()) { $wgOut->addWikiText($editnotice_base_msg->plain()); } } } else { # Even if there are no subpages in namespace, we still don't want / in MW ns. $editnoticeText = $editnotice_ns . '-' . str_replace('/', '-', $this->mTitle->getDBkey()); $editnoticeMsg = wfMessage($editnoticeText)->inContentLanguage(); if ($editnoticeMsg->exists()) { $wgOut->addWikiText($editnoticeMsg->plain()); } } if ($this->isConflict) { $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1\n</div>", 'explainconflict'); $this->edittime = $this->mArticle->getTimestamp(); } else { if ($this->section != '' && !$this->isSectionEditSupported()) { // We use $this->section to much before this and getVal('wgSection') directly in other places // at this point we can't reset $this->section to '' to fallback to non-section editing. // Someone is welcome to try refactoring though $wgOut->showErrorPage('sectioneditnotsupported-title', 'sectioneditnotsupported-text'); return false; } if ($this->section != '' && $this->section != 'new') { if (!$this->summary && !$this->preview && !$this->diff) { $sectionTitle = self::extractSectionTitle($this->textbox1); if ($sectionTitle !== false) { $this->summary = "/* {$sectionTitle} */ "; } } } if ($this->missingComment) { $wgOut->wrapWikiMsg("<div id='mw-missingcommenttext'>\n\$1\n</div>", 'missingcommenttext'); } if ($this->missingSummary && $this->section != 'new') { $wgOut->wrapWikiMsg("<div id='mw-missingsummary'>\n\$1\n</div>", 'missingsummary'); } if ($this->missingSummary && $this->section == 'new') { $wgOut->wrapWikiMsg("<div id='mw-missingcommentheader'>\n\$1\n</div>", 'missingcommentheader'); } if ($this->hookError !== '') { $wgOut->addWikiText($this->hookError); } if (!$this->checkUnicodeCompliantBrowser()) { $wgOut->addWikiMsg('nonunicodebrowser'); } if ($this->section != 'new') { $revision = $this->mArticle->getRevisionFetched(); if ($revision) { // Let sysop know that this will make private content public if saved if (!$revision->userCan(Revision::DELETED_TEXT)) { $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-permission'); } elseif ($revision->isDeleted(Revision::DELETED_TEXT)) { $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1\n</div>\n", 'rev-deleted-text-view'); } if (!$revision->isCurrent()) { $this->mArticle->setOldSubtitle($revision->getId()); $wgOut->addWikiMsg('editingold'); } } elseif ($this->mTitle->exists()) { // Something went wrong $wgOut->wrapWikiMsg("<div class='errorbox'>\n\$1\n</div>\n", array('missing-article', $this->mTitle->getPrefixedText(), wfMsgNoTrans('missingarticle-rev', $this->oldid))); } } } if (wfReadOnly()) { $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason())); } elseif ($wgUser->isAnon()) { if ($this->formtype != 'preview') { $wgOut->wrapWikiMsg("<div id=\"mw-anon-edit-warning\">\n\$1</div>", 'anoneditwarning'); } else { $wgOut->wrapWikiMsg("<div id=\"mw-anon-preview-warning\">\n\$1</div>", 'anonpreviewwarning'); } } else { if ($this->isCssJsSubpage) { # Check the skin exists if ($this->isWrongCaseCssJsPage) { $wgOut->wrapWikiMsg("<div class='error' id='mw-userinvalidcssjstitle'>\n\$1\n</div>", array('userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage())); } if ($this->getTitle()->isSubpageOf($wgUser->getUserPage())) { if ($this->formtype !== 'preview') { if ($this->isCssSubpage) { $wgOut->wrapWikiMsg("<div id='mw-usercssyoucanpreview'>\n\$1\n</div>", array('usercssyoucanpreview')); } if ($this->isJsSubpage) { $wgOut->wrapWikiMsg("<div id='mw-userjsyoucanpreview'>\n\$1\n</div>", array('userjsyoucanpreview')); } } } } } if ($this->mTitle->getNamespace() != NS_MEDIAWIKI && $this->mTitle->isProtected('edit')) { # Is the title semi-protected? if ($this->mTitle->isSemiProtected()) { $noticeMsg = 'semiprotectedpagewarning'; } else { # Then it must be protected based on static groups (regular) $noticeMsg = 'protectedpagewarning'; } LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'msgKey' => array($noticeMsg))); } if ($this->mTitle->isCascadeProtected()) { # Is this page under cascading protection from some source pages? list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources(); $notice = "<div class='mw-cascadeprotectedwarning'>\n\$1\n"; $cascadeSourcesCount = count($cascadeSources); if ($cascadeSourcesCount > 0) { # Explain, and list the titles responsible foreach ($cascadeSources as $page) { $notice .= '* [[:' . $page->getPrefixedText() . "]]\n"; } } $notice .= '</div>'; $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount)); } if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) { LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle, '', array('lim' => 1, 'showIfEmpty' => false, 'msgKey' => array('titleprotectedwarning'), 'wrap' => "<div class=\"mw-titleprotectedwarning\">\n\$1</div>")); } if ($this->kblength === false) { $this->kblength = (int) (strlen($this->textbox1) / 1024); } if ($this->tooBig || $this->kblength > $wgMaxArticleSize) { $wgOut->wrapWikiMsg("<div class='error' id='mw-edit-longpageerror'>\n\$1\n</div>", array('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize))); } else { if (!wfMessage('longpage-hint')->isDisabled()) { $wgOut->wrapWikiMsg("<div id='mw-edit-longpage-hint'>\n\$1\n</div>", array('longpage-hint', $wgLang->formatSize(strlen($this->textbox1)), strlen($this->textbox1))); } } }
/** * Returns page counts that would be too "expensive" to retrieve by normal means. * * @param Title $title Title to get counts for * @return array */ protected function pageCounts(Title $title) { $id = $title->getArticleID(); $config = $this->context->getConfig(); $dbrWatchlist = wfGetDB(DB_SLAVE, 'watchlist'); $result = array(); // Number of page watchers $watchers = (int) $dbrWatchlist->selectField('watchlist', 'COUNT(*)', array('wl_namespace' => $title->getNamespace(), 'wl_title' => $title->getDBkey()), __METHOD__); $result['watchers'] = $watchers; if ($config->get('ShowUpdatedMarker')) { // Threshold: last visited about 26 weeks before latest edit $updated = wfTimestamp(TS_UNIX, $this->page->getTimestamp()); $age = $config->get('WatchersMaxAge'); $threshold = $dbrWatchlist->timestamp($updated - $age); // Number of page watchers who also visited a "recent" edit $visitingWatchers = (int) $dbrWatchlist->selectField('watchlist', 'COUNT(*)', array('wl_namespace' => $title->getNamespace(), 'wl_title' => $title->getDBkey(), 'wl_notificationtimestamp >= ' . $dbrWatchlist->addQuotes($threshold) . ' OR wl_notificationtimestamp IS NULL'), __METHOD__); $result['visitingWatchers'] = $visitingWatchers; } $dbr = wfGetDB(DB_SLAVE); // Total number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(*)', array('rev_page' => $id), __METHOD__); $result['edits'] = $edits; // Total number of distinct authors if ($config->get('MiserMode')) { $result['authors'] = 0; } else { $result['authors'] = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', array('rev_page' => $id), __METHOD__); } // "Recent" threshold defined by RCMaxAge setting $threshold = $dbr->timestamp(time() - $config->get('RCMaxAge')); // Recent number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(rev_page)', array('rev_page' => $id, "rev_timestamp >= " . $dbr->addQuotes($threshold)), __METHOD__); $result['recent_edits'] = $edits; // Recent number of distinct authors $result['recent_authors'] = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', array('rev_page' => $id, "rev_timestamp >= " . $dbr->addQuotes($threshold)), __METHOD__); // Subpages (if enabled) if (MWNamespace::hasSubpages($title->getNamespace())) { $conds = array('page_namespace' => $title->getNamespace()); $conds[] = 'page_title ' . $dbr->buildLike($title->getDBkey() . '/', $dbr->anyString()); // Subpages of this page (redirects) $conds['page_is_redirect'] = 1; $result['subpages']['redirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, __METHOD__); // Subpages of this page (non-redirects) $conds['page_is_redirect'] = 0; $result['subpages']['nonredirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, __METHOD__); // Subpages of this page (total) $result['subpages']['total'] = $result['subpages']['redirects'] + $result['subpages']['nonredirects']; } // Counts for the number of transclusion links (to/from) if ($config->get('MiserMode')) { $result['transclusion']['to'] = 0; } else { $result['transclusion']['to'] = (int) $dbr->selectField('templatelinks', 'COUNT(tl_from)', array('tl_namespace' => $title->getNamespace(), 'tl_title' => $title->getDBkey()), __METHOD__); } $result['transclusion']['from'] = (int) $dbr->selectField('templatelinks', 'COUNT(*)', array('tl_from' => $title->getArticleID()), __METHOD__); return $result; }
/** * Get a list of rendered edit notices for this page. * * Array is keyed by the original message key, and values are rendered using parseAsBlock, so * they will already be wrapped in paragraphs. * * @since 1.21 * @param int $oldid Revision ID that's being edited * @return array */ public function getEditNotices($oldid = 0) { $notices = array(); # Optional notices on a per-namespace and per-page basis $editnotice_ns = 'editnotice-' . $this->getNamespace(); $editnotice_ns_message = wfMessage($editnotice_ns); if ($editnotice_ns_message->exists()) { $notices[$editnotice_ns] = $editnotice_ns_message->parseAsBlock(); } if (MWNamespace::hasSubpages($this->getNamespace())) { $parts = explode('/', $this->getDBkey()); $editnotice_base = $editnotice_ns; while (count($parts) > 0) { $editnotice_base .= '-' . array_shift($parts); $editnotice_base_msg = wfMessage($editnotice_base); if ($editnotice_base_msg->exists()) { $notices[$editnotice_base] = $editnotice_base_msg->parseAsBlock(); } } } else { # Even if there are no subpages in namespace, we still don't want / in MW ns. $editnoticeText = $editnotice_ns . '-' . str_replace('/', '-', $this->getDBkey()); $editnoticeMsg = wfMessage($editnoticeText); if ($editnoticeMsg->exists()) { $notices[$editnoticeText] = $editnoticeMsg->parseAsBlock(); } } wfRunHooks('TitleGetEditNotices', array($this, $oldid, &$notices)); return $notices; }
/** * Find the parent hub, if any. * Returns the first CollaborationHub Title found, even if more are higher up, or null if none * @param $title Title to start looking from * @return Title|null */ public static function getParentHub(Title $title) { global $wgCollaborationHubAllowedNamespaces; $namespace = $title->getNamespace(); if (MWNamespace::hasSubpages($namespace) && in_array($namespace, array_keys(array_filter($wgCollaborationHubAllowedNamespaces)))) { $parentTitle = $title->getBaseTitle(); while (!$title->equals($parentTitle)) { $parentRev = Revision::newFromTitle($parentTitle); if ($parentTitle->getContentModel() == 'CollaborationHubContent' && isset($parentRev)) { return $parentTitle; } // keep looking $title = $parentTitle; } } // Nothing was found return null; }
/** * @param $contextTitle Title * @param $target * @param $text * @return string */ static function normalizeSubpageLink($contextTitle, $target, &$text) { # Valid link forms: # Foobar -- normal # :Foobar -- override special treatment of prefix (images, language links) # /Foobar -- convert to CurrentPage/Foobar # /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text # ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage # ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage wfProfileIn(__METHOD__); $ret = $target; # default return value is no change # Some namespaces don't allow subpages, # so only perform processing if subpages are allowed if ($contextTitle && MWNamespace::hasSubpages($contextTitle->getNamespace())) { $hash = strpos($target, '#'); if ($hash !== false) { $suffix = substr($target, $hash); $target = substr($target, 0, $hash); } else { $suffix = ''; } # bug 7425 $target = trim($target); # Look at the first character if ($target != '' && $target[0] === '/') { # / at end means we don't want the slash to be shown $m = array(); $trailingSlashes = preg_match_all('%(/+)$%', $target, $m); if ($trailingSlashes) { $noslash = $target = substr($target, 1, -strlen($m[0][0])); } else { $noslash = substr($target, 1); } $ret = $contextTitle->getPrefixedText() . '/' . trim($noslash) . $suffix; if ($text === '') { $text = $target . $suffix; } # this might be changed for ugliness reasons } else { # check for .. subpage backlinks $dotdotcount = 0; $nodotdot = $target; while (strncmp($nodotdot, "../", 3) == 0) { ++$dotdotcount; $nodotdot = substr($nodotdot, 3); } if ($dotdotcount > 0) { $exploded = explode('/', $contextTitle->GetPrefixedText()); if (count($exploded) > $dotdotcount) { # not allowed to go below top level page $ret = implode('/', array_slice($exploded, 0, -$dotdotcount)); # / at the end means don't show full path if (substr($nodotdot, -1, 1) === '/') { $nodotdot = substr($nodotdot, 0, -1); if ($text === '') { $text = $nodotdot . $suffix; } } $nodotdot = trim($nodotdot); if ($nodotdot != '') { $ret .= '/' . $nodotdot; } $ret .= $suffix; } } } } wfProfileOut(__METHOD__); return $ret; }
protected function appendNamespaces($property) { global $wgContLang; $data = array(); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $data[$ns] = array('id' => intval($ns), 'case' => MWNamespace::isCapitalized($ns) ? 'first-letter' : 'case-sensitive'); ApiResult::setContent($data[$ns], $title); $canonical = MWNamespace::getCanonicalName($ns); if (MWNamespace::hasSubpages($ns)) { $data[$ns]['subpages'] = ''; } if ($canonical) { $data[$ns]['canonical'] = strtr($canonical, '_', ' '); } if (MWNamespace::isContent($ns)) { $data[$ns]['content'] = ''; } } $this->getResult()->setIndexedTagName($data, 'ns'); return $this->getResult()->addValue('query', $property, $data); }
function subPageSubtitle() { $subpages = ''; if (!wfRunHooks('SkinSubPageSubtitle', array(&$subpages))) { return $subpages; } global $wgOut, $wgTitle; if ($wgOut->isArticle() && MWNamespace::hasSubpages($wgTitle->getNamespace())) { $ptext = $wgTitle->getPrefixedText(); if (preg_match('/\\//', $ptext)) { $links = explode('/', $ptext); array_pop($links); $c = 0; $growinglink = ''; $display = ''; foreach ($links as $link) { $growinglink .= $link; $display .= $link; $linkObj = Title::newFromText($growinglink); if (is_object($linkObj) && $linkObj->exists()) { $getlink = $this->makeKnownLinkObj($linkObj, htmlspecialchars($display)); $c++; if ($c > 1) { $subpages .= wfMsgExt('pipe-separator', 'escapenoentities'); } else { $subpages .= '< '; } $subpages .= $getlink; $display = ''; } else { $display .= '/'; } $growinglink .= '/'; } } } return $subpages; }
/** * Returns page counts that would be too "expensive" to retrieve by normal means. * * @param WikiPage|Article|Page $page * @return array */ protected function pageCounts(Page $page) { $fname = __METHOD__; $config = $this->context->getConfig(); return ObjectCache::getMainWANInstance()->getWithSetCallback(self::getCacheKey($page->getTitle(), $page->getLatest()), WANObjectCache::TTL_WEEK, function ($oldValue, &$ttl, &$setOpts) use($page, $config, $fname) { $title = $page->getTitle(); $id = $title->getArticleID(); $dbr = wfGetDB(DB_REPLICA); $dbrWatchlist = wfGetDB(DB_REPLICA, 'watchlist'); $setOpts += Database::getCacheSetOptions($dbr, $dbrWatchlist); $watchedItemStore = MediaWikiServices::getInstance()->getWatchedItemStore(); $result = []; $result['watchers'] = $watchedItemStore->countWatchers($title); if ($config->get('ShowUpdatedMarker')) { $updated = wfTimestamp(TS_UNIX, $page->getTimestamp()); $result['visitingWatchers'] = $watchedItemStore->countVisitingWatchers($title, $updated - $config->get('WatchersMaxAge')); } // Total number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(*)', ['rev_page' => $id], $fname); $result['edits'] = $edits; // Total number of distinct authors if ($config->get('MiserMode')) { $result['authors'] = 0; } else { $result['authors'] = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', ['rev_page' => $id], $fname); } // "Recent" threshold defined by RCMaxAge setting $threshold = $dbr->timestamp(time() - $config->get('RCMaxAge')); // Recent number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(rev_page)', ['rev_page' => $id, "rev_timestamp >= " . $dbr->addQuotes($threshold)], $fname); $result['recent_edits'] = $edits; // Recent number of distinct authors $result['recent_authors'] = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', ['rev_page' => $id, "rev_timestamp >= " . $dbr->addQuotes($threshold)], $fname); // Subpages (if enabled) if (MWNamespace::hasSubpages($title->getNamespace())) { $conds = ['page_namespace' => $title->getNamespace()]; $conds[] = 'page_title ' . $dbr->buildLike($title->getDBkey() . '/', $dbr->anyString()); // Subpages of this page (redirects) $conds['page_is_redirect'] = 1; $result['subpages']['redirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, $fname); // Subpages of this page (non-redirects) $conds['page_is_redirect'] = 0; $result['subpages']['nonredirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, $fname); // Subpages of this page (total) $result['subpages']['total'] = $result['subpages']['redirects'] + $result['subpages']['nonredirects']; } // Counts for the number of transclusion links (to/from) if ($config->get('MiserMode')) { $result['transclusion']['to'] = 0; } else { $result['transclusion']['to'] = (int) $dbr->selectField('templatelinks', 'COUNT(tl_from)', ['tl_namespace' => $title->getNamespace(), 'tl_title' => $title->getDBkey()], $fname); } $result['transclusion']['from'] = (int) $dbr->selectField('templatelinks', 'COUNT(*)', ['tl_from' => $title->getArticleID()], $fname); return $result; }); }
function showSubpages( $title ) { if ( !MWNamespace::hasSubpages( $title->getNamespace() ) ) { return; } $subpages = $title->getSubpages(); $count = $subpages instanceof TitleArray ? $subpages->count() : 0; $out = $this->getOutput(); $out->wrapWikiMsg( '== $1 ==', array( 'movesubpage', $count ) ); # No subpages. if ( $count == 0 ) { $out->addWikiMsg( 'movenosubpage' ); return; } $out->addWikiMsg( 'movesubpagetext', $this->getLanguage()->formatNum( $count ) ); $out->addHTML( "<ul>\n" ); foreach ( $subpages as $subpage ) { $link = Linker::link( $subpage ); $out->addHTML( "<li>$link</li>\n" ); } $out->addHTML( "</ul>\n" ); }
public static function replaceSubtitle(&$subpages, $skin = null, OutputPage $out) { if (!TranslatablePage::isTranslationPage($out->getTitle()) && !TranslatablePage::isSourcePage($out->getTitle())) { return true; } // Copied from Skin::subPageSubtitle() if ($out->isArticle() && MWNamespace::hasSubpages($out->getTitle()->getNamespace())) { $ptext = $out->getTitle()->getPrefixedText(); if (preg_match('/\\//', $ptext)) { $links = explode('/', $ptext); array_pop($links); // Also pop of one extra for language code is needed if (TranslatablePage::isTranslationPage($out->getTitle())) { array_pop($links); } $c = 0; $growinglink = ''; $display = ''; foreach ($links as $link) { $growinglink .= $link; $display .= $link; $linkObj = Title::newFromText($growinglink); if (is_object($linkObj) && $linkObj->exists()) { $getlink = Linker::linkKnown(SpecialPage::getTitleFor('MyLanguage', $growinglink), htmlspecialchars($display)); $c++; if ($c > 1) { $subpages .= wfMessage('pipe-separator')->plain(); } else { // This one is stupid imho, doesn't work with chihuahua // $subpages .= '< '; } $subpages .= $getlink; $display = ''; } else { $display .= '/'; } $growinglink .= '/'; } } return false; } return true; }
/** * Replace entire edit method, need to convert HTML -> wikitext before saving */ function edit() { global $wgOut, $wgUser, $wgRequest; wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": enter\n"); // This is not an article $wgOut->setArticleFlag(false); $this->importFormData($wgRequest); $this->firsttime = false; if ($this->live) { $this->livePreview(); wfProfileOut(__METHOD__); return; } if (wfReadOnly() && $this->save) { // Force preview $this->save = false; $this->preview = true; } $wgOut->addScriptFile('edit.js'); $permErrors = $this->getEditPermissionErrors(); if ($permErrors) { wfDebug(__METHOD__ . ": User can't edit\n"); $this->readOnlyPage($this->getContent(), true, $permErrors, 'edit'); wfProfileOut(__METHOD__); return; } else { if ($this->save) { $this->formtype = 'save'; } else { if ($this->preview) { $this->formtype = 'preview'; } else { if ($this->diff) { $this->formtype = 'diff'; } else { # First time through $this->firsttime = true; if ($this->previewOnOpen()) { $this->formtype = 'preview'; } else { $this->extractMetaDataFromArticle(); $this->formtype = 'initial'; } } } } } // If they used redlink=1 and the page exists, redirect to the main article if ($wgRequest->getBool('redlink') && $this->mTitle->exists()) { $wgOut->redirect($this->mTitle->getFullURL()); } wfProfileIn(__METHOD__ . "-business-end"); $this->isConflict = false; // css / js subpages of user pages get a special treatment $this->isCssJsSubpage = $this->mTitle->isCssJsSubpage(); $this->isValidCssJsSubpage = $this->mTitle->isValidCssJsSubpage(); # Show applicable editing introductions if ($this->formtype == 'initial' || $this->firsttime) { $this->showIntro(); } if ($this->mTitle->isTalkPage()) { $wgOut->addWikiMsg('talkpagetext'); } # Optional notices on a per-namespace and per-page basis $editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace(); if (!wfEmptyMsg($editnotice_ns, wfMsgForContent($editnotice_ns))) { $wgOut->addWikiText(wfMsgForContent($editnotice_ns)); } if (MWNamespace::hasSubpages($this->mTitle->getNamespace())) { $parts = explode('/', $this->mTitle->getDBkey()); $editnotice_base = $editnotice_ns; while (count($parts) > 0) { $editnotice_base .= '-' . array_shift($parts); if (!wfEmptyMsg($editnotice_base, wfMsgForContent($editnotice_base))) { $wgOut->addWikiText(wfMsgForContent($editnotice_base)); } } } # MeanEditor: always use traditional editing for these strange things if ($this->mTitle->getNamespace() != NS_MAIN || $this->isCssJsSubpage) { $this->noVisualEditor = true; } # MeanEditor: convert HTML to wikitext # The hidden box should tell us if the editor was in use (we got HTML in the POST) if (!$this->firsttime && !($this->formtype == 'initial') && !$this->noVisualEditor) { wfRunHooks('EditPage::html2wiki', array($this->mArticle, $wgUser, &$this, &$this->textbox1)); } # MeanEditor: we could leave MeanEditor enabled, but I think it would be confusing if ($this->diff || $this->formtype == 'diff') { $this->noVisualEditor = true; } # Attempt submission here. This will check for edit conflicts, # and redundantly check for locked database, blocked IPs, etc. # that edit() already checked just in case someone tries to sneak # in the back door with a hand-edited submission URL. if ('save' == $this->formtype) { if (!$this->attemptSave()) { wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); return; } } # First time through: get contents, set time for conflict # checking, etc. if ('initial' == $this->formtype || $this->firsttime) { if ($this->initialiseForm() === false) { $this->noSuchSectionPage(); wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); return; } if (!$this->mTitle->getArticleId()) { wfRunHooks('EditFormPreloadText', array(&$this->textbox1, &$this->mTitle)); } } $this->showEditForm(); wfProfileOut(__METHOD__ . "-business-end"); wfProfileOut(__METHOD__); }
/** * Returns condition array suitable for `select' or `estimateRowCount'. * * @since 0.6 * * @param $title — Either page title (Title instance) or namespace (integer). Do not pass null. * * @param $kidsOnly — Boolean. If true, only direct subpages are included. * * @return array — Conditions or `null' if something is wrong (e. g. subpages are not enabled * in this namespace or page does not exits). */ protected function getConditions( $title, $kidsOnly ) { if ( is_null( $title ) ) { // Just in case. If `getTitle' returns `null' it means page does not exist. return null; } $dbr = wfGetDB( DB_SLAVE ); $conditions = array(); $conditions['page_is_redirect'] = 0; if ( $title instanceof Title ) { if ( ! MWNamespace::hasSubpages( $title->getNamespace() ) ) { // Subpages are not enabled in this namespace. If we return empty array such a // condition will meet all the pages, so let us return `null' istead to signal // result is not valid. return null; } $conditions['page_namespace'] = $title->getNamespace(); // Don't let list cross namespaces. // TODO: this is rather resource heavy $conditions[] = 'page_title ' . $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString() ); if ( $kidsOnly ) { $conditions[] = 'page_title NOT ' . $dbr->buildLike( $title->getDBkey() . '/', $dbr->anyString(), '/', $dbr->anyString() ); } } else { // `$title' is namespace index. $conditions['page_namespace'] = $title; if ( $kidsOnly && MWNamespace::hasSubpages( $title ) ) { // Requested only "root" pages, not subpages. $conditions[] = 'page_title NOT ' . $dbr->buildLike( $dbr->anyString(), '/', $dbr->anyString() ); } else { // Subpages requested for namespace: not just direct kids or namespace does not have // subpages => we should return *all* the pages in namespace => condition is not // needed. } } return $conditions; } // getConditions
/** * @param OutputPage $out Defaults to $this->getOutput() if left as null * @return string */ function subPageSubtitle($out = null) { if ($out === null) { $out = $this->getOutput(); } $title = $out->getTitle(); $subpages = ''; if (!Hooks::run('SkinSubPageSubtitle', [&$subpages, $this, $out])) { return $subpages; } if ($out->isArticle() && MWNamespace::hasSubpages($title->getNamespace())) { $ptext = $title->getPrefixedText(); if (strpos($ptext, '/') !== false) { $links = explode('/', $ptext); array_pop($links); $c = 0; $growinglink = ''; $display = ''; $lang = $this->getLanguage(); foreach ($links as $link) { $growinglink .= $link; $display .= $link; $linkObj = Title::newFromText($growinglink); if (is_object($linkObj) && $linkObj->isKnown()) { $getlink = Linker::linkKnown($linkObj, htmlspecialchars($display)); $c++; if ($c > 1) { $subpages .= $lang->getDirMarkEntity() . $this->msg('pipe-separator')->escaped(); } else { $subpages .= '< '; } $subpages .= $getlink; $display = ''; } else { $display .= '/'; } $growinglink .= '/'; } } } return $subpages; }
/** * Return true if subpage links should be expanded on this page. * @return Boolean */ function areSubpagesAllowed() { # Some namespaces don't allow subpages return MWNamespace::hasSubpages($this->mTitle->getNamespace()); }
/** * Returns page information that would be too "expensive" to retrieve by normal means. * * @param $title Title object * @param $canViewUnwatched bool * @param $disableCounter bool * @return array */ public static function pageCountInfo($title, $canViewUnwatched, $disableCounter) { global $wgRCMaxAge; wfProfileIn(__METHOD__); $id = $title->getArticleID(); $dbr = wfGetDB(DB_SLAVE); $result = array(); if (!$disableCounter) { // Number of views $views = (int) $dbr->selectField('page', 'page_counter', array('page_id' => $id), __METHOD__); $result['views'] = $views; } if ($canViewUnwatched) { // Number of page watchers $watchers = (int) $dbr->selectField('watchlist', 'COUNT(*)', array('wl_namespace' => $title->getNamespace(), 'wl_title' => $title->getDBkey()), __METHOD__); $result['watchers'] = $watchers; } // Total number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(rev_page)', array('rev_page' => $id), __METHOD__); $result['edits'] = $edits; // Total number of distinct authors $authors = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', array('rev_page' => $id), __METHOD__); $result['authors'] = $authors; // "Recent" threshold defined by $wgRCMaxAge $threshold = $dbr->timestamp(time() - $wgRCMaxAge); // Recent number of edits $edits = (int) $dbr->selectField('revision', 'COUNT(rev_page)', array('rev_page' => $id, "rev_timestamp >= {$threshold}"), __METHOD__); $result['recent_edits'] = $edits; // Recent number of distinct authors $authors = (int) $dbr->selectField('revision', 'COUNT(DISTINCT rev_user_text)', array('rev_page' => $id, "rev_timestamp >= {$threshold}"), __METHOD__); $result['recent_authors'] = $authors; // Subpages (if enabled) if (MWNamespace::hasSubpages($title->getNamespace())) { $conds = array('page_namespace' => $title->getNamespace()); $conds[] = 'page_title ' . $dbr->buildLike($title->getDBkey() . '/', $dbr->anyString()); // Subpages of this page (redirects) $conds['page_is_redirect'] = 1; $result['subpages']['redirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, __METHOD__); // Subpages of this page (non-redirects) $conds['page_is_redirect'] = 0; $result['subpages']['nonredirects'] = (int) $dbr->selectField('page', 'COUNT(page_id)', $conds, __METHOD__); // Subpages of this page (total) $result['subpages']['total'] = $result['subpages']['redirects'] + $result['subpages']['nonredirects']; } wfProfileOut(__METHOD__); return $result; }
/** * Set a target root page under which all pages are imported * @param null|string $rootpage * @return Status */ public function setTargetRootPage($rootpage) { $status = Status::newGood(); if (is_null($rootpage)) { // No rootpage $this->setImportTitleFactory(new NaiveImportTitleFactory()); } elseif ($rootpage !== '') { $rootpage = rtrim($rootpage, '/'); //avoid double slashes $title = Title::newFromText($rootpage, !is_null($this->mTargetNamespace) ? $this->mTargetNamespace : NS_MAIN); if (!$title || $title->isExternal()) { $status->fatal('import-rootpage-invalid'); } else { if (!MWNamespace::hasSubpages($title->getNamespace())) { global $wgContLang; $displayNSText = $title->getNamespace() == NS_MAIN ? wfMessage('blanknamespace')->text() : $wgContLang->getNsText($title->getNamespace()); $status->fatal('import-rootpage-nosubpage', $displayNSText); } else { // set namespace to 'all', so the namespace check in processTitle() can pass $this->setTargetNamespace(null); $this->setImportTitleFactory(new SubpageImportTitleFactory($title)); } } } return $status; }
/** * Show subpages of the page being moved. Section is not shown if both current * namespace does not support subpages and no talk subpages were found. * * @param Title $title Page being moved. */ function showSubpages($title) { $nsHasSubpages = MWNamespace::hasSubpages($title->getNamespace()); $subpages = $title->getSubpages(); $count = $subpages instanceof TitleArray ? $subpages->count() : 0; $titleIsTalk = $title->isTalkPage(); $subpagesTalk = $title->getTalkPage()->getSubpages(); $countTalk = $subpagesTalk instanceof TitleArray ? $subpagesTalk->count() : 0; $totalCount = $count + $countTalk; if (!$nsHasSubpages && $countTalk == 0) { return; } $this->getOutput()->wrapWikiMsg('== $1 ==', ['movesubpage', $titleIsTalk ? $count : $totalCount]); if ($nsHasSubpages) { $this->showSubpagesList($subpages, $count, 'movesubpagetext', true); } if (!$titleIsTalk && $countTalk > 0) { $this->showSubpagesList($subpagesTalk, $countTalk, 'movesubpagetalktext'); } }
/** * Get a list of rendered edit notices for this page. * * Array is keyed by the original message key, and values are rendered using parseAsBlock, so * they will already be wrapped in paragraphs. * * @since 1.21 * @param int $oldid Revision ID that's being edited * @return array */ public function getEditNotices($oldid = 0) { $notices = array(); // Optional notice for the entire namespace $editnotice_ns = 'editnotice-' . $this->getNamespace(); $msg = wfMessage($editnotice_ns); if ($msg->exists()) { $html = $msg->parseAsBlock(); // Edit notices may have complex logic, but output nothing (T91715) if (trim($html) !== '') { $notices[$editnotice_ns] = Html::rawElement('div', array('class' => array('mw-editnotice', 'mw-editnotice-namespace', Sanitizer::escapeClass("mw-{$editnotice_ns}"))), $html); } } if (MWNamespace::hasSubpages($this->getNamespace())) { // Optional notice for page itself and any parent page $parts = explode('/', $this->getDBkey()); $editnotice_base = $editnotice_ns; while (count($parts) > 0) { $editnotice_base .= '-' . array_shift($parts); $msg = wfMessage($editnotice_base); if ($msg->exists()) { $html = $msg->parseAsBlock(); if (trim($html) !== '') { $notices[$editnotice_base] = Html::rawElement('div', array('class' => array('mw-editnotice', 'mw-editnotice-base', Sanitizer::escapeClass("mw-{$editnotice_base}"))), $html); } } } } else { // Even if there are no subpages in namespace, we still don't want "/" in MediaWiki message keys $editnoticeText = $editnotice_ns . '-' . strtr($this->getDBkey(), '/', '-'); $msg = wfMessage($editnoticeText); if ($msg->exists()) { $html = $msg->parseAsBlock(); if (trim($html) !== '') { $notices[$editnoticeText] = Html::rawElement('div', array('class' => array('mw-editnotice', 'mw-editnotice-page', Sanitizer::escapeClass("mw-{$editnoticeText}"))), $html); } } } Hooks::run('TitleGetEditNotices', array($this, $oldid, &$notices)); return $notices; }
protected function appendNamespaces($property) { global $wgContLang; $data = array(ApiResult::META_TYPE => 'assoc'); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $data[$ns] = array('id' => intval($ns), 'case' => MWNamespace::isCapitalized($ns) ? 'first-letter' : 'case-sensitive'); ApiResult::setContentValue($data[$ns], 'name', $title); $canonical = MWNamespace::getCanonicalName($ns); $data[$ns]['subpages'] = MWNamespace::hasSubpages($ns); if ($canonical) { $data[$ns]['canonical'] = strtr($canonical, '_', ' '); } $data[$ns]['content'] = MWNamespace::isContent($ns); $data[$ns]['nonincludable'] = MWNamespace::isNonincludable($ns); $contentmodel = MWNamespace::getNamespaceContentModel($ns); if ($contentmodel) { $data[$ns]['defaultcontentmodel'] = $contentmodel; } } ApiResult::setIndexedTagName($data, 'ns'); return $this->getResult()->addValue('query', $property, $data); }