public function execute($par) { $this->checkPermissions(); $this->checkReadOnly(); list($this->target, $this->type) = SpecialBlock::getTargetAndType($par, $this->getRequest()); $this->block = Block::newFromTarget($this->target); $this->setHeaders(); $this->outputHeader(); $out = $this->getOutput(); $out->setPageTitle($this->msg('unblockip')); $out->addModules('mediawiki.special'); $form = new HTMLForm($this->getFields(), $this->getContext()); $form->setWrapperLegendMsg('unblockip'); $form->setSubmitCallback(array(__CLASS__, 'processUIUnblock')); $form->setSubmitTextMsg('ipusubmit'); $form->addPreText($this->msg('unblockiptext')->parseAsBlock()); if ($form->show()) { switch ($this->type) { case Block::TYPE_USER: case Block::TYPE_IP: $out->addWikiMsg('unblocked', wfEscapeWikiText($this->target)); break; case Block::TYPE_RANGE: $out->addWikiMsg('unblocked-range', wfEscapeWikiText($this->target)); break; case Block::TYPE_ID: case Block::TYPE_AUTO: $out->addWikiMsg('unblocked-id', wfEscapeWikiText($this->target)); break; } } }
function __construct(IContextSource $context, $userName = null, $search = '', $including = false, $showAll = false) { $this->setContext($context); $this->mIncluding = $including; $this->mShowAll = $showAll; if ($userName !== null && $userName !== '') { $nt = Title::newFromText($userName, NS_USER); $user = User::newFromName($userName, false); if (!is_null($nt)) { $this->mUserName = $nt->getText(); } if (!$user || $user->isAnon() && !User::isIP($user->getName())) { $this->getOutput()->wrapWikiMsg("<div class=\"mw-userpage-userdoesnotexist error\">\n\$1\n</div>", array('listfiles-userdoesnotexist', wfEscapeWikiText($userName))); } } if ($search !== '' && !$this->getConfig()->get('MiserMode')) { $this->mSearch = $search; $nt = Title::newFromURL($this->mSearch); if ($nt) { $dbr = wfGetDB(DB_SLAVE); $this->mQueryConds[] = 'LOWER(img_name)' . $dbr->buildLike($dbr->anyString(), strtolower($nt->getDBkey()), $dbr->anyString()); } } if (!$including) { if ($this->getRequest()->getText('sort', 'img_date') == 'img_date') { $this->mDefaultDirection = IndexPager::DIR_DESCENDING; } else { $this->mDefaultDirection = IndexPager::DIR_ASCENDING; } } else { $this->mDefaultDirection = IndexPager::DIR_DESCENDING; } parent::__construct($context); }
function execute() { global $wgOut, $wgUser; $wgOut->setPagetitle(wfMsgHtml("mergehistory")); if ($this->mTargetID && $this->mDestID && $this->mAction == "submit" && $this->mMerge) { return $this->merge(); } if (!$this->mSubmitted) { $this->showMergeForm(); return; } $errors = array(); if (!$this->mTargetObj instanceof Title) { $errors[] = wfMsgExt('mergehistory-invalid-source', array('parse')); } elseif (!$this->mTargetObj->exists()) { $errors[] = wfMsgExt('mergehistory-no-source', array('parse'), wfEscapeWikiText($this->mTargetObj->getPrefixedText())); } if (!$this->mDestObj instanceof Title) { $errors[] = wfMsgExt('mergehistory-invalid-destination', array('parse')); } elseif (!$this->mDestObj->exists()) { $errors[] = wfMsgExt('mergehistory-no-destination', array('parse'), wfEscapeWikiText($this->mDestObj->getPrefixedText())); } if ($this->mTargetObj->equals($this->mDestObj)) { $errors[] = wfMsgExt('mergehistory-same-destination', array('parse')); } if (count($errors)) { $this->showMergeForm(); $wgOut->addHTML(implode("\n", $errors)); } else { $this->showHistory(); } }
function Html5SetSpamMessage($match = false) { Html5editor::$spam_message = wfMsg('spamprotectiontext'); if ($match) { Html5editor::$spam_message .= wfMsgExt('spamprotectionmatch', 'parse', wfEscapeWikiText($match)); } return true; }
/** * This function limits the possible charactes passed as template keys and * values to letters, numbers, hypens and underscores. The function also * performs standard escaping of the passed values. * * @param $string The unsafe string to escape and check for invalid characters * @return mixed|String A string matching the regex or an empty string */ function makeSafe($string) { $num = preg_match('([a-zA-Z0-9_-]+)', $string, $matches); if ($num == 1) { # theoretically this is overkill, but better safe than sorry return wfEscapeWikiText(htmlspecialchars($matches[0])); } return ''; }
function execute($params = null) { global $IP, $wgWikiaLocalSettingsPath; /* go with each supplied wiki and delete the supplied article load all configs for particular wikis before doing so (from wikifactory, not by _obsolete_ maintenance scripts and from LocalSettings as worked on fps) */ $this->mTaskID = $params->task_id; $oUser = User::newFromId($params->task_user_id); if ($oUser instanceof User) { $oUser->load(); $this->mUser = $oUser->getName(); } else { $this->log("Invalid user - id: " . $params->task_user_id); return true; } $data = unserialize($params->task_arguments); foreach ($data['page_list'] as $imageData) { $retval = ""; list($wikiId, $imageId) = $imageData; $dbname = WikiFactory::getWikiByID($wikiId); if (!$dbname) { continue; } $title = GlobalTitle::newFromId($imageId, $wikiId); if (!is_object($title)) { $this->log('Apparently the article does not exist anymore'); continue; } $city_url = WikiFactory::getVarValueByName("wgServer", $wikiId); if (empty($city_url)) { continue; } $city_path = WikiFactory::getVarValueByName("wgScript", $wikiId); $city_lang = WikiFactory::getVarValueByName("wgLanguageCode", $wikiId); $reason = wfMsgExt('imagereview-reason', array('language' => $city_lang)); $sCommand = "perl /usr/wikia/backend/bin/run_maintenance --id={$wikiId} --script=wikia/deleteOn.php "; $sCommand .= "-- "; $sCommand .= "-u " . escapeshellarg($this->mUser) . " "; $sCommand .= "-t " . escapeshellarg($title->getPrefixedText()) . " "; if ($reason) { $sCommand .= "-r " . escapeshellarg($reason) . " "; } $actual_title = wfShellExec($sCommand, $retval); if ($retval) { $this->addLog('Article deleting error! (' . $city_url . '). Error code returned: ' . $retval . ' Error was: ' . $actual_title); } else { $this->addLog('Removed: <a href="' . $city_url . $city_path . '?title=' . wfEscapeWikiText($actual_title) . '">' . $city_url . $city_path . '?title=' . $actual_title . '</a>'); } $this->flagUser($imageId, $wikiId); $this->flagWiki($wikiId); } return true; }
/** * Constructor */ function wfSpecialImport($page = '') { global $wgUser, $wgOut, $wgLang, $wgRequest, $wgTitle; global $wgImportSources; ### # $wgOut->addWikiText( "Special:Import is not ready for this beta release, sorry." ); # return; ### if ($wgRequest->wasPosted() && $wgRequest->getVal('action') == 'submit') { switch ($wgRequest->getVal("source")) { case "upload": if ($wgUser->isAllowed('importupload')) { $source = ImportStreamSource::newFromUpload("xmlimport"); } else { return $wgOut->permissionRequired('importupload'); } break; case "interwiki": $source = ImportStreamSource::newFromInterwiki($wgRequest->getVal("interwiki"), $wgRequest->getText("frompage")); break; default: $source = new WikiError("Unknown import source type"); } if (WikiError::isError($source)) { $wgOut->addWikiText(wfEscapeWikiText($source->getMessage())); } else { $importer = new WikiImporter($source); $result = $importer->doImport(); if (WikiError::isError($result)) { $wgOut->addWikiText(wfMsg("importfailed", wfEscapeWikiText($result->getMessage()))); } else { # Success! $wgOut->addWikiText(wfMsg("importsuccess")); } } } $action = $wgTitle->escapeLocalUrl('action=submit'); if ($wgUser->isAllowed('importupload')) { $wgOut->addWikiText(wfMsg("importtext")); $wgOut->addHTML("\n<fieldset>\n\t<legend>" . wfMsgHtml('upload') . "</legend>\n\t<form enctype='multipart/form-data' method='post' action=\"{$action}\">\n\t\t<input type='hidden' name='action' value='submit' />\n\t\t<input type='hidden' name='source' value='upload' />\n\t\t<input type='hidden' name='MAX_FILE_SIZE' value='2000000' />\n\t\t<input type='file' name='xmlimport' value='' size='30' />\n\t\t<input type='submit' value='" . wfMsgHtml("uploadbtn") . "'/>\n\t</form>\n</fieldset>\n"); } else { if (empty($wgImportSources)) { $wgOut->addWikiText(wfMsg('importnosources')); } } if (!empty($wgImportSources)) { $wgOut->addHTML("\n<fieldset>\n\t<legend>" . wfMsgHtml('importinterwiki') . "</legend>\n\t<form method='post' action=\"{$action}\">\n\t\t<input type='hidden' name='action' value='submit' />\n\t\t<input type='hidden' name='source' value='interwiki' />\n\t\t<select name='interwiki'>\n"); foreach ($wgImportSources as $interwiki) { $iw = htmlspecialchars($interwiki); $wgOut->addHTML("<option value=\"{$iw}\">{$iw}</option>\n"); } $wgOut->addHTML("\n\t\t</select>\n\t\t<input name='frompage' />\n\t\t<input type='submit' />\n\t</form>\n</fieldset>\n"); } }
/** * @see ValueFormatter::format * * @param MonolingualTextValue $value * * @throws InvalidArgumentException * @return string HTML */ public function format($value) { if (!$value instanceof MonolingualTextValue) { throw new InvalidArgumentException('Data value type mismatch. Expected a MonolingualTextValue.'); } $text = $value->getText(); $languageCode = $value->getLanguageCode(); $languageName = $this->languageNameLookup->getName($languageCode); $msg = wfMessage('wikibase-monolingualtext')->params(wfEscapeWikiText($text), wfEscapeWikiText($languageCode), wfEscapeWikiText($languageName)); return $msg->parse(); }
/** * Main execution function * * @param $par Mixed: Parameters passed to the page */ public function execute($par) { $out = $this->getOutput(); $title = ShortUrlUtils::decodeURL($par); if ($title !== false) { $out->redirect($title->getFullURL(), '301'); } else { $parEsc = wfEscapeWikiText($par); $out->showErrorPage('shorturl-not-found-title', 'shorturl-not-found-message', array($parEsc)); } }
/** * @see SnakFormatter::format * * Formats the given Snak as an wikitext link to an authoritative resource. * The URL of that link is determined using a SnakUrlExpander. * If the snak could not be expanded into a URL, the identifier is returned as simple text. * * @param Snak $snak * * @throws ParameterTypeException if $snak is not a PropertyValueSnak, or if $snak->getDataValue() * does not return a StringValue. * @return string Wikitext */ public function formatSnak(Snak $snak) { Assert::parameterType('Wikibase\\DataModel\\Snak\\PropertyValueSnak', $snak, '$snak'); /** @var PropertyValueSnak $snak */ $id = $snak->getDataValue()->getValue(); $url = $this->urlExpander->expandUrl($snak); if ($url === null) { return wfEscapeWikiText($id); } else { return '[' . $this->escapeWikitextInUrl($url) . ' ' . wfEscapeWikiText($id) . ']'; } }
public function delete($pageList, $suppress = false) { global $IP; $user = \User::newFromId($this->createdBy); $userName = $user->getName(); $articlesDeleted = 0; foreach ($pageList as $imageData) { list($wikiId, $imageId) = $imageData; if (!\WikiFactory::isPublic($wikiId)) { $this->notice('wiki has been disabled', ['wiki_id' => $wikiId]); continue; } $dbname = \WikiFactory::getWikiByID($wikiId); if (!$dbname) { $this->warning('did not find database', ['wiki_id' => $wikiId]); continue; } $cityUrl = \WikiFactory::getVarValueByName('wgServer', $wikiId); if (empty($cityUrl)) { $this->warning('could not determine city url', ['wiki_id' => $wikiId]); continue; } $cityLang = \WikiFactory::getVarValueByName('wgLanguageCode', $wikiId); $reason = wfMsgExt('imagereview-reason', ['language' => $cityLang]); $command = "SERVER_ID={$wikiId} php {$IP}/maintenance/wikia/deleteOn.php" . ' -u ' . escapeshellarg($userName) . ' --id ' . $imageId; if ($reason) { $command .= ' -r ' . escapeshellarg($reason); } if ($suppress) { $command .= ' -s'; } $title = wfShellExec($command, $exitStatus); if ($exitStatus !== 0) { $this->error('article deletion error', ['city_url' => $cityUrl, 'exit_status' => $exitStatus, 'error' => $title]); continue; } $cityPath = \WikiFactory::getVarValueByName('wgScript', $wikiId); $escapedTitle = wfEscapeWikiText($title); $this->info('removed image', ['link' => "{$cityUrl}{$cityPath}?title={$escapedTitle}", 'title' => $escapedTitle]); ++$articlesDeleted; } $success = $articlesDeleted == count($pageList); if (!$success) { $this->sendNotification(); } return $success; }
function show() { global $wgOut; $wgOut->setRobotpolicy('noindex,nofollow'); if (is_null($this->mTitle) || !$this->mTitle->exists() || $this->mTitle->getNamespace() == NS_MEDIAWIKI) { $wgOut->showFatalError(wfMsg('badarticleerror')); return; } if ($this->save()) { $wgOut->redirect($this->mTitle->getFullUrl()); return; } $wgOut->setPageTitle(wfMsg('confirmprotect')); $wgOut->setSubtitle(wfMsg('protectsub', $this->mTitle->getPrefixedText())); $wgOut->addWikiText(wfMsg($this->disabled ? "protect-viewtext" : "protect-text", wfEscapeWikiText($this->mTitle->getPrefixedText()))); $wgOut->addHTML($this->buildForm()); $this->showLogExtract($wgOut); }
function listForm($username, $reason) { global $wgUser, $wgOut, $wgLang; $pages = $this->getNewPages($username); $escapedName = wfEscapeWikiText($username); if (count($pages) == 0) { $wgOut->addWikiText(wfMsg('nuke-nopages', $escapedName)); return $this->promptForm(); } $wgOut->addWikiText(wfMsg('nuke-list', $escapedName)); $nuke = Title::makeTitle(NS_SPECIAL, 'Nuke'); $submit = wfElement('input', array('type' => 'submit', 'value' => wfMsgHtml('nuke-submit-delete'))); $wgOut->addHTML(wfElement('form', array('action' => $nuke->getLocalURL('action=delete'), 'method' => 'post'), null) . "\n<div>" . wfMsgHtml('deletecomment') . ': ' . wfElement('input', array('name' => 'wpReason', 'value' => $reason, 'size' => 60)) . "</div><br />" . $submit . wfElement('input', array('type' => 'hidden', 'name' => 'wpEditToken', 'value' => $wgUser->editToken())) . "\n<ul>\n"); $sk =& $wgUser->getSkin(); foreach ($pages as $info) { list($title, $edits) = $info; $wgOut->addHTML('<li>' . wfElement('input', array('type' => 'checkbox', 'name' => "pages[]", 'value' => $title->getPrefixedDbKey(), 'checked' => 'checked')) . ' ' . $sk->makeKnownLinkObj($title) . ' (' . $sk->makeKnownLinkObj($title, wfMsgExt('nchanges', array('parsemag'), $wgLang->formatNum($edits)), 'action=history') . ")</li>\n"); } $wgOut->addHTML("</ul>\n{$submit}</form>"); }
public function execute($par) { $this->checkPermissions(); $this->checkReadOnly(); list($this->target, $this->type) = SpecialBlock::getTargetAndType($par, $this->getRequest()); $this->block = Block::newFromTarget($this->target); if ($this->target instanceof User) { # Set the 'relevant user' in the skin, so it displays links like Contributions, # User logs, UserRights, etc. $this->getSkin()->setRelevantUser($this->target); } $this->setHeaders(); $this->outputHeader(); $out = $this->getOutput(); $out->setPageTitle($this->msg('unblockip')); $out->addModules(['mediawiki.special', 'mediawiki.userSuggest']); $form = new HTMLForm($this->getFields(), $this->getContext()); $form->setWrapperLegendMsg('unblockip'); $form->setSubmitCallback([__CLASS__, 'processUIUnblock']); $form->setSubmitTextMsg('ipusubmit'); $form->addPreText($this->msg('unblockiptext')->parseAsBlock()); if ($form->show()) { switch ($this->type) { case Block::TYPE_IP: $out->addWikiMsg('unblocked-ip', wfEscapeWikiText($this->target)); break; case Block::TYPE_USER: $out->addWikiMsg('unblocked', wfEscapeWikiText($this->target)); break; case Block::TYPE_RANGE: $out->addWikiMsg('unblocked-range', wfEscapeWikiText($this->target)); break; case Block::TYPE_ID: case Block::TYPE_AUTO: $out->addWikiMsg('unblocked-id', wfEscapeWikiText($this->target)); break; } } }
private function showCurrent() { global $wgOut, $wgMemc; $wgOut->addHTML("<fieldset>\n"); $wgOut->addHTML("<legend>CurrentValue</legend>\n"); $sysopId = $wgMemc->get(wfMemcKey("last-sysop-id")); if ($sysopId) { $this->mSysop = User::newFromId($sysopId); $sysopName = wfEscapeWikiText($this->mSysop->getName()); $groups = $this->mSysop->getEffectiveGroups(); $wgOut->addHTML("ID: <code>" . $sysopId . "</code><br/>"); $wgOut->addHTML("Name: <code>" . $sysopName . "</code><br/>"); $wgOut->addHTML("Groups: <code>" . implode(", ", $groups) . "</code><br/>"); $action_url = $this->mTitle->getFullURL(); $wgOut->addHTML("<form action='{$action_url}' method='post'>\n"); $wgOut->addHTML("<input type='hidden' name='method' value='clear' />\n"); $wgOut->addHTML("<input type='submit' value='clear' />\n"); $wgOut->addHTML("</form>\n"); } else { $wgOut->addHTML("<i>n/a</i>"); } $wgOut->addHTML("</fieldset>\n"); }
/** * Recursively-called function to actually construct the help * * @param IContextSource $context * @param ApiBase[] $modules * @param array $options * @param array &$haveModules * @return string */ private static function getHelpInternal(IContextSource $context, array $modules, array $options, &$haveModules) { $out = ''; $level = empty($options['headerlevel']) ? 2 : $options['headerlevel']; if (empty($options['tocnumber'])) { $tocnumber = array(2 => 0); } else { $tocnumber =& $options['tocnumber']; } foreach ($modules as $module) { $tocnumber[$level]++; $path = $module->getModulePath(); $module->setContext($context); $help = array('header' => '', 'flags' => '', 'description' => '', 'help-urls' => '', 'parameters' => '', 'examples' => '', 'submodules' => ''); if (empty($options['noheader']) || !empty($options['toc'])) { $anchor = $path; $i = 1; while (isset($haveModules[$anchor])) { $anchor = $path . '|' . ++$i; } if ($module->isMain()) { $header = $context->msg('api-help-main-header')->parse(); } else { $name = $module->getModuleName(); $header = $module->getParent()->getModuleManager()->getModuleGroup($name) . "={$name}"; if ($module->getModulePrefix() !== '') { $header .= ' ' . $context->msg('parentheses', $module->getModulePrefix())->parse(); } } $haveModules[$anchor] = array('toclevel' => count($tocnumber), 'level' => $level, 'anchor' => $anchor, 'line' => $header, 'number' => join('.', $tocnumber), 'index' => false); if (empty($options['noheader'])) { $help['header'] .= Html::element('h' . min(6, $level), array('id' => $anchor, 'class' => 'apihelp-header'), $header); } } else { $haveModules[$path] = true; } $links = array(); $any = false; for ($m = $module; $m !== null; $m = $m->getParent()) { $name = $m->getModuleName(); if ($name === 'main_int') { $name = 'main'; } if (count($modules) === 1 && $m === $modules[0] && !(!empty($options['submodules']) && $m->getModuleManager())) { $link = Html::element('b', null, $name); } else { $link = SpecialPage::getTitleFor('ApiHelp', $m->getModulePath())->getLocalURL(); $link = Html::element('a', array('href' => $link, 'class' => 'apihelp-linktrail'), $name); $any = true; } array_unshift($links, $link); } if ($any) { $help['header'] .= self::wrap($context->msg('parentheses')->rawParams($context->getLanguage()->pipeList($links)), 'apihelp-linktrail', 'div'); } $flags = $module->getHelpFlags(); $help['flags'] .= Html::openElement('div', array('class' => 'apihelp-block apihelp-flags')); $msg = $context->msg('api-help-flags'); if (!$msg->isDisabled()) { $help['flags'] .= self::wrap($msg->numParams(count($flags)), 'apihelp-block-head', 'div'); } $help['flags'] .= Html::openElement('ul'); foreach ($flags as $flag) { $help['flags'] .= Html::rawElement('li', null, self::wrap($context->msg("api-help-flag-{$flag}"), "apihelp-flag-{$flag}")); } $sourceInfo = $module->getModuleSourceInfo(); if ($sourceInfo) { if (isset($sourceInfo['namemsg'])) { $extname = $context->msg($sourceInfo['namemsg'])->text(); } else { $extname = $sourceInfo['name']; } $help['flags'] .= Html::rawElement('li', null, self::wrap($context->msg('api-help-source', $extname, $sourceInfo['name']), 'apihelp-source')); $link = SpecialPage::getTitleFor('Version', 'License/' . $sourceInfo['name']); if (isset($sourceInfo['license-name'])) { $msg = $context->msg('api-help-license', $link, $sourceInfo['license-name']); } elseif (SpecialVersion::getExtLicenseFileName(dirname($sourceInfo['path']))) { $msg = $context->msg('api-help-license-noname', $link); } else { $msg = $context->msg('api-help-license-unknown'); } $help['flags'] .= Html::rawElement('li', null, self::wrap($msg, 'apihelp-license')); } else { $help['flags'] .= Html::rawElement('li', null, self::wrap($context->msg('api-help-source-unknown'), 'apihelp-source')); $help['flags'] .= Html::rawElement('li', null, self::wrap($context->msg('api-help-license-unknown'), 'apihelp-license')); } $help['flags'] .= Html::closeElement('ul'); $help['flags'] .= Html::closeElement('div'); foreach ($module->getFinalDescription() as $msg) { $msg->setContext($context); $help['description'] .= $msg->parseAsBlock(); } $urls = $module->getHelpUrls(); if ($urls) { $help['help-urls'] .= Html::openElement('div', array('class' => 'apihelp-block apihelp-help-urls')); $msg = $context->msg('api-help-help-urls'); if (!$msg->isDisabled()) { $help['help-urls'] .= self::wrap($msg->numParams(count($urls)), 'apihelp-block-head', 'div'); } if (!is_array($urls)) { $urls = array($urls); } $help['help-urls'] .= Html::openElement('ul'); foreach ($urls as $url) { $help['help-urls'] .= Html::rawElement('li', null, Html::element('a', array('href' => $url), $url)); } $help['help-urls'] .= Html::closeElement('ul'); $help['help-urls'] .= Html::closeElement('div'); } $params = $module->getFinalParams(ApiBase::GET_VALUES_FOR_HELP); $dynamicParams = $module->dynamicParameterDocumentation(); $groups = array(); if ($params || $dynamicParams !== null) { $help['parameters'] .= Html::openElement('div', array('class' => 'apihelp-block apihelp-parameters')); $msg = $context->msg('api-help-parameters'); if (!$msg->isDisabled()) { $help['parameters'] .= self::wrap($msg->numParams(count($params)), 'apihelp-block-head', 'div'); } $help['parameters'] .= Html::openElement('dl'); $descriptions = $module->getFinalParamDescription(); foreach ($params as $name => $settings) { if (!is_array($settings)) { $settings = array(ApiBase::PARAM_DFLT => $settings); } $help['parameters'] .= Html::element('dt', null, $module->encodeParamName($name)); // Add description $description = array(); if (isset($descriptions[$name])) { foreach ($descriptions[$name] as $msg) { $msg->setContext($context); $description[] = $msg->parseAsBlock(); } } // Add usage info $info = array(); // Required? if (!empty($settings[ApiBase::PARAM_REQUIRED])) { $info[] = $context->msg('api-help-param-required')->parse(); } // Custom info? if (!empty($settings[ApiBase::PARAM_HELP_MSG_INFO])) { foreach ($settings[ApiBase::PARAM_HELP_MSG_INFO] as $i) { $tag = array_shift($i); $info[] = $context->msg("apihelp-{$path}-paraminfo-{$tag}")->numParams(count($i))->params($context->getLanguage()->commaList($i))->params($module->getModulePrefix())->parse(); } } // Type documentation if (!isset($settings[ApiBase::PARAM_TYPE])) { $dflt = isset($settings[ApiBase::PARAM_DFLT]) ? $settings[ApiBase::PARAM_DFLT] : null; if (is_bool($dflt)) { $settings[ApiBase::PARAM_TYPE] = 'boolean'; } elseif (is_string($dflt) || is_null($dflt)) { $settings[ApiBase::PARAM_TYPE] = 'string'; } elseif (is_int($dflt)) { $settings[ApiBase::PARAM_TYPE] = 'integer'; } } if (isset($settings[ApiBase::PARAM_TYPE])) { $type = $settings[ApiBase::PARAM_TYPE]; $multi = !empty($settings[ApiBase::PARAM_ISMULTI]); $hintPipeSeparated = true; $count = ApiBase::LIMIT_SML2 + 1; if (is_array($type)) { $count = count($type); $links = isset($settings[ApiBase::PARAM_VALUE_LINKS]) ? $settings[ApiBase::PARAM_VALUE_LINKS] : array(); $type = array_map(function ($v) use($links) { $ret = wfEscapeWikiText($v); if (isset($links[$v])) { $ret = "[[{$links[$v]}|{$ret}]]"; } return $ret; }, $type); $i = array_search('', $type, true); if ($i === false) { $type = $context->getLanguage()->commaList($type); } else { unset($type[$i]); $type = $context->msg('api-help-param-list-can-be-empty')->numParams(count($type))->params($context->getLanguage()->commaList($type))->parse(); } $info[] = $context->msg('api-help-param-list')->params($multi ? 2 : 1)->params($type)->parse(); $hintPipeSeparated = false; } else { switch ($type) { case 'submodule': $groups[] = $name; if (isset($settings[ApiBase::PARAM_SUBMODULE_MAP])) { $map = $settings[ApiBase::PARAM_SUBMODULE_MAP]; ksort($map); $submodules = array(); foreach ($map as $v => $m) { $submodules[] = "[[Special:ApiHelp/{$m}|{$v}]]"; } } else { $submodules = $module->getModuleManager()->getNames($name); sort($submodules); $prefix = $module->isMain() ? '' : $module->getModulePath() . '+'; $submodules = array_map(function ($name) use($prefix) { return "[[Special:ApiHelp/{$prefix}{$name}|{$name}]]"; }, $submodules); } $count = count($submodules); $info[] = $context->msg('api-help-param-list')->params($multi ? 2 : 1)->params($context->getLanguage()->commaList($submodules))->parse(); $hintPipeSeparated = false; // No type message necessary, we have a list of values. $type = null; break; case 'namespace': $namespaces = MWNamespace::getValidNamespaces(); $count = count($namespaces); $info[] = $context->msg('api-help-param-list')->params($multi ? 2 : 1)->params($context->getLanguage()->commaList($namespaces))->parse(); $hintPipeSeparated = false; // No type message necessary, we have a list of values. $type = null; break; case 'limit': if (isset($settings[ApiBase::PARAM_MAX2])) { $info[] = $context->msg('api-help-param-limit2')->numParams($settings[ApiBase::PARAM_MAX])->numParams($settings[ApiBase::PARAM_MAX2])->parse(); } else { $info[] = $context->msg('api-help-param-limit')->numParams($settings[ApiBase::PARAM_MAX])->parse(); } break; case 'integer': // Possible messages: // api-help-param-integer-min, // api-help-param-integer-max, // api-help-param-integer-minmax $suffix = ''; $min = $max = 0; if (isset($settings[ApiBase::PARAM_MIN])) { $suffix .= 'min'; $min = $settings[ApiBase::PARAM_MIN]; } if (isset($settings[ApiBase::PARAM_MAX])) { $suffix .= 'max'; $max = $settings[ApiBase::PARAM_MAX]; } if ($suffix !== '') { $info[] = $context->msg("api-help-param-integer-{$suffix}")->params($multi ? 2 : 1)->numParams($min, $max)->parse(); } break; case 'upload': $info[] = $context->msg('api-help-param-upload')->parse(); // No type message necessary, api-help-param-upload should handle it. $type = null; break; case 'string': case 'text': // Displaying a type message here would be useless. $type = null; break; } } // Add type. Messages for grep: api-help-param-type-limit // api-help-param-type-integer api-help-param-type-boolean // api-help-param-type-timestamp api-help-param-type-user // api-help-param-type-password if (is_string($type)) { $msg = $context->msg("api-help-param-type-{$type}"); if (!$msg->isDisabled()) { $info[] = $msg->params($multi ? 2 : 1)->parse(); } } if ($multi) { $extra = array(); if ($hintPipeSeparated) { $extra[] = $context->msg('api-help-param-multi-separate')->parse(); } if ($count > ApiBase::LIMIT_SML1) { $extra[] = $context->msg('api-help-param-multi-max')->numParams(ApiBase::LIMIT_SML1, ApiBase::LIMIT_SML2)->parse(); } if ($extra) { $info[] = join(' ', $extra); } } } // Add default $default = isset($settings[ApiBase::PARAM_DFLT]) ? $settings[ApiBase::PARAM_DFLT] : null; if ($default === '') { $info[] = $context->msg('api-help-param-default-empty')->parse(); } elseif ($default !== null && $default !== false) { $info[] = $context->msg('api-help-param-default')->params(wfEscapeWikiText($default))->parse(); } if (!array_filter($description)) { $description = array(self::wrap($context->msg('api-help-param-no-description'), 'apihelp-empty')); } // Add "deprecated" flag if (!empty($settings[ApiBase::PARAM_DEPRECATED])) { $help['parameters'] .= Html::openElement('dd', array('class' => 'info')); $help['parameters'] .= self::wrap($context->msg('api-help-param-deprecated'), 'apihelp-deprecated', 'strong'); $help['parameters'] .= Html::closeElement('dd'); } if ($description) { $description = join('', $description); $description = preg_replace('!\\s*</([oud]l)>\\s*<\\1>\\s*!', "\n", $description); $help['parameters'] .= Html::rawElement('dd', array('class' => 'description'), $description); } foreach ($info as $i) { $help['parameters'] .= Html::rawElement('dd', array('class' => 'info'), $i); } } if ($dynamicParams !== null) { $dynamicParams = ApiBase::makeMessage($dynamicParams, $context, array($module->getModulePrefix(), $module->getModuleName(), $module->getModulePath())); $help['parameters'] .= Html::element('dt', null, '*'); $help['parameters'] .= Html::rawElement('dd', array('class' => 'description'), $dynamicParams->parse()); } $help['parameters'] .= Html::closeElement('dl'); $help['parameters'] .= Html::closeElement('div'); } $examples = $module->getExamplesMessages(); if ($examples) { $help['examples'] .= Html::openElement('div', array('class' => 'apihelp-block apihelp-examples')); $msg = $context->msg('api-help-examples'); if (!$msg->isDisabled()) { $help['examples'] .= self::wrap($msg->numParams(count($examples)), 'apihelp-block-head', 'div'); } $help['examples'] .= Html::openElement('dl'); foreach ($examples as $qs => $msg) { $msg = ApiBase::makeMessage($msg, $context, array($module->getModulePrefix(), $module->getModuleName(), $module->getModulePath())); $link = wfAppendQuery(wfScript('api'), $qs); $help['examples'] .= Html::rawElement('dt', null, $msg->parse()); $help['examples'] .= Html::rawElement('dd', null, Html::element('a', array('href' => $link), "api.php?{$qs}")); } $help['examples'] .= Html::closeElement('dl'); $help['examples'] .= Html::closeElement('div'); } $subtocnumber = $tocnumber; $subtocnumber[$level + 1] = 0; $suboptions = array('submodules' => $options['recursivesubmodules'], 'headerlevel' => $level + 1, 'tocnumber' => &$subtocnumber, 'noheader' => false) + $options; if ($options['submodules'] && $module->getModuleManager()) { $manager = $module->getModuleManager(); $submodules = array(); foreach ($groups as $group) { $names = $manager->getNames($group); sort($names); foreach ($names as $name) { $submodules[] = $manager->getModule($name); } } $help['submodules'] .= self::getHelpInternal($context, $submodules, $suboptions, $haveModules); } $module->modifyHelp($help, $suboptions, $haveModules); Hooks::run('APIHelpModifyOutput', array($module, &$help, $suboptions, &$haveModules)); $out .= join("\n", $help); } return $out; }
/** * Check if there's an overwrite conflict and, if so, if restrictions * forbid this user from performing the upload. * * @return mixed true on success, WikiError on failure * @access private */ function checkOverwrite($name) { $img = Image::newFromName($name); if (is_null($img)) { // Uh... this shouldn't happen ;) // But if it does, fall through to previous behavior return false; } $error = ''; if ($img->exists()) { global $wgUser, $wgOut; if ($img->isLocal()) { if (!$wgUser->isAllowed('reupload')) { $error = 'fileexists-forbidden'; } } else { if (!$wgUser->isAllowed('reupload') || !$wgUser->isAllowed('reupload-shared')) { $error = "fileexists-shared-forbidden"; } } } if ($error) { $errorText = wfMsg($error, wfEscapeWikiText($img->getName())); return new WikiError($wgOut->parse($errorText)); } // Rockin', go ahead and upload return true; }
public function execute($par) { $this->useTransactionalTimeLimit(); $this->checkPermissions(); $this->checkReadOnly(); $this->loadRequestParams(); $this->setHeaders(); $this->outputHeader(); if ($this->mTargetID && $this->mDestID && $this->mAction == 'submit' && $this->mMerge) { $this->merge(); return; } if (!$this->mSubmitted) { $this->showMergeForm(); return; } $errors = []; if (!$this->mTargetObj instanceof Title) { $errors[] = $this->msg('mergehistory-invalid-source')->parseAsBlock(); } elseif (!$this->mTargetObj->exists()) { $errors[] = $this->msg('mergehistory-no-source', wfEscapeWikiText($this->mTargetObj->getPrefixedText()))->parseAsBlock(); } if (!$this->mDestObj instanceof Title) { $errors[] = $this->msg('mergehistory-invalid-destination')->parseAsBlock(); } elseif (!$this->mDestObj->exists()) { $errors[] = $this->msg('mergehistory-no-destination', wfEscapeWikiText($this->mDestObj->getPrefixedText()))->parseAsBlock(); } if ($this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals($this->mDestObj)) { $errors[] = $this->msg('mergehistory-same-destination')->parseAsBlock(); } if (count($errors)) { $this->showMergeForm(); $this->getOutput()->addHTML(implode("\n", $errors)); } else { $this->showHistory(); } }
/** * Show the input form with optional error message * * @param string $err error message or null if there's no error */ function show($err = null) { global $wgOut; $wgOut->setRobotPolicy('noindex,nofollow'); $wgOut->addBacklinkSubtitle($this->mTitle); if (is_array($err)) { $wgOut->wrapWikiMsg("<p class='error'>\n\$1\n</p>\n", $err); } elseif (is_string($err)) { $wgOut->addHTML("<p class='error'>{$err}</p>\n"); } if ($this->mTitle->getRestrictionTypes() === array()) { // No restriction types available for the current title // this might happen if an extension alters the available types $wgOut->setPageTitle(wfMessage('protect-norestrictiontypes-title', $this->mTitle->getPrefixedText())); $wgOut->addWikiText(wfMessage('protect-norestrictiontypes-text')->text()); // Show the log in case protection was possible once $this->showLogExtract($wgOut); // return as there isn't anything else we can do return; } list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources(); if ($cascadeSources && count($cascadeSources) > 0) { $titles = ''; foreach ($cascadeSources as $title) { $titles .= '* [[:' . $title->getPrefixedText() . "]]\n"; } $wgOut->wrapWikiMsg("<div id=\"mw-protect-cascadeon\">\n\$1\n" . $titles . "</div>", array('protect-cascadeon', count($cascadeSources))); } # Show an appropriate message if the user isn't allowed or able to change # the protection settings at this time if ($this->disabled) { $wgOut->setPageTitle(wfMessage('protect-title-notallowed', $this->mTitle->getPrefixedText())); $wgOut->addWikiText($wgOut->formatPermissionsErrorMessage($this->mPermErrors, 'protect')); } else { $wgOut->setPageTitle(wfMessage('protect-title', $this->mTitle->getPrefixedText())); $wgOut->addWikiMsg('protect-text', wfEscapeWikiText($this->mTitle->getPrefixedText())); } $wgOut->addHTML($this->buildForm()); $this->showLogExtract($wgOut); }
protected function showHistory() { $this->checkReadOnly(); $out = $this->getOutput(); if ($this->mAllowed) { $out->addModules('mediawiki.special.undelete'); } $out->wrapWikiMsg("<div class='mw-undelete-pagetitle'>\n\$1\n</div>\n", array('undeletepagetitle', wfEscapeWikiText($this->mTargetObj->getPrefixedText()))); $archive = new PageArchive($this->mTargetObj, $this->getConfig()); Hooks::run('UndeleteForm::showHistory', array(&$archive, $this->mTargetObj)); /* $text = $archive->getLastRevisionText(); if( is_null( $text ) ) { $out->addWikiMsg( 'nohistory' ); return; } */ $out->addHTML('<div class="mw-undelete-history">'); if ($this->mAllowed) { $out->addWikiMsg('undeletehistory'); $out->addWikiMsg('undeleterevdel'); } else { $out->addWikiMsg('undeletehistorynoadmin'); } $out->addHTML('</div>'); # List all stored revisions $revisions = $archive->listRevisions(); $files = $archive->listFiles(); $haveRevisions = $revisions && $revisions->numRows() > 0; $haveFiles = $files && $files->numRows() > 0; # Batch existence check on user and talk pages if ($haveRevisions) { $batch = new LinkBatch(); foreach ($revisions as $row) { $batch->addObj(Title::makeTitleSafe(NS_USER, $row->ar_user_text)); $batch->addObj(Title::makeTitleSafe(NS_USER_TALK, $row->ar_user_text)); } $batch->execute(); $revisions->seek(0); } if ($haveFiles) { $batch = new LinkBatch(); foreach ($files as $row) { $batch->addObj(Title::makeTitleSafe(NS_USER, $row->fa_user_text)); $batch->addObj(Title::makeTitleSafe(NS_USER_TALK, $row->fa_user_text)); } $batch->execute(); $files->seek(0); } if ($this->mAllowed) { $action = $this->getPageTitle()->getLocalURL(array('action' => 'submit')); # Start the form here $top = Xml::openElement('form', array('method' => 'post', 'action' => $action, 'id' => 'undelete')); $out->addHTML($top); } # Show relevant lines from the deletion log: $deleteLogPage = new LogPage('delete'); $out->addHTML(Xml::element('h2', null, $deleteLogPage->getName()->text()) . "\n"); LogEventsList::showLogExtract($out, 'delete', $this->mTargetObj); # Show relevant lines from the suppression log: $suppressLogPage = new LogPage('suppress'); if ($this->getUser()->isAllowed('suppressionlog')) { $out->addHTML(Xml::element('h2', null, $suppressLogPage->getName()->text()) . "\n"); LogEventsList::showLogExtract($out, 'suppress', $this->mTargetObj); } if ($this->mAllowed && ($haveRevisions || $haveFiles)) { # Format the user-visible controls (comment field, submission button) # in a nice little table if ($this->getUser()->isAllowed('suppressrevision')) { $unsuppressBox = "<tr>\n\t\t\t\t\t\t<td> </td>\n\t\t\t\t\t\t<td class='mw-input'>" . Xml::checkLabel($this->msg('revdelete-unsuppress')->text(), 'wpUnsuppress', 'mw-undelete-unsuppress', $this->mUnsuppress) . "</td>\n\t\t\t\t\t</tr>"; } else { $unsuppressBox = ''; } $table = Xml::fieldset($this->msg('undelete-fieldset-title')->text()) . Xml::openElement('table', array('id' => 'mw-undelete-table')) . "<tr>\n\t\t\t\t\t<td colspan='2' class='mw-undelete-extrahelp'>" . $this->msg('undeleteextrahelp')->parseAsBlock() . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td class='mw-label'>" . Xml::label($this->msg('undeletecomment')->text(), 'wpComment') . "</td>\n\t\t\t\t<td class='mw-input'>" . Xml::input('wpComment', 50, $this->mComment, array('id' => 'wpComment', 'autofocus' => '')) . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td> </td>\n\t\t\t\t<td class='mw-submit'>" . Xml::submitButton($this->msg('undeletebtn')->text(), array('name' => 'restore', 'id' => 'mw-undelete-submit')) . ' ' . Xml::submitButton($this->msg('undeleteinvert')->text(), array('name' => 'invert', 'id' => 'mw-undelete-invert')) . "</td>\n\t\t\t</tr>" . $unsuppressBox . Xml::closeElement('table') . Xml::closeElement('fieldset'); $out->addHTML($table); } $out->addHTML(Xml::element('h2', null, $this->msg('history')->text()) . "\n"); if ($haveRevisions) { # The page's stored (deleted) history: $out->addHTML('<ul>'); $remaining = $revisions->numRows(); $earliestLiveTime = $this->mTargetObj->getEarliestRevTime(); foreach ($revisions as $row) { $remaining--; $out->addHTML($this->formatRevisionRow($row, $earliestLiveTime, $remaining)); } $revisions->free(); $out->addHTML('</ul>'); } else { $out->addWikiMsg('nohistory'); } if ($haveFiles) { $out->addHTML(Xml::element('h2', null, $this->msg('filehist')->text()) . "\n"); $out->addHTML('<ul>'); foreach ($files as $row) { $out->addHTML($this->formatFileRow($row)); } $files->free(); $out->addHTML('</ul>'); } if ($this->mAllowed) { # Slip in the hidden controls here $misc = Html::hidden('target', $this->mTarget); $misc .= Html::hidden('wpEditToken', $this->getUser()->getEditToken()); $misc .= Xml::closeElement('form'); $out->addHTML($misc); } return true; }
/** * Perform a deletion and output success or failure messages * @param string $reason * @param bool $suppress */ public function doDelete($reason, $suppress = false) { $error = ''; $context = $this->getContext(); $outputPage = $context->getOutput(); $user = $context->getUser(); $status = $this->mPage->doDeleteArticleReal($reason, $suppress, 0, true, $error, $user); if ($status->isGood()) { $deleted = $this->getTitle()->getPrefixedText(); $outputPage->setPageTitle(wfMessage('actioncomplete')); $outputPage->setRobotPolicy('noindex,nofollow'); $loglink = '[[Special:Log/delete|' . wfMessage('deletionlog')->text() . ']]'; $outputPage->addWikiMsg('deletedtext', wfEscapeWikiText($deleted), $loglink); Hooks::run('ArticleDeleteAfterSuccess', array($this->getTitle(), $outputPage)); $outputPage->returnToMain(false); } else { $outputPage->setPageTitle(wfMessage('cannotdelete-title', $this->getTitle()->getPrefixedText())); if ($error == '') { $outputPage->addWikiText("<div class=\"error mw-error-cannotdelete\">\n" . $status->getWikiText() . "\n</div>"); $deleteLogPage = new LogPage('delete'); $outputPage->addHTML(Xml::element('h2', null, $deleteLogPage->getName()->text())); LogEventsList::showLogExtract($outputPage, 'delete', $this->getTitle()); } else { $outputPage->addHTML($error); } } }
/** * @param Parser $parser * @param string $text The sortkey to use * @param string $uarg Either "noreplace" or "noerror" (in en) * both suppress errors, and noreplace does nothing if * a default sortkey already exists. * @return string */ public static function defaultsort($parser, $text, $uarg = '') { static $magicWords = null; if (is_null($magicWords)) { $magicWords = new MagicWordArray(['defaultsort_noerror', 'defaultsort_noreplace']); } $arg = $magicWords->matchStartToEnd($uarg); $text = trim($text); if (strlen($text) == 0) { return ''; } $old = $parser->getCustomDefaultSort(); if ($old === false || $arg !== 'defaultsort_noreplace') { $parser->setDefaultSort($text); } if ($old === false || $old == $text || $arg) { return ''; } else { $converter = $parser->getConverterLanguage()->getConverter(); return '<span class="error">' . wfMessage('duplicate-defaultsort', $converter->markNoConversion(wfEscapeWikiText($old)), $converter->markNoConversion(wfEscapeWikiText($text)))->inContentLanguage()->text() . '</span>'; } }
/** * Constructor */ function wfSpecialImport($page = '') { global $wgUser, $wgOut, $wgRequest, $wgTitle, $wgImportSources; global $wgImportTargetNamespace; $interwiki = false; $namespace = $wgImportTargetNamespace; $frompage = ''; $history = true; if ($wgRequest->wasPosted() && $wgRequest->getVal('action') == 'submit') { $isUpload = false; $namespace = $wgRequest->getIntOrNull('namespace'); switch ($wgRequest->getVal("source")) { case "upload": $isUpload = true; if ($wgUser->isAllowed('importupload')) { $source = ImportStreamSource::newFromUpload("xmlimport"); } else { return $wgOut->permissionRequired('importupload'); } break; case "interwiki": $interwiki = $wgRequest->getVal('interwiki'); $history = $wgRequest->getCheck('interwikiHistory'); $frompage = $wgRequest->getText("frompage"); $source = ImportStreamSource::newFromInterwiki($interwiki, $frompage, $history); break; default: $source = new WikiErrorMsg("importunknownsource"); } if (WikiError::isError($source)) { $wgOut->addWikiText(wfEscapeWikiText($source->getMessage())); } else { $wgOut->addWikiText(wfMsg("importstart")); $importer = new WikiImporter($source); if (!is_null($namespace)) { $importer->setTargetNamespace($namespace); } $reporter = new ImportReporter($importer, $isUpload, $interwiki); $reporter->open(); $result = $importer->doImport(); $reporter->close(); if (WikiError::isError($result)) { $wgOut->addWikiText(wfMsg("importfailed", wfEscapeWikiText($result->getMessage()))); } else { # Success! $wgOut->addWikiText(wfMsg("importsuccess")); } } } $action = $wgTitle->escapeLocalUrl('action=submit'); if ($wgUser->isAllowed('importupload')) { $wgOut->addWikiText(wfMsg("importtext")); $wgOut->addHTML("\n<fieldset>\n\t<legend>" . wfMsgHtml('upload') . "</legend>\n\t<form enctype='multipart/form-data' method='post' action=\"{$action}\">\n\t\t<input type='hidden' name='action' value='submit' />\n\t\t<input type='hidden' name='source' value='upload' />\n\t\t<input type='hidden' name='MAX_FILE_SIZE' value='2000000' />\n\t\t<input type='file' name='xmlimport' value='' size='30' />\n\t\t<input type='submit' value=\"" . wfMsgHtml("uploadbtn") . "\" />\n\t</form>\n</fieldset>\n"); } else { if (empty($wgImportSources)) { $wgOut->addWikiText(wfMsg('importnosources')); } } if (!empty($wgImportSources)) { $wgOut->addHTML("\n<fieldset>\n\t<legend>" . wfMsgHtml('importinterwiki') . "</legend>\n\t<form method='post' action=\"{$action}\">" . $wgOut->parse(wfMsg('import-interwiki-text')) . "\n\t\t<input type='hidden' name='action' value='submit' />\n\t\t<input type='hidden' name='source' value='interwiki' />\n\t\t<table>\n\t\t\t<tr>\n\t\t\t\t<td>\n\t\t\t\t\t<select name='interwiki'>"); foreach ($wgImportSources as $prefix) { $iw = htmlspecialchars($prefix); $selected = $interwiki === $prefix ? ' selected="selected"' : ''; $wgOut->addHTML("<option value=\"{$iw}\"{$selected}>{$iw}</option>\n"); } $wgOut->addHTML("\n\t\t\t\t\t</select>\n\t\t\t\t</td>\n\t\t\t\t<td>" . wfInput('frompage', 50, $frompage) . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td>" . wfCheckLabel(wfMsg('import-interwiki-history'), 'interwikiHistory', 'interwikiHistory', $history) . "</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td>\n\t\t\t\t\t" . wfMsgHtml('import-interwiki-namespace') . " " . HTMLnamespaceselector($namespace, '') . "\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td></td>\n\t\t\t\t<td>" . wfSubmitButton(wfMsg('import-interwiki-submit')) . "</td>\n\t\t\t</tr>\n\t\t</table>\n\t</form>\n</fieldset>\n"); } }
/** * Show the form to edit group memberships. * * @param $user User or UserRightsProxy you're editing * @param $groups Array: Array of groups the user is in */ protected function showEditUserGroupsForm($user, $groups) { global $wgOut, $wgUser, $wgLang; $list = array(); foreach ($groups as $group) { $list[] = self::buildGroupLink($group); } $grouplist = ''; if (count($list) > 0) { $grouplist = wfMsgHtml('userrights-groupsmember'); $grouplist = '<p>' . $grouplist . ' ' . $wgLang->listToText($list) . '</p>'; } $wgOut->addHTML(Xml::openElement('form', array('method' => 'post', 'action' => $this->getTitle()->getLocalURL(), 'name' => 'editGroup', 'id' => 'mw-userrights-form2')) . Xml::hidden('user', $this->mTarget) . Xml::hidden('wpEditToken', $wgUser->editToken($this->mTarget)) . Xml::openElement('fieldset') . Xml::element('legend', array(), wfMsg('userrights-editusergroup')) . wfMsgExt('editinguser', array('parse'), wfEscapeWikiText($user->getName())) . wfMsgExt('userrights-groups-help', array('parse')) . $grouplist . Xml::tags('p', null, $this->groupCheckboxes($groups)) . Xml::openElement('table', array('border' => '0', 'id' => 'mw-userrights-table-outer')) . "<tr>\n\t\t\t\t\t<td class='mw-label'>" . Xml::label(wfMsg('userrights-reason'), 'wpReason') . "</td>\n\t\t\t\t\t<td class='mw-input'>" . Xml::input('user-reason', 60, false, array('id' => 'wpReason', 'maxlength' => 255)) . "</td>\n\t\t\t\t</tr>\n\t\t\t\t<tr>\n\t\t\t\t\t<td></td>\n\t\t\t\t\t<td class='mw-submit'>" . Xml::submitButton(wfMsg('saveusergroups'), array('name' => 'saveusergroups', 'accesskey' => 's')) . "</td>\n\t\t\t\t</tr>" . Xml::closeElement('table') . "\n" . Xml::closeElement('fieldset') . Xml::closeElement('form') . "\n"); }
/** * This is used to generate an array element for each metadata value * That array is then used to generate the table of metadata values * on the image page * * @param array &$array An array containing elements for each type of visibility * and each of those elements being an array of metadata items. This function adds * a value to that array. * @param string $visibility ('visible' or 'collapsed') if this value is hidden * by default. * @param string $type Type of metadata tag (currently always 'exif') * @param string $id The name of the metadata tag (like 'artist' for example). * its name in the table displayed is the message "$type-$id" (Ex exif-artist ). * @param string $value Thingy goes into a wikitext table; it used to be escaped but * that was incompatible with previous practise of customized display * with wikitext formatting via messages such as 'exif-model-value'. * So the escaping is taken back out, but generally this seems a confusing * interface. * @param bool|string $param Value to pass to the message for the name of the field * as $1. Currently this parameter doesn't seem to ever be used. * * Note, everything here is passed through the parser later on (!) */ protected static function addMeta(&$array, $visibility, $type, $id, $value, $param = false) { $msg = wfMessage("{$type}-{$id}", $param); if ($msg->exists()) { $name = $msg->text(); } else { // This is for future compatibility when using instant commons. // So as to not display as ugly a name if a new metadata // property is defined that we don't know about // (not a major issue since such a property would be collapsed // by default). wfDebug(__METHOD__ . ' Unknown metadata name: ' . $id . "\n"); $name = wfEscapeWikiText($id); } $array[$visibility][] = ['id' => "{$type}-{$id}", 'name' => $name, 'value' => $value]; }
/** * Create a new child frame * $args is optionally a multi-root PPNode or array containing the template arguments * * @param bool|array $args * @param Title|bool $title * @param int $indexOffset * @return PPTemplateFrame_DOM */ public function newChild($args = false, $title = false, $indexOffset = 0) { $namedArgs = array(); $numberedArgs = array(); if ($title === false) { $title = $this->title; } if ($args !== false) { $xpath = false; if ($args instanceof PPNode) { $args = $args->node; } foreach ($args as $arg) { if ($arg instanceof PPNode) { $arg = $arg->node; } if (!$xpath || $xpath->document !== $arg->ownerDocument) { $xpath = new DOMXPath($arg->ownerDocument); } $nameNodes = $xpath->query('name', $arg); $value = $xpath->query('value', $arg); if ($nameNodes->item(0)->hasAttributes()) { // Numbered parameter $index = $nameNodes->item(0)->attributes->getNamedItem('index')->textContent; $index = $index - $indexOffset; if (isset($namedArgs[$index]) || isset($numberedArgs[$index])) { $this->parser->getOutput()->addWarning(wfMessage('duplicate-args-warning', wfEscapeWikiText($this->title), wfEscapeWikiText($title), wfEscapeWikiText($index))->text()); $this->parser->addTrackingCategory('duplicate-args-category'); } $numberedArgs[$index] = $value->item(0); unset($namedArgs[$index]); } else { // Named parameter $name = trim($this->expand($nameNodes->item(0), PPFrame::STRIP_COMMENTS)); if (isset($namedArgs[$name]) || isset($numberedArgs[$name])) { $this->parser->getOutput()->addWarning(wfMessage('duplicate-args-warning', wfEscapeWikiText($this->title), wfEscapeWikiText($title), wfEscapeWikiText($name))->text()); $this->parser->addTrackingCategory('duplicate-args-category'); } $namedArgs[$name] = $value->item(0); unset($numberedArgs[$name]); } } } return new PPTemplateFrame_DOM($this->preprocessor, $this, $numberedArgs, $namedArgs, $title); }
/** * Back-end article deletion * Deletes the article with database consistency, writes logs, purges caches * * @since 1.19 * * @param string $reason delete reason for deletion log * @param $suppress boolean suppress all revisions and log the deletion in * the suppression log instead of the deletion log * @param int $id article ID * @param $commit boolean defaults to true, triggers transaction end * @param &$error Array of errors to append to * @param $user User The deleting user * @return Status: Status object; if successful, $status->value is the log_id of the * deletion log entry. If the page couldn't be deleted because it wasn't * found, $status is a non-fatal 'cannotdelete' error */ public function doDeleteArticleReal( $reason, $suppress = false, $id = 0, $commit = true, &$error = '', User $user = null ) { global $wgUser, $wgContentHandlerUseDB; wfDebug( __METHOD__ . "\n" ); $status = Status::newGood(); if ( $this->mTitle->getDBkey() === '' ) { $status->error( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) ); return $status; } $user = is_null( $user ) ? $wgUser : $user; if ( ! wfRunHooks( 'ArticleDelete', array( &$this, &$user, &$reason, &$error, &$status ) ) ) { if ( $status->isOK() ) { // Hook aborted but didn't set a fatal status $status->fatal( 'delete-hook-aborted' ); } return $status; } if ( $id == 0 ) { $this->loadPageData( 'forupdate' ); $id = $this->getID(); if ( $id == 0 ) { $status->error( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) ); return $status; } } // Bitfields to further suppress the content if ( $suppress ) { $bitfield = 0; // This should be 15... $bitfield |= Revision::DELETED_TEXT; $bitfield |= Revision::DELETED_COMMENT; $bitfield |= Revision::DELETED_USER; $bitfield |= Revision::DELETED_RESTRICTED; } else { $bitfield = 'rev_deleted'; } // we need to remember the old content so we can use it to generate all deletion updates. $content = $this->getContent( Revision::RAW ); $dbw = wfGetDB( DB_MASTER ); $dbw->begin( __METHOD__ ); // For now, shunt the revision data into the archive table. // Text is *not* removed from the text table; bulk storage // is left intact to avoid breaking block-compression or // immutable storage schemes. // // For backwards compatibility, note that some older archive // table entries will have ar_text and ar_flags fields still. // // In the future, we may keep revisions and mark them with // the rev_deleted field, which is reserved for this purpose. $row = array( 'ar_namespace' => 'page_namespace', 'ar_title' => 'page_title', 'ar_comment' => 'rev_comment', 'ar_user' => 'rev_user', 'ar_user_text' => 'rev_user_text', 'ar_timestamp' => 'rev_timestamp', 'ar_minor_edit' => 'rev_minor_edit', 'ar_rev_id' => 'rev_id', 'ar_parent_id' => 'rev_parent_id', 'ar_text_id' => 'rev_text_id', 'ar_text' => '\'\'', // Be explicit to appease 'ar_flags' => '\'\'', // MySQL's "strict mode"... 'ar_len' => 'rev_len', 'ar_page_id' => 'page_id', 'ar_deleted' => $bitfield, 'ar_sha1' => 'rev_sha1', ); if ( $wgContentHandlerUseDB ) { $row['ar_content_model'] = 'rev_content_model'; $row['ar_content_format'] = 'rev_content_format'; } $dbw->insertSelect( 'archive', array( 'page', 'revision' ), $row, array( 'page_id' => $id, 'page_id = rev_page' ), __METHOD__ ); // Now that it's safely backed up, delete it $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__ ); $ok = ( $dbw->affectedRows() > 0 ); // $id could be laggy if ( !$ok ) { $dbw->rollback( __METHOD__ ); $status->error( 'cannotdelete', wfEscapeWikiText( $this->getTitle()->getPrefixedText() ) ); return $status; } if ( !$dbw->cascadingDeletes() ) { $dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ ); } $this->doDeleteUpdates( $id, $content ); // Log the deletion, if the page was suppressed, log it at Oversight instead $logtype = $suppress ? 'suppress' : 'delete'; $logEntry = new ManualLogEntry( $logtype, 'delete' ); $logEntry->setPerformer( $user ); $logEntry->setTarget( $this->mTitle ); $logEntry->setComment( $reason ); $logid = $logEntry->insert(); $logEntry->publish( $logid ); if ( $commit ) { $dbw->commit( __METHOD__ ); } wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$user, $reason, $id, $content, $logEntry ) ); $status->value = $logid; return $status; }
/** * Back-end article deletion * Deletes the article with database consistency, writes logs, purges caches * * @since 1.19 * * @param string $reason Delete reason for deletion log * @param bool $suppress Suppress all revisions and log the deletion in * the suppression log instead of the deletion log * @param int $u1 Unused * @param bool $u2 Unused * @param array|string &$error Array of errors to append to * @param User $user The deleting user * @param array $tags Tags to apply to the deletion action * @return Status Status object; if successful, $status->value is the log_id of the * deletion log entry. If the page couldn't be deleted because it wasn't * found, $status is a non-fatal 'cannotdelete' error */ public function doDeleteArticleReal($reason, $suppress = false, $u1 = null, $u2 = null, &$error = '', User $user = null, $tags = []) { global $wgUser, $wgContentHandlerUseDB; wfDebug(__METHOD__ . "\n"); $status = Status::newGood(); if ($this->mTitle->getDBkey() === '') { $status->error('cannotdelete', wfEscapeWikiText($this->getTitle()->getPrefixedText())); return $status; } $user = is_null($user) ? $wgUser : $user; if (!Hooks::run('ArticleDelete', [&$this, &$user, &$reason, &$error, &$status, $suppress])) { if ($status->isOK()) { // Hook aborted but didn't set a fatal status $status->fatal('delete-hook-aborted'); } return $status; } $dbw = wfGetDB(DB_MASTER); $dbw->startAtomic(__METHOD__); $this->loadPageData(self::READ_LATEST); $id = $this->getId(); // T98706: lock the page from various other updates but avoid using // WikiPage::READ_LOCKING as that will carry over the FOR UPDATE to // the revisions queries (which also JOIN on user). Only lock the page // row and CAS check on page_latest to see if the trx snapshot matches. $lockedLatest = $this->lockAndGetLatest(); if ($id == 0 || $this->getLatest() != $lockedLatest) { $dbw->endAtomic(__METHOD__); // Page not there or trx snapshot is stale $status->error('cannotdelete', wfEscapeWikiText($this->getTitle()->getPrefixedText())); return $status; } // Given the lock above, we can be confident in the title and page ID values $namespace = $this->getTitle()->getNamespace(); $dbKey = $this->getTitle()->getDBkey(); // At this point we are now comitted to returning an OK // status unless some DB query error or other exception comes up. // This way callers don't have to call rollback() if $status is bad // unless they actually try to catch exceptions (which is rare). // we need to remember the old content so we can use it to generate all deletion updates. $revision = $this->getRevision(); try { $content = $this->getContent(Revision::RAW); } catch (Exception $ex) { wfLogWarning(__METHOD__ . ': failed to load content during deletion! ' . $ex->getMessage()); $content = null; } $fields = Revision::selectFields(); $bitfield = false; // Bitfields to further suppress the content if ($suppress) { $bitfield = Revision::SUPPRESSED_ALL; $fields = array_diff($fields, ['rev_deleted']); } // For now, shunt the revision data into the archive table. // Text is *not* removed from the text table; bulk storage // is left intact to avoid breaking block-compression or // immutable storage schemes. // In the future, we may keep revisions and mark them with // the rev_deleted field, which is reserved for this purpose. // Get all of the page revisions $res = $dbw->select('revision', $fields, ['rev_page' => $id], __METHOD__, 'FOR UPDATE'); // Build their equivalent archive rows $rowsInsert = []; foreach ($res as $row) { $rowInsert = ['ar_namespace' => $namespace, 'ar_title' => $dbKey, 'ar_comment' => $row->rev_comment, 'ar_user' => $row->rev_user, 'ar_user_text' => $row->rev_user_text, 'ar_timestamp' => $row->rev_timestamp, 'ar_minor_edit' => $row->rev_minor_edit, 'ar_rev_id' => $row->rev_id, 'ar_parent_id' => $row->rev_parent_id, 'ar_text_id' => $row->rev_text_id, 'ar_text' => '', 'ar_flags' => '', 'ar_len' => $row->rev_len, 'ar_page_id' => $id, 'ar_deleted' => $suppress ? $bitfield : $row->rev_deleted, 'ar_sha1' => $row->rev_sha1]; if ($wgContentHandlerUseDB) { $rowInsert['ar_content_model'] = $row->rev_content_model; $rowInsert['ar_content_format'] = $row->rev_content_format; } $rowsInsert[] = $rowInsert; } // Copy them into the archive table $dbw->insert('archive', $rowsInsert, __METHOD__); // Save this so we can pass it to the ArticleDeleteComplete hook. $archivedRevisionCount = $dbw->affectedRows(); // Clone the title and wikiPage, so we have the information we need when // we log and run the ArticleDeleteComplete hook. $logTitle = clone $this->mTitle; $wikiPageBeforeDelete = clone $this; // Now that it's safely backed up, delete it $dbw->delete('page', ['page_id' => $id], __METHOD__); $dbw->delete('revision', ['rev_page' => $id], __METHOD__); // Log the deletion, if the page was suppressed, put it in the suppression log instead $logtype = $suppress ? 'suppress' : 'delete'; $logEntry = new ManualLogEntry($logtype, 'delete'); $logEntry->setPerformer($user); $logEntry->setTarget($logTitle); $logEntry->setComment($reason); $logEntry->setTags($tags); $logid = $logEntry->insert(); $dbw->onTransactionPreCommitOrIdle(function () use($dbw, $logEntry, $logid) { // Bug 56776: avoid deadlocks (especially from FileDeleteForm) $logEntry->publish($logid); }, __METHOD__); $dbw->endAtomic(__METHOD__); $this->doDeleteUpdates($id, $content, $revision); Hooks::run('ArticleDeleteComplete', [&$wikiPageBeforeDelete, &$user, $reason, $id, $content, $logEntry, $archivedRevisionCount]); $status->value = $logid; // Show log excerpt on 404 pages rather than just a link $cache = ObjectCache::getMainStashInstance(); $key = wfMemcKey('page-recent-delete', md5($logTitle->getPrefixedText())); $cache->set($key, 1, $cache::TTL_DAY); return $status; }
/** * @return string */ function getImageSection() { $r = ''; $rescnt = $this->showGallery ? $this->gallery->count() : count($this->imgsNoGallery); if ($rescnt > 0) { $dbcnt = $this->cat->getFileCount(); $countmsg = $this->getCountMessage($rescnt, $dbcnt, 'file'); $r .= "<div id=\"mw-category-media\">\n"; $r .= '<h2>' . $this->msg('category-media-header', wfEscapeWikiText($this->title->getText()))->text() . "</h2>\n"; $r .= $countmsg; $r .= $this->getSectionPagingLinks('file'); if ($this->showGallery) { $r .= $this->gallery->toHTML(); } else { $r .= $this->formatList($this->imgsNoGallery, $this->imgsNoGallery_start_char); } $r .= $this->getSectionPagingLinks('file'); $r .= "\n</div>"; } return $r; }
/** * Fetch the user's signature text, if any, and normalize to * validated, ready-to-insert wikitext. * If you have pre-fetched the nickname or the fancySig option, you can * specify them here to save a database query. * Do not reuse this parser instance after calling getUserSig(), * as it may have changed if it's the $wgParser. * * @param $user User * @param string|bool $nickname nickname to use or false to use user's default nickname * @param $fancySig Boolean|null whether the nicknname is the complete signature * or null to use default value * @return string */ function getUserSig(&$user, $nickname = false, $fancySig = null) { global $wgMaxSigChars; $username = $user->getName(); # If not given, retrieve from the user object. if ($nickname === false) { $nickname = $user->getOption('nickname'); } if (is_null($fancySig)) { $fancySig = $user->getBoolOption('fancysig'); } $nickname = $nickname == null ? $username : $nickname; if (mb_strlen($nickname) > $wgMaxSigChars) { $nickname = $username; wfDebug(__METHOD__ . ": {$username} has overlong signature.\n"); } elseif ($fancySig !== false) { # Sig. might contain markup; validate this if ($this->validateSig($nickname) !== false) { # Validated; clean up (if needed) and return it return $this->cleanSig($nickname, true); } else { # Failed to validate; fall back to the default $nickname = $username; wfDebug(__METHOD__ . ": {$username} has bad XML tags in signature.\n"); } } # Make sure nickname doesnt get a sig in a sig $nickname = self::cleanSigInSig($nickname); # If we're still here, make it a link to the user page $userText = wfEscapeWikiText($username); $nickText = wfEscapeWikiText($nickname); $msgName = $user->isAnon() ? 'signature-anon' : 'signature'; return wfMessage($msgName, $userText, $nickText)->inContentLanguage()->title($this->getTitle())->text(); }