Пример #1
0
 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);
 }
Пример #4
0
 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();
 }
Пример #5
0
 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();
 }
Пример #6
0
 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(),
			) ) );
	}
Пример #9
0
 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);
 }
Пример #16
0
 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];
 }
Пример #19
0
 /**
  * @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;
 }
Пример #20
0
 /**
  * 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;
 }
Пример #21
0
 /**
  * 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'];
 }
Пример #22
0
    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');
    }
Пример #23
0
 /**
  * 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;
 }
Пример #24
0
 /**
  * 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());
 }
Пример #25
0
 /**
  * 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);
 }
Пример #26
0
 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);
     }
 }
Пример #27
0
 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;
 }
Пример #28
0
 /**
  * @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');
 }
Пример #29
0
 /**
  * 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');
 }