public function execute() { global $wgUser, $wgArticleFeedbackRatingTypes, $wgArticleFeedbackSMaxage, $wgArticleFeedbackNamespaces; $params = $this->extractRequestParams(); // Anon token check if ($wgUser->isAnon()) { if (!isset($params['anontoken'])) { $this->dieUsageMsg(array('missingparam', 'anontoken')); } elseif (strlen($params['anontoken']) != 32) { $this->dieUsage('The anontoken is not 32 characters', 'invalidtoken'); } $token = $params['anontoken']; } else { $token = ''; } // Load check, is this page ArticleFeedback-enabled ? // Keep in sync with ext.articleFeedback.startup.js $title = Title::newFromID($params['pageid']); if (is_null($title) || !in_array($title->getNamespace(), $wgArticleFeedbackNamespaces) || $title->isRedirect()) { // ...then error out $this->dieUsage('ArticleFeedback is not enabled on this page', 'invalidpage'); } $dbw = wfGetDB(DB_MASTER); // Query the latest ratings by this user for this page, // possibly for an older revision // Select from the master to prevent replag-induced bugs $res = $dbw->select('article_feedback', array('aa_rating_id', 'aa_rating_value', 'aa_revision'), array('aa_user_text' => $wgUser->getName(), 'aa_page_id' => $params['pageid'], 'aa_rating_id' => array_keys($wgArticleFeedbackRatingTypes), 'aa_user_anon_token' => $token), __METHOD__, array('ORDER BY' => 'aa_revision DESC', 'LIMIT' => count($wgArticleFeedbackRatingTypes))); $lastRatings = array(); foreach ($res as $row) { $lastRatings[$row->aa_rating_id]['value'] = $row->aa_rating_value; $lastRatings[$row->aa_rating_id]['revision'] = $row->aa_revision; } $pageId = $params['pageid']; $revisionId = $params['revid']; foreach ($wgArticleFeedbackRatingTypes as $ratingID => $unused) { $lastPageRating = false; $lastRevRating = false; if (isset($lastRatings[$ratingID])) { $lastPageRating = intval($lastRatings[$ratingID]['value']); if (intval($lastRatings[$ratingID]['revision']) == $revisionId) { $lastRevRating = $lastPageRating; } } $thisRating = false; if (isset($params["r{$ratingID}"])) { $thisRating = intval($params["r{$ratingID}"]); } $this->insertRevisionRating($pageId, $revisionId, $ratingID, $thisRating - $lastRevRating, $thisRating, $lastRevRating); $this->insertPageRating($pageId, $ratingID, $thisRating - $lastPageRating, $thisRating, $lastPageRating); $this->insertUserRatings($pageId, $revisionId, $wgUser, $token, $ratingID, $thisRating, $params['bucket']); } $this->insertProperties($revisionId, $wgUser, $token, $params); $squidUpdate = new SquidUpdate(array(wfAppendQuery(wfScript('api'), array('action' => 'query', 'format' => 'json', 'list' => 'articlefeedback', 'afpageid' => $pageId, 'afanontoken' => '', 'afuserrating' => 0, 'maxage' => 0, 'smaxage' => $wgArticleFeedbackSMaxage)))); $squidUpdate->doUpdate(); wfRunHooks('ArticleFeedbackChangeRating', array($params)); $r = array('result' => 'Success'); $this->getResult()->addValue(null, $this->getModuleName(), $r); }
public function performUploadInit($comment, $pageText, $watch, $user) { $check = $this->mUpload->validateNameAndOverwrite(); if ($check !== true) { $this->getVerificationError($check); } $session = $this->mUpload->setupChunkSession($comment, $pageText, $watch); return array('uploadUrl' => wfExpandUrl(wfScript('api')) . "?" . wfArrayToCGI(array('action' => 'firefoggupload', 'token' => $user->editToken(), 'format' => 'json', 'chunksession' => $session, 'filename' => $this->mUpload->getDesiredName()))); }
/** @brief Fetch the edit form and return the text in #wpTextbox1. @param title The page to be opened for editing. */ public function getPreloadedText($title) { $url = wfAppendQuery(wfScript('index'), array('title' => $title, 'action' => 'edit')); $this->loadFromURL($url); $elem = $this->getElementById('wpTextbox1'); if (!$elem) { return null; } return trim($elem->textContent); }
protected function setUp() { global $wgServer; parent::setUp(); self::$apiUrl = $wgServer . wfScript('api'); ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session self::$users = array('sysop' => new TestUser('Apitestsysop', 'Api Test Sysop', '*****@*****.**', array('sysop')), 'uploader' => new TestUser('Apitestuser', 'Api Test User', '*****@*****.**', array())); $this->setMwGlobals(array('wgAuth' => new StubObject('wgAuth', 'AuthPlugin'), 'wgRequest' => new FauxRequest(array()), 'wgUser' => self::$users['sysop']->user)); $this->apiContext = new ApiTestContext(); }
protected function setUp() { global $wgServer, $wgDisableAuthManager; parent::setUp(); self::$apiUrl = $wgServer . wfScript('api'); ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session self::$users = ['sysop' => static::getTestSysop(), 'uploader' => static::getTestUser()]; $this->setMwGlobals(['wgAuth' => $wgDisableAuthManager ? new AuthPlugin() : new MediaWiki\Auth\AuthManagerAuthPlugin(), 'wgRequest' => new FauxRequest([]), 'wgUser' => self::$users['sysop']->user]); $this->apiContext = new ApiTestContext(); }
function setUp() { global $wgContLang, $wgAuth, $wgMemc, $wgRequest, $wgUser, $wgServer; parent::setUp(); self::$apiUrl = $wgServer . wfScript('api'); $wgMemc = new EmptyBagOStuff(); $wgContLang = Language::factory('en'); $wgAuth = new StubObject('wgAuth', 'AuthPlugin'); $wgRequest = new FauxRequest(array()); self::$users = array('sysop' => new ApiTestUser('Apitestsysop', 'Api Test Sysop', '*****@*****.**', array('sysop')), 'uploader' => new ApiTestUser('Apitestuser', 'Api Test User', '*****@*****.**', array())); $wgUser = self::$users['sysop']->user; }
function execute($par) { $mime = $par ? $par : $this->getRequest()->getText('mime'); $mime = trim($mime); $this->setHeaders(); $this->outputHeader(); $this->getOutput()->addHTML(Xml::openElement('form', array('id' => 'specialmimesearch', 'method' => 'get', 'action' => wfScript())) . Xml::openElement('fieldset') . Html::hidden('title', $this->getPageTitle()->getPrefixedText()) . Xml::element('legend', null, $this->msg('mimesearch')->text()) . Xml::inputLabel($this->msg('mimetype')->text(), 'mime', 'mime', 20, $mime) . ' ' . Xml::submitButton($this->msg('ilsubmit')->text()) . Xml::closeElement('fieldset') . Xml::closeElement('form')); list($this->major, $this->minor) = File::splitMime($mime); if ($this->major == '' || $this->minor == '' || $this->minor == 'unknown' || !self::isValidType($this->major)) { return; } parent::execute($par); }
public function performUploadInit($comment, $pageText, $watchlist, $user) { // Verify the initial upload request $this->verifyUploadInit(); $session = $this->mUpload->setupChunkSession( $comment, $pageText, $watchlist ); return array('uploadUrl' => wfExpandUrl( wfScript( 'api' ) ) . "?" . wfArrayToCGI( array( 'action' => 'resumableupload', 'token' => $user->editToken(), 'format' => 'json', 'chunksession' => $session, 'filename' => $this->mUpload->getDesiredName(), ) ) ); }
protected function setUp() { global $wgContLang, $wgAuth, $wgMemc, $wgRequest, $wgUser, $wgServer; parent::setUp(); self::$apiUrl = $wgServer . wfScript('api'); $wgMemc = new EmptyBagOStuff(); $wgContLang = Language::factory('en'); $wgAuth = new StubObject('wgAuth', 'AuthPlugin'); $wgRequest = new FauxRequest(array()); ApiQueryInfo::resetTokenCache(); // tokens are invalid because we cleared the session self::$users = array('sysop' => new TestUser('Apitestsysop', 'Api Test Sysop', '*****@*****.**', array('sysop')), 'uploader' => new TestUser('Apitestuser', 'Api Test User', '*****@*****.**', array())); $wgUser = self::$users['sysop']->user; $this->apiContext = new ApiTestContext(); }
/** * Registers core modules and runs registration hooks. */ public function __construct() { global $IP, $wgResourceModules, $wgResourceLoaderSources, $wgLoadScript, $wgEnableJavaScriptTest; wfProfileIn(__METHOD__); // Add 'local' source first $this->addSource('local', array('loadScript' => $wgLoadScript, 'apiScript' => wfScript('api'))); // Add other sources $this->addSource($wgResourceLoaderSources); // Register modules shared between mwEmbed and mediaWiki: $this->register(include "{$IP}/resources/MwEmbedSharedResources.php"); // Register extension modules wfRunHooks('ResourceLoaderRegisterModules', array(&$this)); $this->register($wgResourceModules); if ($wgEnableJavaScriptTest === true) { $this->registerTestModules(); } wfProfileOut(__METHOD__); }
/** * Initialize the printer function and prepares the output headers, etc. * This method must be the first outputing method during execution. * A help screen's header is printed for the HTML-based output */ function initPrinter($isError) { $isHtml = $this->getIsHtml(); $mime = $isHtml ? 'text/html' : $this->getMimeType(); $script = wfScript('api'); // Some printers (ex. Feed) do their own header settings, // in which case $mime will be set to null if (is_null($mime)) { return; } // skip any initialization header("Content-Type: {$mime}; charset=utf-8"); if ($isHtml) { ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>MediaWiki API</title> </head> <body> <?php if (!$isError) { ?> <br/> <small> You are looking at the HTML representation of the <?php echo $this->mFormat; ?> format.<br/> HTML is good for debugging, but probably is not suitable for your application.<br/> See <a href='http://www.mediawiki.org/wiki/API'>complete documentation</a>, or <a href='<?php echo $script; ?> '>API help</a> for more information. </small> <?php } ?> <pre> <?php } }
public function execute($par) { $redirect = $this->getRedirect($par); $query = $this->getRedirectQuery(); // Redirect to a page title with possible query parameters if ($redirect instanceof Title) { $url = $redirect->getFullURL($query); $this->getOutput()->redirect($url); return $redirect; } elseif ($redirect === true) { // Redirect to index.php with query parameters $url = wfAppendQuery(wfScript('index'), $query); $this->getOutput()->redirect($url); return $redirect; } else { $class = get_class($this); throw new MWException("RedirectSpecialPage {$class} doesn't redirect!"); } }
/** * Main execution point * * @param string $subpage */ public function execute($subpage) { // Backwards-compatibility: redirect to new feed URLs $feedFormat = $this->getRequest()->getVal('feed'); if (!$this->including() && $feedFormat) { $query = $this->getFeedQuery(); $query['feedformat'] = $feedFormat === 'atom' ? 'atom' : 'rss'; $this->getOutput()->redirect(wfAppendQuery(wfScript('api'), $query)); return; } // 10 seconds server-side caching max $this->getOutput()->setSquidMaxage(10); // Check if the client has a cached version $lastmod = $this->checkLastModified(); if ($lastmod === false) { return; } parent::execute($subpage); }
/** * Get a webservice handler. * * @see $wgTranslateTranslationServices * @param string $name Name of the service. * @param array $config * @return TranslationWebService|null */ public static function factory($name, $config) { $handlers = array('microsoft' => 'MicrosoftWebService', 'apertium' => 'ApertiumWebService', 'yandex' => 'YandexWebService', 'remote-ttmserver' => 'RemoteTTMServerWebService', 'cxserver' => 'CxserverWebService', 'youdao' => 'YoudaoWebService'); if (!isset($config['timeout'])) { $config['timeout'] = 3; } // Alter local ttmserver instance to appear as remote // to take advantage of the query aggregator. But only // if they are public. if (isset($config['class']) && $config['class'] === 'ElasticSearchTTMServer' && isset($config['public']) && $config['public'] === true) { $config['type'] = 'remote-ttmserver'; $config['service'] = $name; $config['url'] = wfExpandURl(wfScript('api'), PROTO_CANONICAL); } if (isset($handlers[$config['type']])) { $class = $handlers[$config['type']]; return new $class($name, $config); } return null; }
function wfSpecialFavoritelist($par) { global $wgUser, $wgOut, $wgLang, $wgRequest; global $wgRCShowFavoritingUsers, $wgEnotifFavoritelist, $wgShowUpdatedMarker; // Add feed links $flToken = $wgUser->getOption('favoritelisttoken'); if (!$flToken) { $flToken = sha1(mt_rand() . microtime(true)); $wgUser->setOption('favoritelisttoken', $flToken); $wgUser->saveSettings(); } global $wgServer, $wgScriptPath, $wgFeedClasses; $apiParams = array('action' => 'feedfavoritelist', 'allrev' => 'allrev', 'flowner' => $wgUser->getName(), 'fltoken' => $flToken); $feedTemplate = wfScript('api') . '?'; foreach ($wgFeedClasses as $format => $class) { $theseParams = $apiParams + array('feedformat' => $format); $url = $feedTemplate . wfArrayToCGI($theseParams); $wgOut->addFeedLink($format, $url); } $skin = $wgUser->getSkin(); $specialTitle = SpecialPage::getTitleFor('Favoritelist'); $wgOut->setRobotPolicy('noindex,nofollow'); # Anons don't get a favoritelist if ($wgUser->isAnon()) { $wgOut->setPageTitle(wfMsg('favoritenologin')); $llink = $skin->linkKnown(SpecialPage::getTitleFor('Userlogin'), wfMsgHtml('loginreqlink'), array(), array('returnto' => $specialTitle->getPrefixedText())); $wgOut->addHTML(wfMsgWikiHtml('favoritelistanontext', $llink)); return; } $wgOut->setPageTitle(wfMsg('favoritelist')); $sub = wfMsgExt('favoritelistfor', 'parseinline', $wgUser->getName()); $sub .= '<br />' . FavoritelistEditor::buildTools($wgUser->getSkin()); $wgOut->setSubtitle($sub); if (($mode = FavoritelistEditor::getMode($wgRequest, $par)) !== false) { $editor = new FavoritelistEditor(); $editor->execute($wgUser, $wgOut, $wgRequest, $mode); return; } $this->viewFavList($wgUser, $wgOut, $wgRequest, $mode); }
public function execute($par) { if (empty($par)) { $par = 'main'; } // These come from transclusions $request = $this->getRequest(); $options = ['action' => 'help', 'nolead' => true, 'submodules' => $request->getCheck('submodules'), 'recursivesubmodules' => $request->getCheck('recursivesubmodules'), 'title' => $request->getVal('title', $this->getPageTitle('$1')->getPrefixedText())]; // These are for linking from wikitext, since url parameters are a pain // to do. while (true) { if (substr($par, 0, 4) === 'sub/') { $par = substr($par, 4); $options['submodules'] = 1; continue; } if (substr($par, 0, 5) === 'rsub/') { $par = substr($par, 5); $options['recursivesubmodules'] = 1; continue; } $moduleName = $par; break; } if (!$this->including()) { unset($options['nolead'], $options['title']); $options['modules'] = $moduleName; $link = wfAppendQuery(wfExpandUrl(wfScript('api'), PROTO_CURRENT), $options); $this->getOutput()->redirect($link); return; } $main = new ApiMain($this->getContext(), false); try { $module = $main->getModuleFromPath($moduleName); } catch (UsageException $ex) { $this->getOutput()->addHTML(Html::rawElement('span', ['class' => 'error'], $this->msg('apihelp-no-such-module', $moduleName)->inContentLanguage()->parse())); return; } ApiHelp::getHelp($this->getContext(), $module, $options); }
public function getHTML() { $searchField = htmlspecialchars($this->data['searchField']); $mainPageUrl = $this->data['mainPageUrl']; $randomPageUrl = $this->data['randomPageUrl']; $homeButton = $this->data['messages']['mobile-frontend-home-button']; $randomButton = $this->data['messages']['mobile-frontend-random-button']; $scriptUrl = wfScript(); $searchBoxDisplayNone = $this->data['hideSearchBox'] ? ' style="display: none;" ' : ''; $logoDisplayNone = $this->data['hideLogo'] ? ' style="display: none;" ' : ''; $openSearchResults = '<div id="results"></div>'; $languageSelection = $this->data['buildLanguageSelection'] . '<br/>'; $languageSelectionText = '<b>' . $this->data['messages']['mobile-frontend-language'] . ':</b><br/>'; $languageSelectionDiv = '<div id="languageselectionsection">' . $languageSelectionText . $languageSelection . '</div>'; $logoOnClick = $this->data['device']['supports_javascript'] ? 'onclick="javascript:logoClick();"' : ''; $searchWebkitHtml = <<<HTML \t\t\t{$openSearchResults} \t\t<div id='header'> \t\t\t<div id='searchbox' {$logoDisplayNone}> \t\t\t<img width="35" height="22" alt='Logo' id='logo' src='{$this->data['wgMobileFrontendLogo']}' {$logoOnClick} {$logoDisplayNone} /> \t\t\t<form action='{$scriptUrl}' class='search_bar' method='get' {$searchBoxDisplayNone}> \t\t\t <input type="hidden" value="Special:Search" name="title" /> \t\t\t\t<div id="sq" class="divclearable"> \t\t\t\t\t<input type="text" name="search" id="search" size="22" value="{$searchField}" autocorrect="off" autocomplete="off" autocapitalize="off" maxlength="1024" /> \t\t\t\t\t<div class="clearlink" id="clearsearch"></div> \t\t\t\t</div> \t\t\t <button id='goButton' type='submit'></button> \t\t\t</form> \t\t\t</div> \t\t\t<div class='nav' id='nav' {$logoDisplayNone}> \t\t\t{$languageSelectionDiv} \t\t\t<button onclick="javascript:location.href='{$mainPageUrl}';" type="submit" id="homeButton">{$homeButton}</button> \t\t\t<button onclick="javascript:location.href='{$randomPageUrl}';" type="submit" id="randomButton">{$randomButton}</button> \t\t </div> \t\t</div> HTML; return $searchWebkitHtml; }
/** * @param ResourceLoaderContext $context * @return array */ protected function getConfigSettings($context) { $hash = $context->getHash(); if (isset($this->configVars[$hash])) { return $this->configVars[$hash]; } global $wgContLang; $conf = $this->getConfig(); // We can't use Title::newMainPage() if 'mainpage' is in // $wgForceUIMsgAsContentMsg because that will try to use the session // user's language and we have no session user. This does the // equivalent but falling back to our ResourceLoaderContext language // instead. $mainPage = Title::newFromText($context->msg('mainpage')->inContentLanguage()->text()); if (!$mainPage) { $mainPage = Title::newFromText('Main Page'); } /** * Namespace related preparation * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces. * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive. */ $namespaceIds = $wgContLang->getNamespaceIds(); $caseSensitiveNamespaces = []; foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) { $namespaceIds[$wgContLang->lc($name)] = $index; if (!MWNamespace::isCapitalized($index)) { $caseSensitiveNamespaces[] = $index; } } $illegalFileChars = $conf->get('IllegalFileChars'); // Build list of variables $vars = ['wgLoadScript' => wfScript('load'), 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $conf->get('StylePath'), 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $conf->get('ArticlePath'), 'wgScriptPath' => $conf->get('ScriptPath'), 'wgScriptExtension' => '.php', 'wgScript' => wfScript(), 'wgSearchType' => $conf->get('SearchType'), 'wgVariantArticlePath' => $conf->get('VariantArticlePath'), 'wgActionPaths' => (object) $conf->get('ActionPaths'), 'wgServer' => $conf->get('Server'), 'wgServerName' => $conf->get('ServerName'), 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgTranslateNumerals' => $conf->get('TranslateNumerals'), 'wgVersion' => $conf->get('Version'), 'wgEnableAPI' => $conf->get('EnableAPI'), 'wgEnableWriteAPI' => $conf->get('EnableWriteAPI'), 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $conf->get('Sitename'), 'wgDBname' => $conf->get('DBname'), 'wgExtraSignatureNamespaces' => $conf->get('ExtraSignatureNamespaces'), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $conf->get('ExtensionAssetsPath'), 'wgCookiePrefix' => $conf->get('CookiePrefix'), 'wgCookieDomain' => $conf->get('CookieDomain'), 'wgCookiePath' => $conf->get('CookiePath'), 'wgCookieExpiration' => $conf->get('CookieExpiration'), 'wgResourceLoaderMaxQueryLength' => $conf->get('ResourceLoaderMaxQueryLength'), 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass($illegalFileChars), 'wgResourceLoaderStorageVersion' => $conf->get('ResourceLoaderStorageVersion'), 'wgResourceLoaderStorageEnabled' => $conf->get('ResourceLoaderStorageEnabled'), 'wgResourceLoaderLegacyModules' => self::getLegacyModules(), 'wgForeignUploadTargets' => $conf->get('ForeignUploadTargets'), 'wgEnableUploads' => $conf->get('EnableUploads')]; Hooks::run('ResourceLoaderGetConfigVars', [&$vars]); $this->configVars[$hash] = $vars; return $this->configVars[$hash]; }
/** * @return array Array in format "link name or number => 'link html'". */ public function getHeadLinksArray() { global $wgVersion; $tags = array(); $config = $this->getConfig(); $canonicalUrl = $this->mCanonicalUrl; $tags['meta-generator'] = Html::element('meta', array('name' => 'generator', 'content' => "MediaWiki {$wgVersion}")); if ($config->get('ReferrerPolicy') !== false) { $tags['meta-referrer'] = Html::element('meta', array('name' => 'referrer', 'content' => $config->get('ReferrerPolicy'))); } $p = "{$this->mIndexPolicy},{$this->mFollowPolicy}"; if ($p !== 'index,follow') { // http://www.robotstxt.org/wc/meta-user.html // Only show if it's different from the default robots policy $tags['meta-robots'] = Html::element('meta', array('name' => 'robots', 'content' => $p)); } foreach ($this->mMetatags as $tag) { if (0 == strcasecmp('http:', substr($tag[0], 0, 5))) { $a = 'http-equiv'; $tag[0] = substr($tag[0], 5); } else { $a = 'name'; } $tagName = "meta-{$tag[0]}"; if (isset($tags[$tagName])) { $tagName .= $tag[1]; } $tags[$tagName] = Html::element('meta', array($a => $tag[0], 'content' => $tag[1])); } foreach ($this->mLinktags as $tag) { $tags[] = Html::element('link', $tag); } # Universal edit button if ($config->get('UniversalEditButton') && $this->isArticleRelated()) { $user = $this->getUser(); if ($this->getTitle()->quickUserCan('edit', $user) && ($this->getTitle()->exists() || $this->getTitle()->quickUserCan('create', $user))) { // Original UniversalEditButton $msg = $this->msg('edit')->text(); $tags['universal-edit-button'] = Html::element('link', array('rel' => 'alternate', 'type' => 'application/x-wiki', 'title' => $msg, 'href' => $this->getTitle()->getEditURL())); // Alternate edit link $tags['alternative-edit'] = Html::element('link', array('rel' => 'edit', 'title' => $msg, 'href' => $this->getTitle()->getEditURL())); } } # Generally the order of the favicon and apple-touch-icon links # should not matter, but Konqueror (3.5.9 at least) incorrectly # uses whichever one appears later in the HTML source. Make sure # apple-touch-icon is specified first to avoid this. if ($config->get('AppleTouchIcon') !== false) { $tags['apple-touch-icon'] = Html::element('link', array('rel' => 'apple-touch-icon', 'href' => $config->get('AppleTouchIcon'))); } if ($config->get('Favicon') !== false) { $tags['favicon'] = Html::element('link', array('rel' => 'shortcut icon', 'href' => $config->get('Favicon'))); } # OpenSearch description link $tags['opensearch'] = Html::element('link', array('rel' => 'search', 'type' => 'application/opensearchdescription+xml', 'href' => wfScript('opensearch_desc'), 'title' => $this->msg('opensearch-desc')->inContentLanguage()->text())); if ($config->get('EnableAPI')) { # Real Simple Discovery link, provides auto-discovery information # for the MediaWiki API (and potentially additional custom API # support such as WordPress or Twitter-compatible APIs for a # blogging extension, etc) $tags['rsd'] = Html::element('link', array('rel' => 'EditURI', 'type' => 'application/rsd+xml', 'href' => wfExpandUrl(wfAppendQuery(wfScript('api'), array('action' => 'rsd')), PROTO_RELATIVE))); } # Language variants if (!$config->get('DisableLangConversion')) { $lang = $this->getTitle()->getPageLanguage(); if ($lang->hasVariants()) { $variants = $lang->getVariants(); foreach ($variants as $_v) { $tags["variant-{$_v}"] = Html::element('link', array('rel' => 'alternate', 'hreflang' => wfBCP47($_v), 'href' => $this->getTitle()->getLocalURL(array('variant' => $_v)))); } } # x-default link per https://support.google.com/webmasters/answer/189077?hl=en $tags["variant-x-default"] = Html::element('link', array('rel' => 'alternate', 'hreflang' => 'x-default', 'href' => $this->getTitle()->getLocalURL())); } # Copyright if ($this->copyrightUrl !== null) { $copyright = $this->copyrightUrl; } else { $copyright = ''; if ($config->get('RightsPage')) { $copy = Title::newFromText($config->get('RightsPage')); if ($copy) { $copyright = $copy->getLocalURL(); } } if (!$copyright && $config->get('RightsUrl')) { $copyright = $config->get('RightsUrl'); } } if ($copyright) { $tags['copyright'] = Html::element('link', array('rel' => 'copyright', 'href' => $copyright)); } # Feeds if ($config->get('Feed')) { foreach ($this->getSyndicationLinks() as $format => $link) { # Use the page name for the title. In principle, this could # lead to issues with having the same name for different feeds # corresponding to the same page, but we can't avoid that at # this low a level. $tags[] = $this->feedLink($format, $link, $this->msg("page-{$format}-feed", $this->getTitle()->getPrefixedText())->text()); } # Recent changes feed should appear on every page (except recentchanges, # that would be redundant). Put it after the per-page feed to avoid # changing existing behavior. It's still available, probably via a # menu in your browser. Some sites might have a different feed they'd # like to promote instead of the RC feed (maybe like a "Recent New Articles" # or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined. # If so, use it instead. $sitename = $config->get('Sitename'); if ($config->get('OverrideSiteFeed')) { foreach ($config->get('OverrideSiteFeed') as $type => $feedUrl) { // Note, this->feedLink escapes the url. $tags[] = $this->feedLink($type, $feedUrl, $this->msg("site-{$type}-feed", $sitename)->text()); } } elseif (!$this->getTitle()->isSpecial('Recentchanges')) { $rctitle = SpecialPage::getTitleFor('Recentchanges'); foreach ($config->get('AdvertisedFeedTypes') as $format) { $tags[] = $this->feedLink($format, $rctitle->getLocalURL(array('feed' => $format)), $this->msg("site-{$format}-feed", $sitename)->text()); } } } # Canonical URL if ($config->get('EnableCanonicalServerLink')) { if ($canonicalUrl !== false) { $canonicalUrl = wfExpandUrl($canonicalUrl, PROTO_CANONICAL); } else { if ($this->isArticleRelated()) { // This affects all requests where "setArticleRelated" is true. This is // typically all requests that show content (query title, curid, oldid, diff), // and all wikipage actions (edit, delete, purge, info, history etc.). // It does not apply to File pages and Special pages. // 'history' and 'info' actions address page metadata rather than the page // content itself, so they may not be canonicalized to the view page url. // TODO: this ought to be better encapsulated in the Action class. $action = Action::getActionName($this->getContext()); if (in_array($action, array('history', 'info'))) { $query = "action={$action}"; } else { $query = ''; } $canonicalUrl = $this->getTitle()->getCanonicalURL($query); } else { $reqUrl = $this->getRequest()->getRequestURL(); $canonicalUrl = wfExpandUrl($reqUrl, PROTO_CANONICAL); } } } if ($canonicalUrl !== false) { $tags[] = Html::element('link', array('rel' => 'canonical', 'href' => $canonicalUrl)); } return $tags; }
/** * 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; }
/** * Replace the result data with the information about an exception. * Returns the error code * @param Exception $e * @return string */ protected function substituteResultWithError($e) { $result = $this->getResult(); $config = $this->getConfig(); if ($e instanceof UsageException) { // User entered incorrect parameters - generate error response $errMessage = $e->getMessageArray(); $link = wfExpandUrl(wfScript('api')); ApiResult::setContentValue($errMessage, 'docref', "See {$link} for API usage"); } else { // Something is seriously wrong if ($e instanceof DBQueryError && !$config->get('ShowSQLErrors')) { $info = 'Database query error'; } else { $info = "Exception Caught: {$e->getMessage()}"; } $errMessage = array('code' => 'internal_api_error_' . get_class($e), 'info' => '[' . MWExceptionHandler::getLogId($e) . '] ' . $info); if ($config->get('ShowExceptionDetails')) { ApiResult::setContentValue($errMessage, 'trace', MWExceptionHandler::getRedactedTraceAsString($e)); } } // Remember all the warnings to re-add them later $warnings = $result->getResultData(array('warnings')); $result->reset(); // Re-add the id $requestid = $this->getParameter('requestid'); if (!is_null($requestid)) { $result->addValue(null, 'requestid', $requestid, ApiResult::NO_SIZE_CHECK); } if ($config->get('ShowHostnames')) { // servedby is especially useful when debugging errors $result->addValue(null, 'servedby', wfHostName(), ApiResult::NO_SIZE_CHECK); } if ($warnings !== null) { $result->addValue(null, 'warnings', $warnings, ApiResult::NO_SIZE_CHECK); } $result->addValue(null, 'error', $errMessage, ApiResult::NO_SIZE_CHECK); return $errMessage['code']; }
function showMergeForm() { $out = $this->getOutput(); $out->addWikiMsg('mergehistory-header'); $out->addHTML(Xml::openElement('form', ['method' => 'get', 'action' => wfScript()]) . '<fieldset>' . Xml::element('legend', [], $this->msg('mergehistory-box')->text()) . Html::hidden('title', $this->getPageTitle()->getPrefixedDBkey()) . Html::hidden('submitted', '1') . Html::hidden('mergepoint', $this->mTimestamp) . Xml::openElement('table') . '<tr> <td>' . Xml::label($this->msg('mergehistory-from')->text(), 'target') . '</td> <td>' . Xml::input('target', 30, $this->mTarget, ['id' => 'target']) . '</td> </tr><tr> <td>' . Xml::label($this->msg('mergehistory-into')->text(), 'dest') . '</td> <td>' . Xml::input('dest', 30, $this->mDest, ['id' => 'dest']) . '</td> </tr><tr><td>' . Xml::submitButton($this->msg('mergehistory-go')->text()) . '</td></tr>' . Xml::closeElement('table') . '</fieldset>' . '</form>'); $this->addHelpLink('Help:Merge history'); }
/** * Builds an internal list of APIs to expose information about. * Normally this only lists the MediaWiki API, with its base URL, * link to documentation, and a marker as to available authentication * (to aid in OAuth client apps switching to support in the future). * * Extensions can expose other APIs, such as WordPress or Twitter- * compatible APIs, by hooking 'ApiRsdServiceApis' and adding more * elements to the array. * * See http://cyber.law.harvard.edu/blogs/gems/tech/rsd.html for * the base RSD spec, and check WordPress and StatusNet sites for * in-production examples listing several blogging and micrblogging * APIs. * * @return array */ protected function getRsdApiList() { $apis = array('MediaWiki' => array('apiLink' => wfExpandUrl(wfScript('api'), PROTO_CURRENT), 'docs' => 'https://www.mediawiki.org/wiki/API', 'blogID' => '', 'settings' => array('OAuth' => false))); Hooks::run('ApiRsdServiceApis', array(&$apis)); return $apis; }
/** * Register core modules and runs registration hooks. * @param Config|null $config */ public function __construct(Config $config = null, LoggerInterface $logger = null) { global $IP; if (!$logger) { $logger = new NullLogger(); } $this->setLogger($logger); if (!$config) { $this->logger->debug(__METHOD__ . ' was called without providing a Config instance'); $config = ConfigFactory::getDefaultInstance()->makeConfig('main'); } $this->config = $config; // Add 'local' source first $this->addSource('local', wfScript('load')); // Add other sources $this->addSource($config->get('ResourceLoaderSources')); // Register core modules $this->register(include "{$IP}/resources/Resources.php"); $this->register(include "{$IP}/resources/ResourcesOOUI.php"); // Register extension modules Hooks::run('ResourceLoaderRegisterModules', array(&$this)); $this->register($config->get('ResourceModules')); if ($config->get('EnableJavaScriptTest') === true) { $this->registerTestModules(); } $this->setMessageBlobStore(new MessageBlobStore()); }
/** * Set the text to be displayed above the changes * * @param FormOptions $opts * @param int $numRows Number of rows in the result to show after this header */ public function doHeader($opts, $numRows) { $this->setTopText($opts); $defaults = $opts->getAllValues(); $nondefaults = $opts->getChangedValues(); $panel = array(); $panel[] = self::makeLegend($this->getContext()); $panel[] = $this->optionsPanel($defaults, $nondefaults, $numRows); $panel[] = '<hr />'; $extraOpts = $this->getExtraOptions($opts); $extraOptsCount = count($extraOpts); $count = 0; $submit = ' ' . Xml::submitbutton($this->msg('allpagessubmit')->text()); $out = Xml::openElement('table', array('class' => 'mw-recentchanges-table')); foreach ($extraOpts as $name => $optionRow) { # Add submit button to the last row only ++$count; $addSubmit = $count === $extraOptsCount ? $submit : ''; $out .= Xml::openElement('tr'); if (is_array($optionRow)) { $out .= Xml::tags('td', array('class' => 'mw-label mw-' . $name . '-label'), $optionRow[0]); $out .= Xml::tags('td', array('class' => 'mw-input'), $optionRow[1] . $addSubmit); } else { $out .= Xml::tags('td', array('class' => 'mw-input', 'colspan' => 2), $optionRow . $addSubmit); } $out .= Xml::closeElement('tr'); } $out .= Xml::closeElement('table'); $unconsumed = $opts->getUnconsumedValues(); foreach ($unconsumed as $key => $value) { $out .= Html::hidden($key, $value); } $t = $this->getPageTitle(); $out .= Html::hidden('title', $t->getPrefixedText()); $form = Xml::tags('form', array('action' => wfScript()), $out); $panel[] = $form; $panelString = implode("\n", $panel); $this->getOutput()->addHTML(Xml::fieldset($this->msg('recentchanges-legend')->text(), $panelString, array('class' => 'rcoptions'))); $this->setBottomText($opts); }
function showSearchForm() { $out = $this->getOutput(); $out->setPageTitle($this->msg('undelete-search-title')); $out->addHTML(Xml::openElement('form', array('method' => 'get', 'action' => wfScript())) . Xml::fieldset($this->msg('undelete-search-box')->text()) . Html::hidden('title', $this->getPageTitle()->getPrefixedDBkey()) . Html::rawElement('label', array('for' => 'prefix'), $this->msg('undelete-search-prefix')->parse()) . Xml::input('prefix', 20, $this->mSearchPrefix, array('id' => 'prefix', 'autofocus' => '')) . ' ' . Xml::submitButton($this->msg('undelete-search-submit')->text()) . Xml::closeElement('fieldset') . Xml::closeElement('form')); # List undeletable articles if ($this->mSearchPrefix) { $result = PageArchive::listPagesByPrefix($this->mSearchPrefix); $this->showList($result); } }
private function getActionButtons($formcontents) { $user = $this->getUser(); $canRevDelete = $user->isAllowedAll('deletedhistory', 'deletelogentry'); $showTagEditUI = ChangeTags::showTagEditingUI($user); # If the user doesn't have the ability to delete log entries nor edit tags, # don't bother showing them the button(s). if (!$canRevDelete && !$showTagEditUI) { return $formcontents; } # Show button to hide log entries and/or edit change tags $s = Html::openElement('form', array('action' => wfScript(), 'id' => 'mw-log-deleterevision-submit')) . "\n"; $s .= Html::hidden('action', 'historysubmit') . "\n"; $s .= Html::hidden('type', 'logging') . "\n"; $buttons = ''; if ($canRevDelete) { $buttons .= Html::element('button', array('type' => 'submit', 'name' => 'revisiondelete', 'value' => '1', 'class' => "deleterevision-log-submit mw-log-deleterevision-button"), $this->msg('showhideselectedlogentries')->text()) . "\n"; } if ($showTagEditUI) { $buttons .= Html::element('button', array('type' => 'submit', 'name' => 'editchangetags', 'value' => '1', 'class' => "editchangetags-log-submit mw-log-editchangetags-button"), $this->msg('log-edit-tags')->text()) . "\n"; } // Select: All, None, Invert $links = array(); $links[] = Html::element('a', array('href' => '#', 'id' => 'checkbox-all'), $this->msg('checkbox-all')->text()); $links[] = Html::element('a', array('href' => '#', 'id' => 'checkbox-none'), $this->msg('checkbox-none')->text()); $links[] = Html::element('a', array('href' => '#', 'id' => 'checkbox-invert'), $this->msg('checkbox-invert')->text()); $buttons .= Html::rawElement('p', array('class' => "mw-checkbox-toggle-controls"), $this->msg('checkbox-select')->rawParams($this->getLanguage()->commaList($links))->escaped()); $this->getOutput()->addModules('mediawiki.checkboxtoggle'); $this->getOutput()->addModuleStyles('mediawiki.checkboxtoggle.styles'); $s .= $buttons . $formcontents . $buttons; $s .= Html::closeElement('form'); return $s; }
/** * @param int $namespace * @param string $type Restriction type * @param string $level Restriction level * @param string $sizetype "min" or "max" * @param int $size * @param bool $indefOnly Only indefinite protection * @param bool $cascadeOnly Only cascading protection * @param bool $noRedirect Don't show redirects * @return string Input form */ protected function showOptions($namespace, $type = 'edit', $level, $sizetype, $size, $indefOnly, $cascadeOnly, $noRedirect) { $title = $this->getPageTitle(); return Xml::openElement('form', array('method' => 'get', 'action' => wfScript())) . Xml::openElement('fieldset') . Xml::element('legend', array(), $this->msg('protectedpages')->text()) . Html::hidden('title', $title->getPrefixedDBkey()) . "\n" . $this->getNamespaceMenu($namespace) . "\n" . $this->getTypeMenu($type) . "\n" . $this->getLevelMenu($level) . "\n" . "<br />\n" . $this->getExpiryCheck($indefOnly) . "\n" . $this->getCascadeCheck($cascadeOnly) . "\n" . $this->getRedirectCheck($noRedirect) . "\n" . "<br />\n" . $this->getSizeLimit($sizetype, $size) . "\n" . Xml::submitButton($this->msg('allpagessubmit')->text()) . "\n" . Xml::closeElement('fieldset') . Xml::closeElement('form'); }
/** * Handle Special:Redirect/logid/xxx * (by redirecting to index.php?title=Special:Log) * * @since 1.27 * @return string|null Url to redirect to, or null if $mValue is invalid. */ function dispatchLog() { $logid = $this->mValue; if (!ctype_digit($logid)) { return null; } $logid = (int) $logid; if ($logid === 0) { return null; } $logparams = ['log_id', 'log_timestamp', 'log_type', 'log_user_text']; $dbr = wfGetDB(DB_REPLICA); // Gets the nested SQL statement which // returns timestamp of the log with the given log ID $inner = $dbr->selectSQLText('logging', ['log_timestamp'], ['log_id' => $logid]); // Returns all fields mentioned in $logparams of the logs // with the same timestamp as the one returned by the statement above $logsSameTimestamps = $dbr->select('logging', $logparams, ["log_timestamp = ({$inner})"]); if ($logsSameTimestamps->numRows() === 0) { return null; } // Stores the row with the same log ID as the one given $rowMain = []; foreach ($logsSameTimestamps as $row) { if ((int) $row->log_id === $logid) { $rowMain = $row; } } array_shift($logparams); // Stores all the rows with the same values in each column // as $rowMain foreach ($logparams as $cond) { $matchedRows = []; foreach ($logsSameTimestamps as $row) { if ($row->{$cond} === $rowMain->{$cond}) { $matchedRows[] = $row; } } if (count($matchedRows) === 1) { break; } $logsSameTimestamps = $matchedRows; } $query = ['title' => 'Special:Log', 'limit' => count($matchedRows)]; // A map of database field names from table 'logging' to the values of $logparams $keys = ['log_timestamp' => 'offset', 'log_type' => 'type', 'log_user_text' => 'user']; foreach ($logparams as $logKey) { $query[$keys[$logKey]] = $matchedRows[0]->{$logKey}; } $query['offset'] = $query['offset'] + 1; $url = $query; return wfAppendQuery(wfScript('index'), $url); }
function getPageHeader() { # Do not show useless input form if special page is cached if ($this->isCached()) { return ''; } $prefix = $this->prefix; $t = $this->getPageTitle(); return Html::openElement('form', array('method' => 'get', 'action' => wfScript())) . "\n" . Html::openElement('fieldset') . "\n" . Html::element('legend', null, $this->msg('withoutinterwiki-legend')->text()) . "\n" . Html::hidden('title', $t->getPrefixedText()) . "\n" . Xml::inputLabel($this->msg('allpagesprefix')->text(), 'prefix', 'wiprefix', 20, $prefix) . "\n" . Xml::submitButton($this->msg('withoutinterwiki-submit')->text()) . "\n" . Html::closeElement('fieldset') . "\n" . Html::closeElement('form'); }