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); }
/** * Check action permissions not already checked in checkQuickPermissions * * @param string $action The action to check * @param User $user User to check * @param array $errors List of current errors * @param string $rigor Same format as Title::getUserPermissionsErrors() * @param bool $short Short circuit on first error * * @return array List of errors */ private function checkActionPermissions($action, $user, $errors, $rigor, $short) { global $wgDeleteRevisionsLimit, $wgLang; if ($action == 'protect') { if (count($this->getUserPermissionsErrorsInternal('edit', $user, $rigor, true))) { // If they can't edit, they shouldn't protect. $errors[] = array('protect-cantedit'); } } elseif ($action == 'create') { $title_protection = $this->getTitleProtection(); if ($title_protection) { if ($title_protection['permission'] == '' || !$user->isAllowed($title_protection['permission'])) { $errors[] = array('titleprotected', User::whoIs($title_protection['user']), $title_protection['reason']); } } } elseif ($action == 'move') { // Check for immobile pages if (!MWNamespace::isMovable($this->mNamespace)) { // Specific message for this case $errors[] = array('immobile-source-namespace', $this->getNsText()); } elseif (!$this->isMovable()) { // Less specific message for rarer cases $errors[] = array('immobile-source-page'); } } elseif ($action == 'move-target') { if (!MWNamespace::isMovable($this->mNamespace)) { $errors[] = array('immobile-target-namespace', $this->getNsText()); } elseif (!$this->isMovable()) { $errors[] = array('immobile-target-page'); } } elseif ($action == 'delete') { $tempErrors = $this->checkPageRestrictions('edit', $user, array(), $rigor, true); if (!$tempErrors) { $tempErrors = $this->checkCascadingSourcesRestrictions('edit', $user, $tempErrors, $rigor, true); } if ($tempErrors) { // If protection keeps them from editing, they shouldn't be able to delete. $errors[] = array('deleteprotected'); } if ($rigor !== 'quick' && $wgDeleteRevisionsLimit && !$this->userCan('bigdelete', $user) && $this->isBigDeletion()) { $errors[] = array('delete-toobig', $wgLang->formatNum($wgDeleteRevisionsLimit)); } } return $errors; }
/** * Would anybody with sufficient privileges be able to move this page? * Some pages just aren't movable. * * @return Bool TRUE or FALSE */ public function isMovable() { return MWNamespace::isMovable($this->getNamespace()) && $this->getInterwiki() == ''; }
/** * Show the form * * @param array $err Error messages. Each item is an error message. * It may either be a string message name or array message name and * parameters, like the second argument to OutputPage::wrapWikiMsg(). */ function showForm($err) { global $wgContLang; $this->getSkin()->setRelevantTitle($this->oldTitle); $oldTitleLink = Linker::link($this->oldTitle); $out = $this->getOutput(); $out->setPageTitle($this->msg('move-page', $this->oldTitle->getPrefixedText())); $out->addModules('mediawiki.special.movePage'); $out->addModuleStyles('mediawiki.special.movePage.styles'); $this->addHelpLink('Help:Moving a page'); $newTitle = $this->newTitle; if (!$newTitle) { # Show the current title as a default # when the form is first opened. $newTitle = $this->oldTitle; } elseif (!count($err)) { # If a title was supplied, probably from the move log revert # link, check for validity. We can then show some diagnostic # information and save a click. $newerr = $this->oldTitle->isValidMoveOperation($newTitle); if (is_array($newerr)) { $err = $newerr; } } $user = $this->getUser(); if (count($err) == 1 && isset($err[0][0]) && $err[0][0] == 'articleexists' && $newTitle->quickUserCan('delete', $user)) { $out->addWikiMsg('delete_and_move_text', $newTitle->getPrefixedText()); $movepagebtn = $this->msg('delete_and_move')->text(); $submitVar = 'wpDeleteAndMove'; $confirm = true; $err = array(); } else { if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage()) { $out->wrapWikiMsg("<div class=\"error mw-moveuserpage-warning\">\n\$1\n</div>", 'moveuserpage-warning'); } elseif ($this->oldTitle->getNamespace() == NS_CATEGORY) { $out->wrapWikiMsg("<div class=\"error mw-movecategorypage-warning\">\n\$1\n</div>", 'movecategorypage-warning'); } $out->addWikiMsg($this->getConfig()->get('FixDoubleRedirects') ? 'movepagetext' : 'movepagetext-noredirectfixer'); $movepagebtn = $this->msg('movepagebtn')->text(); $submitVar = 'wpMove'; $confirm = false; } if (count($err) == 1 && isset($err[0][0]) && $err[0][0] == 'file-exists-sharedrepo' && $user->isAllowed('reupload-shared')) { $out->addWikiMsg('move-over-sharedrepo', $newTitle->getPrefixedText()); $submitVar = 'wpMoveOverSharedFile'; $err = array(); } $oldTalk = $this->oldTitle->getTalkPage(); $oldTitleSubpages = $this->oldTitle->hasSubpages(); $oldTitleTalkSubpages = $this->oldTitle->getTalkPage()->hasSubpages(); $canMoveSubpage = ($oldTitleSubpages || $oldTitleTalkSubpages) && !count($this->oldTitle->getUserPermissionsErrors('move-subpages', $user)); # We also want to be able to move assoc. subpage talk-pages even if base page # has no associated talk page, so || with $oldTitleTalkSubpages. $considerTalk = !$this->oldTitle->isTalkPage() && ($oldTalk->exists() || $oldTitleTalkSubpages && $canMoveSubpage); $dbr = wfGetDB(DB_SLAVE); if ($this->getConfig()->get('FixDoubleRedirects')) { $hasRedirects = $dbr->selectField('redirect', '1', array('rd_namespace' => $this->oldTitle->getNamespace(), 'rd_title' => $this->oldTitle->getDBkey()), __METHOD__); } else { $hasRedirects = false; } if ($considerTalk) { $out->addWikiMsg('movepagetalktext'); } if (count($err)) { $out->addHTML("<div class='error'>\n"); $action_desc = $this->msg('action-move')->plain(); $out->addWikiMsg('permissionserrorstext-withaction', count($err), $action_desc); if (count($err) == 1) { $errMsg = $err[0]; $errMsgName = array_shift($errMsg); if ($errMsgName == 'hookaborted') { $out->addHTML("<p>{$errMsg[0]}</p>\n"); } else { $out->addWikiMsgArray($errMsgName, $errMsg); } } else { $errStr = array(); foreach ($err as $errMsg) { if ($errMsg[0] == 'hookaborted') { $errStr[] = $errMsg[1]; } else { $errMsgName = array_shift($errMsg); $errStr[] = $this->msg($errMsgName, $errMsg)->parse(); } } $out->addHTML('<ul><li>' . implode("</li>\n<li>", $errStr) . "</li></ul>\n"); } $out->addHTML("</div>\n"); } if ($this->oldTitle->isProtected('move')) { # Is the title semi-protected? if ($this->oldTitle->isSemiProtected('move')) { $noticeMsg = 'semiprotectedpagemovewarning'; $classes[] = 'mw-textarea-sprotected'; } else { # Then it must be protected based on static groups (regular) $noticeMsg = 'protectedpagemovewarning'; $classes[] = 'mw-textarea-protected'; } $out->addHTML("<div class='mw-warning-with-logexcerpt'>\n"); $out->addWikiMsg($noticeMsg); LogEventsList::showLogExtract($out, 'protect', $this->oldTitle, '', array('lim' => 1)); $out->addHTML("</div>\n"); } // Byte limit (not string length limit) for wpReason and wpNewTitleMain // is enforced in the mediawiki.special.movePage module $immovableNamespaces = array(); foreach (array_keys($this->getLanguage()->getNamespaces()) as $nsId) { if (!MWNamespace::isMovable($nsId)) { $immovableNamespaces[] = $nsId; } } $handler = ContentHandler::getForTitle($this->oldTitle); $out->enableOOUI(); $fields = array(); $fields[] = new OOUI\FieldLayout(new OOUI\LabelWidget(array('label' => new OOUI\HtmlSnippet("<strong>{$oldTitleLink}</strong>"))), array('label' => $this->msg('movearticle')->text(), 'align' => 'top')); $fields[] = new OOUI\FieldLayout(new MediaWiki\Widget\ComplexTitleInputWidget(array('id' => 'wpNewTitle', 'namespace' => array('id' => 'wpNewTitleNs', 'name' => 'wpNewTitleNs', 'value' => $newTitle->getNamespace(), 'exclude' => $immovableNamespaces), 'title' => array('id' => 'wpNewTitleMain', 'name' => 'wpNewTitleMain', 'value' => $wgContLang->recodeForEdit($newTitle->getText()), 'suggestions' => false), 'infusable' => true)), array('label' => $this->msg('newtitle')->text(), 'align' => 'top')); $fields[] = new OOUI\FieldLayout(new OOUI\TextInputWidget(array('name' => 'wpReason', 'id' => 'wpReason', 'maxLength' => 200, 'infusable' => true, 'value' => $this->reason)), array('label' => $this->msg('movereason')->text(), 'align' => 'top')); if ($considerTalk) { $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpMovetalk', 'id' => 'wpMovetalk', 'value' => '1', 'selected' => $this->moveTalk)), array('label' => $this->msg('movetalk')->text(), 'align' => 'inline')); } if ($user->isAllowed('suppressredirect')) { if ($handler->supportsRedirects()) { $isChecked = $this->leaveRedirect; $isDisabled = false; } else { $isChecked = false; $isDisabled = true; } $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpLeaveRedirect', 'id' => 'wpLeaveRedirect', 'value' => '1', 'selected' => $isChecked, 'disabled' => $isDisabled)), array('label' => $this->msg('move-leave-redirect')->text(), 'align' => 'inline')); } if ($hasRedirects) { $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpFixRedirects', 'id' => 'wpFixRedirects', 'value' => '1', 'selected' => $this->fixRedirects)), array('label' => $this->msg('fix-double-redirects')->text(), 'align' => 'inline')); } if ($canMoveSubpage) { $maximumMovedPages = $this->getConfig()->get('MaximumMovedPages'); $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpMovesubpages', 'id' => 'wpMovesubpages', 'value' => '1', 'selected' => $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk))), array('label' => new OOUI\HtmlSnippet($this->msg($this->oldTitle->hasSubpages() ? 'move-subpages' : 'move-talk-subpages')->numParams($maximumMovedPages)->params($maximumMovedPages)->parse()), 'align' => 'inline')); } # Don't allow watching if user is not logged in if ($user->isLoggedIn()) { $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption('watchmoves') || $user->isWatched($this->oldTitle)); $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpWatch', 'id' => 'watch', 'value' => '1', 'selected' => $watchChecked)), array('label' => $this->msg('move-watch')->text(), 'align' => 'inline')); } if ($confirm) { $fields[] = new OOUI\FieldLayout(new OOUI\CheckboxInputWidget(array('name' => 'wpConfirm', 'id' => 'wpConfirm', 'value' => '1')), array('label' => $this->msg('delete_and_move_confirm')->text(), 'align' => 'inline')); } $fields[] = new OOUI\FieldLayout(new OOUI\ButtonInputWidget(array('name' => $submitVar, 'value' => $movepagebtn, 'label' => $movepagebtn, 'flags' => array('constructive', 'primary'), 'type' => 'submit')), array('align' => 'top')); $fieldset = new OOUI\FieldsetLayout(array('label' => $this->msg('move-page-legend')->text(), 'id' => 'mw-movepage-table', 'items' => $fields)); $form = new OOUI\FormLayout(array('method' => 'post', 'action' => $this->getPageTitle()->getLocalURL('action=submit'), 'id' => 'movepage')); $form->appendContent($fieldset, new OOUI\HtmlSnippet(Html::hidden('wpOldTitle', $this->oldTitle->getPrefixedText()) . Html::hidden('wpEditToken', $user->getEditToken()))); $out->addHTML(new OOUI\PanelLayout(array('classes' => array('movepage-wrapper'), 'expanded' => false, 'padded' => true, 'framed' => true, 'content' => $form))); $this->showLogFragment($this->oldTitle); $this->showSubpages($this->oldTitle); }
/** * @todo Write more texts, handle $wgAllowImageMoving setting */ public function testIsMovable() { $this->assertFalse(MWNamespace::isMovable(NS_CATEGORY)); # @todo FIXME: Write more tests!! }
/** * Check action permissions not already checked in checkQuickPermissions * * @param $action String the action to check * @param $user User to check * @param $errors Array list of current errors * @param $doExpensiveQueries Boolean whether or not to perform expensive queries * @param $short Boolean short circuit on first error * * @return Array list of errors */ private function checkActionPermissions($action, $user, $errors, $doExpensiveQueries, $short) { global $wgDeleteRevisionsLimit, $wgLang; if ($action == 'protect') { if (count($this->getUserPermissionsErrorsInternal('edit', $user, $doExpensiveQueries, true))) { // If they can't edit, they shouldn't protect. $errors[] = array('protect-cantedit'); } } elseif ($action == 'create') { $title_protection = $this->getTitleProtection(); if ($title_protection) { if ($title_protection['pt_create_perm'] == 'sysop') { $title_protection['pt_create_perm'] = 'protect'; // B/C } if ($title_protection['pt_create_perm'] == '' || !$user->isAllowed($title_protection['pt_create_perm'])) { $errors[] = array('titleprotected', User::whoIs($title_protection['pt_user']), $title_protection['pt_reason']); } } } elseif ($action == 'move') { // Check for immobile pages if (!MWNamespace::isMovable($this->mNamespace)) { // Specific message for this case $errors[] = array('immobile-source-namespace', $this->getNsText()); } elseif (!$this->isMovable()) { // Less specific message for rarer cases $errors[] = array('immobile-source-page'); } } elseif ($action == 'move-target') { if (!MWNamespace::isMovable($this->mNamespace)) { $errors[] = array('immobile-target-namespace', $this->getNsText()); } elseif (!$this->isMovable()) { $errors[] = array('immobile-target-page'); } } elseif ($action == 'delete') { if ($doExpensiveQueries && $wgDeleteRevisionsLimit && !$this->userCan('bigdelete', $user) && $this->isBigDeletion()) { $errors[] = array('delete-toobig', $wgLang->formatNum($wgDeleteRevisionsLimit)); } } elseif ($action == 'edit') { if (!$user->isAllowed('edit')) { $errors[] = $user->isAnon() ? array('editnologintext', wfGetReturntoParam()) : array('editnotallowed'); } } # end change by wikia return $errors; }
function testNamespaceSelector() { global $wgContLang; $this->assertEquals('<select id="namespace" name="namespace">' . "\n" . '<option value="0">(Main)</option>' . "\n" . '<option value="1">Talk</option>' . "\n" . '<option value="2">User</option>' . "\n" . '<option value="3">User talk</option>' . "\n" . '<option value="4">MyWiki</option>' . "\n" . '<option value="5">MyWiki Talk</option>' . "\n" . '<option value="6">File</option>' . "\n" . '<option value="7">File talk</option>' . "\n" . '<option value="8">MediaWiki</option>' . "\n" . '<option value="9">MediaWiki talk</option>' . "\n" . '<option value="10">Template</option>' . "\n" . '<option value="11">Template talk</option>' . "\n" . '<option value="100">Custom</option>' . "\n" . '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector(), 'Basic namespace selector without custom options'); $this->assertEquals('<label for="mw-test-namespace">Select a namespace:</label> ' . '<select id="mw-test-namespace" name="wpNamespace">' . "\n" . '<option value="all">all</option>' . "\n" . '<option value="0">(Main)</option>' . "\n" . '<option value="1">Talk</option>' . "\n" . '<option value="2" selected="">User</option>' . "\n" . '<option value="3">User talk</option>' . "\n" . '<option value="4">MyWiki</option>' . "\n" . '<option value="5">MyWiki Talk</option>' . "\n" . '<option value="6">File</option>' . "\n" . '<option value="7">File talk</option>' . "\n" . '<option value="8">MediaWiki</option>' . "\n" . '<option value="9">MediaWiki talk</option>' . "\n" . '<option value="10">Template</option>' . "\n" . '<option value="11">Template talk</option>' . "\n" . '<option value="100">Custom</option>' . "\n" . '<option value="101">Custom talk</option>' . "\n" . '</select>', Html::namespaceSelector(array('selected' => '2', 'all' => 'all', 'label' => 'Select a namespace:'), array('name' => 'wpNamespace', 'id' => 'mw-test-namespace')), 'Basic namespace selector with custom values'); $immovable = array(); $namespaces = $wgContLang->getNamespaces(); foreach ($namespaces as $nsId => $nsName) { if (!MWNamespace::isMovable(intval($nsId))) { $immovable[] = $nsId; } } $this->assertEquals('<select id="namespace" name="namespace">' . "\n" . '<option value="0">(Main)</option>' . "\n" . '<option value="1">Talk</option>' . "\n" . '<option value="2">User</option>' . "\n" . '<option value="3">User talk</option>' . "\n" . '<option value="4">MyWiki</option>' . "\n" . '<option value="5">MyWiki Talk</option>' . "\n" . '<option value="6">File</option>' . "\n" . '<option value="7">File talk</option>' . "\n" . '<option value="8">MediaWiki</option>' . "\n" . '<option value="9">MediaWiki talk</option>' . "\n" . '<option value="10">Template</option>' . "\n" . '<option value="11">Template talk</option>' . "\n" . '<option disabled="" value="14">Category</option>' . "\n" . '<option value="15">Category talk</option>' . "\n" . '</select>', Html::namespaceSelector(array('exclude' => array(100, 101), 'disable' => $immovable)), 'Namespace selector without the custom namespace and immovable namespaces disabled.'); }
/** * Show the form * * @param array $err error messages. Each item is an error message. * It may either be a string message name or array message name and * parameters, like the second argument to OutputPage::wrapWikiMsg(). */ function showForm($err) { global $wgContLang, $wgFixDoubleRedirects, $wgMaximumMovedPages; $this->getSkin()->setRelevantTitle($this->oldTitle); $oldTitleLink = Linker::link($this->oldTitle); $out = $this->getOutput(); $out->setPageTitle($this->msg('move-page', $this->oldTitle->getPrefixedText())); $out->addModules('mediawiki.special.movePage'); $newTitle = $this->newTitle; if (!$newTitle) { # Show the current title as a default # when the form is first opened. $newTitle = $this->oldTitle; } elseif (!count($err)) { # If a title was supplied, probably from the move log revert # link, check for validity. We can then show some diagnostic # information and save a click. $newerr = $this->oldTitle->isValidMoveOperation($newTitle); if (is_array($newerr)) { $err = $newerr; } } $user = $this->getUser(); if (count($err) == 1 && isset($err[0][0]) && $err[0][0] == 'articleexists' && $newTitle->quickUserCan('delete', $user)) { $out->addWikiMsg('delete_and_move_text', $newTitle->getPrefixedText()); $movepagebtn = $this->msg('delete_and_move')->text(); $submitVar = 'wpDeleteAndMove'; $confirm = "\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::checkLabel($this->msg('delete_and_move_confirm')->text(), 'wpConfirm', 'wpConfirm') . "</td>\n\t\t\t\t</tr>"; $err = array(); } else { if ($this->oldTitle->getNamespace() == NS_USER && !$this->oldTitle->isSubpage()) { $out->wrapWikiMsg("<div class=\"error mw-moveuserpage-warning\">\n\$1\n</div>", 'moveuserpage-warning'); } $out->addWikiMsg($wgFixDoubleRedirects ? 'movepagetext' : 'movepagetext-noredirectfixer'); $movepagebtn = $this->msg('movepagebtn')->text(); $submitVar = 'wpMove'; $confirm = false; } if (count($err) == 1 && isset($err[0][0]) && $err[0][0] == 'file-exists-sharedrepo' && $user->isAllowed('reupload-shared')) { $out->addWikiMsg('move-over-sharedrepo', $newTitle->getPrefixedText()); $submitVar = 'wpMoveOverSharedFile'; $err = array(); } $oldTalk = $this->oldTitle->getTalkPage(); $oldTitleSubpages = $this->oldTitle->hasSubpages(); $oldTitleTalkSubpages = $this->oldTitle->getTalkPage()->hasSubpages(); $canMoveSubpage = ($oldTitleSubpages || $oldTitleTalkSubpages) && !count($this->oldTitle->getUserPermissionsErrors('move-subpages', $user)); # We also want to be able to move assoc. subpage talk-pages even if base page # has no associated talk page, so || with $oldTitleTalkSubpages. $considerTalk = !$this->oldTitle->isTalkPage() && ($oldTalk->exists() || $oldTitleTalkSubpages && $canMoveSubpage); $dbr = wfGetDB(DB_SLAVE); if ($wgFixDoubleRedirects) { $hasRedirects = $dbr->selectField('redirect', '1', array('rd_namespace' => $this->oldTitle->getNamespace(), 'rd_title' => $this->oldTitle->getDBkey()), __METHOD__); } else { $hasRedirects = false; } if ($considerTalk) { $out->addWikiMsg('movepagetalktext'); } if (count($err)) { $out->addHTML("<div class='error'>\n"); $action_desc = $this->msg('action-move')->plain(); $out->addWikiMsg('permissionserrorstext-withaction', count($err), $action_desc); if (count($err) == 1) { $errMsg = $err[0]; $errMsgName = array_shift($errMsg); if ($errMsgName == 'hookaborted') { $out->addHTML("<p>{$errMsg[0]}</p>\n"); } else { $out->addWikiMsgArray($errMsgName, $errMsg); } } else { $errStr = array(); foreach ($err as $errMsg) { if ($errMsg[0] == 'hookaborted') { $errStr[] = $errMsg[1]; } else { $errMsgName = array_shift($errMsg); $errStr[] = $this->msg($errMsgName, $errMsg)->parse(); } } $out->addHTML('<ul><li>' . implode("</li>\n<li>", $errStr) . "</li></ul>\n"); } $out->addHTML("</div>\n"); } if ($this->oldTitle->isProtected('move')) { # Is the title semi-protected? if ($this->oldTitle->isSemiProtected('move')) { $noticeMsg = 'semiprotectedpagemovewarning'; $classes[] = 'mw-textarea-sprotected'; } else { # Then it must be protected based on static groups (regular) $noticeMsg = 'protectedpagemovewarning'; $classes[] = 'mw-textarea-protected'; } $out->addHTML("<div class='mw-warning-with-logexcerpt'>\n"); $out->addWikiMsg($noticeMsg); LogEventsList::showLogExtract($out, 'protect', $this->oldTitle, '', array('lim' => 1)); $out->addHTML("</div>\n"); } // Byte limit (not string length limit) for wpReason and wpNewTitleMain // is enforced in the mediawiki.special.movePage module $immovableNamespaces = array(); foreach (array_keys($this->getLanguage()->getNamespaces()) as $nsId) { if (!MWNamespace::isMovable($nsId)) { $immovableNamespaces[] = $nsId; } } $handler = ContentHandler::getForTitle($this->oldTitle); $out->addHTML(Xml::openElement('form', array('method' => 'post', 'action' => $this->getPageTitle()->getLocalURL('action=submit'), 'id' => 'movepage')) . Xml::openElement('fieldset') . Xml::element('legend', null, $this->msg('move-page-legend')->text()) . Xml::openElement('table', array('id' => 'mw-movepage-table')) . "<tr>\n\t\t\t\t<td class='mw-label'>" . $this->msg('movearticle')->escaped() . "</td>\n\t\t\t\t<td class='mw-input'>\n\t\t\t\t\t<strong>{$oldTitleLink}</strong>\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td class='mw-label'>" . Xml::label($this->msg('newtitle')->text(), 'wpNewTitleMain') . "</td>\n\t\t\t\t<td class='mw-input'>" . Html::namespaceSelector(array('selected' => $newTitle->getNamespace(), 'exclude' => $immovableNamespaces), array('name' => 'wpNewTitleNs', 'id' => 'wpNewTitleNs')) . Xml::input('wpNewTitleMain', 60, $wgContLang->recodeForEdit($newTitle->getText()), array('type' => 'text', 'id' => 'wpNewTitleMain', 'maxlength' => 255, 'class' => 'input_med')) . Html::hidden('wpOldTitle', $this->oldTitle->getPrefixedText()) . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td class='mw-label'>" . Xml::label($this->msg('movereason')->text(), 'wpReason') . "</td>\n\t\t\t\t<td class='mw-input'>" . Xml::input('wpReason', 60, $this->reason, array('type' => 'text', 'id' => 'wpReason', 'maxlength' => 200)) . "</td>\n\t\t\t</tr>"); if ($considerTalk) { $out->addHTML("\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::checkLabel($this->msg('movetalk')->text(), 'wpMovetalk', 'wpMovetalk', $this->moveTalk) . "</td>\n\t\t\t\t</tr>"); } if ($user->isAllowed('suppressredirect')) { if ($handler->supportsRedirects()) { $isChecked = $this->leaveRedirect; $options = array(); } else { $isChecked = false; $options = array('disabled' => 'disabled'); } $out->addHTML("\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-input' >" . Xml::checkLabel($this->msg('move-leave-redirect')->text(), 'wpLeaveRedirect', 'wpLeaveRedirect', $isChecked, $options) . "</td>\n\t\t\t\t</tr>"); } if ($hasRedirects) { $out->addHTML("\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-input' >" . Xml::checkLabel($this->msg('fix-double-redirects')->text(), 'wpFixRedirects', 'wpFixRedirects', $this->fixRedirects) . "</td>\n\t\t\t\t</tr>"); } if ($canMoveSubpage) { $out->addHTML("\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class=\"mw-input\">" . Xml::check('wpMovesubpages', $this->moveSubpages && ($this->oldTitle->hasSubpages() || $this->moveTalk), array('id' => 'wpMovesubpages')) . ' ' . Xml::tags('label', array('for' => 'wpMovesubpages'), $this->msg($this->oldTitle->hasSubpages() ? 'move-subpages' : 'move-talk-subpages')->numParams($wgMaximumMovedPages)->params($wgMaximumMovedPages)->parse()) . "</td>\n\t\t\t\t</tr>"); } $watchChecked = $user->isLoggedIn() && ($this->watch || $user->getBoolOption('watchmoves') || $user->isWatched($this->oldTitle)); # Don't allow watching if user is not logged in if ($user->isLoggedIn()) { $out->addHTML("\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td class='mw-input'>" . Xml::checkLabel($this->msg('move-watch')->text(), 'wpWatch', 'watch', $watchChecked) . "</td>\n\t\t\t</tr>"); } $out->addHTML("\n\t\t\t\t{$confirm}\n\t\t\t<tr>\n\t\t\t\t<td> </td>\n\t\t\t\t<td class='mw-submit'>" . Xml::submitButton($movepagebtn, array('name' => $submitVar, 'class' => 'button primary')) . "</td>\n\t\t\t</tr>" . Xml::closeElement('table') . Html::hidden('wpEditToken', $user->getEditToken()) . Xml::closeElement('fieldset') . Xml::closeElement('form') . "\n"); $this->showLogFragment($this->oldTitle); $this->showSubpages($this->oldTitle); }