private static function getManager($continue, $allModules, $generatedModules)
 {
     $context = new DerivativeContext(RequestContext::getMain());
     $context->setRequest(new FauxRequest(array('continue' => $continue)));
     $main = new ApiMain($context);
     return new ApiContinuationManager($main, $allModules, $generatedModules);
 }
 /**
  * Main execution point
  *
  * @param string $par title fragment
  */
 public function execute($par)
 {
     $this->setHeaders();
     $this->outputHeader();
     $out = $this->getOutput();
     $lang = $this->getLanguage();
     $out->setPageTitle($this->msg('ipblocklist'));
     $out->addModuleStyles('mediawiki.special');
     $request = $this->getRequest();
     $par = $request->getVal('ip', $par);
     $this->target = trim($request->getVal('wpTarget', $par));
     $this->options = $request->getArray('wpOptions', array());
     $action = $request->getText('action');
     if ($action == 'unblock' || $action == 'submit' && $request->wasPosted()) {
         # B/C @since 1.18: Unblock interface is now at Special:Unblock
         $title = SpecialPage::getTitleFor('Unblock', $this->target);
         $out->redirect($title->getFullURL());
         return;
     }
     # Just show the block list
     $fields = array('Target' => array('type' => 'text', 'label-message' => 'ipadressorusername', 'tabindex' => '1', 'size' => '45', 'default' => $this->target), 'Options' => array('type' => 'multiselect', 'options' => array($this->msg('blocklist-userblocks')->text() => 'userblocks', $this->msg('blocklist-tempblocks')->text() => 'tempblocks', $this->msg('blocklist-addressblocks')->text() => 'addressblocks', $this->msg('blocklist-rangeblocks')->text() => 'rangeblocks'), 'flatlist' => true), 'Limit' => array('class' => 'HTMLBlockedUsersItemSelect', 'label-message' => 'table_pager_limit_label', 'options' => array($lang->formatNum(20) => 20, $lang->formatNum(50) => 50, $lang->formatNum(100) => 100, $lang->formatNum(250) => 250, $lang->formatNum(500) => 500), 'name' => 'limit', 'default' => 50));
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle());
     // Remove subpage
     $form = new HTMLForm($fields, $context);
     $form->setMethod('get');
     $form->setWrapperLegendMsg('ipblocklist-legend');
     $form->setSubmitTextMsg('ipblocklist-submit');
     $form->prepareForm();
     $form->displayForm('');
     $this->showList();
 }
 /**
  * @dataProvider provideValidate
  */
 public function testForm($text, $value)
 {
     $form = HTMLForm::factory('ooui', ['restrictions' => ['class' => HTMLRestrictionsField::class]]);
     $request = new FauxRequest(['wprestrictions' => $text], true);
     $context = new DerivativeContext(RequestContext::getMain());
     $context->setRequest($request);
     $form->setContext($context);
     $form->setTitle(Title::newFromText('Main Page'))->setSubmitCallback(function () {
         return true;
     })->prepareForm();
     $status = $form->trySubmit();
     if ($status instanceof StatusValue) {
         $this->assertEquals($value !== false, $status->isGood());
     } elseif ($value === false) {
         $this->assertNotSame(true, $status);
     } else {
         $this->assertSame(true, $status);
     }
     if ($value !== false) {
         $restrictions = $form->mFieldData['restrictions'];
         $this->assertInstanceOf(MWRestrictions::class, $restrictions);
         $this->assertEquals($value, $restrictions->toArray()['IPAddresses']);
     }
     // sanity
     $form->getHTML($status);
 }
Example #4
0
 /**
  * Format the rows (generated by SpecialRecentchanges or SpecialRecentchangeslinked)
  * as an RSS/Atom feed.
  */
 public function execute()
 {
     $config = $this->getConfig();
     $this->params = $this->extractRequestParams();
     if (!$config->get('Feed')) {
         $this->dieUsage('Syndication feeds are not available', 'feed-unavailable');
     }
     $feedClasses = $config->get('FeedClasses');
     if (!isset($feedClasses[$this->params['feedformat']])) {
         $this->dieUsage('Invalid subscription feed type', 'feed-invalid');
     }
     $this->getMain()->setCacheMode('public');
     if (!$this->getMain()->getParameter('smaxage')) {
         // bug 63249: This page gets hit a lot, cache at least 15 seconds.
         $this->getMain()->setCacheMaxAge(15);
     }
     $feedFormat = $this->params['feedformat'];
     $specialClass = $this->params['target'] !== null ? 'SpecialRecentchangeslinked' : 'SpecialRecentchanges';
     $formatter = $this->getFeedObject($feedFormat, $specialClass);
     // Parameters are passed via the request in the context… :(
     $context = new DerivativeContext($this);
     $context->setRequest(new DerivativeRequest($this->getRequest(), $this->params, $this->getRequest()->wasPosted()));
     // The row-getting functionality should be factored out of ChangesListSpecialPage too…
     $rc = new $specialClass();
     $rc->setContext($context);
     $rows = $rc->getRows();
     $feedItems = $rows ? ChangesFeed::buildItems($rows) : array();
     ApiFormatFeedWrapper::setResult($this->getResult(), $formatter, $feedItems);
 }
 private function getContext($requestedAction = null)
 {
     $request = new FauxRequest(array('action' => $requestedAction));
     $context = new DerivativeContext(RequestContext::getMain());
     $context->setRequest($request);
     $context->setWikiPage($this->getPage());
     return $context;
 }
 /**
  * If we are trying to edit and no token is set, supply one.
  *
  * @param DerivativeContext $context
  */
 private function setEditTokenFromUser(DerivativeContext $context)
 {
     $request = $context->getRequest();
     // Edits via GET are a security issue and should not succeed. On the other hand, not all
     // POST requests are edits, but should ignore unused parameters.
     if (!$request->getCheck('wpEditToken') && $request->wasPosted()) {
         $request->setVal('wpEditToken', $context->getUser()->getEditToken());
     }
 }
 /**
  * @param string $url
  * @param array $cookies
  * @return MobileContext
  */
 private function makeContext($url = '/', $cookies = array())
 {
     $context = new DerivativeContext(RequestContext::getMain());
     $context->setRequest(new MFFauxRequest($url, $cookies));
     $context->setOutput(new OutputPage($context));
     $instance = unserialize('O:13:"MobileContext":0:{}');
     $instance->setContext($context);
     return $instance;
 }
Example #8
0
 /**
  * Returns a DerivativeContext with the request variables in place
  *
  * @param $request WebRequest request object including parameters and session
  * @param $user User or null
  * @return DerivativeContext
  */
 public function newTestContext(WebRequest $request, User $user = null)
 {
     $context = new DerivativeContext($this);
     $context->setRequest($request);
     if ($user !== null) {
         $context->setUser($user);
     }
     return $context;
 }
 private function showResetForm()
 {
     if (!$this->getUser()->isAllowed('editmyoptions')) {
         throw new PermissionsError('editmyoptions');
     }
     $this->getOutput()->addWikiMsg('prefs-reset-intro');
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle('reset'));
     // Reset subpage
     $htmlForm = new HTMLForm(array(), $context, 'prefs-restore');
     $htmlForm->setSubmitTextMsg('restoreprefs');
     $htmlForm->setSubmitCallback(array($this, 'submitReset'));
     $htmlForm->suppressReset();
     $htmlForm->show();
 }
 /**
  * Returns warning messages in situations where a revision cannot be viewed by a user
  * explaining to them why.
  * Returns empty string when the revision can be viewed.
  *
  * @return string
  */
 public function getWarningMessageText()
 {
     $msg = '';
     if ($this->isHiddenFromUser()) {
         $allowed = $this->isUserAllowedToSee();
         $suppressed = $this->isSuppressedDiff();
         // This IContextSource object will be used to get a message object for the
         // messages used in this function. We need to to this to allow the message to
         // get the correct value for the FULLPAGENAME inclusion (which is used in
         // rev-suppressed-no-diff, e.g.). Otherwise it would use Special:MobileDiff as
         // the target for Special:Log/delete?page=Special:MobileDiff/..., which isn't
         // correct and very helpful. To fix this bug, we create a new context from the
         // current one and set the title object (which we can get from the new revision).
         // Bug: T122984
         $context = new DerivativeContext($this->getContext());
         $revision = $this->mNewRev;
         $context->setTitle($revision->getTitle());
         if (!$allowed) {
             $msg = $context->msg($suppressed ? 'rev-suppressed-no-diff' : 'rev-deleted-no-diff')->parse();
         } else {
             # Give explanation and add a link to view the diff...
             $query = $this->getRequest()->appendQueryValue('unhide', '1', true);
             $link = $this->getTitle()->getFullURL($query);
             $msg = $context->msg($suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff', $link)->parse();
         }
     }
     return $msg;
 }
 /**
  * @param string $url
  * @param array $cookies
  * @return MobileContext
  */
 private function makeContext($url = '/', $cookies = array())
 {
     $query = array();
     if ($url) {
         $params = wfParseUrl(wfExpandUrl($url));
         if (isset($params['query'])) {
             $query = wfCgiToArray($params['query']);
         }
     }
     $request = new FauxRequest($query);
     $request->setRequestURL($url);
     $request->setCookies($cookies, '');
     $context = new DerivativeContext(RequestContext::getMain());
     $context->setRequest($request);
     $context->setOutput(new OutputPage($context));
     $instance = unserialize('O:13:"MobileContext":0:{}');
     $instance->setContext($context);
     return $instance;
 }
Example #12
0
 /**
  * @dataProvider provideGetParameterFromSettings
  * @param string|null $input
  * @param array $paramSettings
  * @param mixed $expected
  * @param string[] $warnings
  */
 public function testGetParameterFromSettings($input, $paramSettings, $expected, $warnings)
 {
     $mock = new MockApi();
     $wrapper = TestingAccessWrapper::newFromObject($mock);
     $context = new DerivativeContext($mock);
     $context->setRequest(new FauxRequest($input !== null ? ['foo' => $input] : []));
     $wrapper->mMainModule = new ApiMain($context);
     if ($expected instanceof UsageException) {
         try {
             $wrapper->getParameterFromSettings('foo', $paramSettings, true);
         } catch (UsageException $ex) {
             $this->assertEquals($expected, $ex);
         }
     } else {
         $result = $wrapper->getParameterFromSettings('foo', $paramSettings, true);
         $this->assertSame($expected, $result);
         $this->assertSame($warnings, $mock->warnings);
     }
 }
Example #13
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     $modules = array();
     foreach ($params['modules'] as $path) {
         $modules[] = $this->getModuleFromPath($path);
     }
     // Get the help
     $context = new DerivativeContext($this->getMain()->getContext());
     $context->setSkin(SkinFactory::getDefaultInstance()->makeSkin('apioutput'));
     $context->setLanguage($this->getMain()->getLanguage());
     $context->setTitle(SpecialPage::getTitleFor('ApiHelp'));
     $out = new OutputPage($context);
     $out->setCopyrightUrl('https://www.mediawiki.org/wiki/Special:MyLanguage/Copyright');
     $context->setOutput($out);
     self::getHelp($context, $modules, $params);
     // Grab the output from the skin
     ob_start();
     $context->getOutput()->output();
     $html = ob_get_clean();
     $result = $this->getResult();
     if ($params['wrap']) {
         $data = array('mime' => 'text/html', 'help' => $html);
         ApiResult::setSubelementsList($data, 'help');
         $result->addValue(null, $this->getModuleName(), $data);
     } else {
         $result->reset();
         $result->addValue(null, 'text', $html, ApiResult::NO_SIZE_CHECK);
         $result->addValue(null, 'mime', 'text/html', ApiResult::NO_SIZE_CHECK);
     }
 }
 /**
  * Creates a new set of object for the actual test context, including a new
  * outputpage and skintemplate.
  *
  * @param string $mode The mode for the test cases (desktop, mobile)
  * @return array Array of objects, including MobileContext (context),
  * SkinTemplate (sk) and OutputPage (out)
  */
 protected function getContextSetup($mode, $mfXAnalyticsItems)
 {
     // Create a new MobileContext object for this test
     MobileContext::setInstance(null);
     // create a new instance of MobileContext
     $context = MobileContext::singleton();
     // create a DerivativeContext to use in MobileContext later
     $mainContext = new DerivativeContext(RequestContext::getMain());
     // create a new, empty OutputPage
     $out = new OutputPage($context);
     // create a new, empty SkinTemplate
     $sk = new SkinTemplate();
     // create a new Title (main page)
     $title = Title::newMainPage();
     // create a FauxRequest to use instead of a WebRequest object (FauxRequest forces
     // the creation of a FauxResponse, which allows to investigate sent header values)
     $request = new FauxRequest();
     // set the new request object to the context
     $mainContext->setRequest($request);
     // set the main page title to the context
     $mainContext->setTitle($title);
     // set the context to the SkinTemplate
     $sk->setContext($mainContext);
     // set the OutputPage to the context
     $mainContext->setOutput($out);
     // set the DerivativeContext as a base to MobileContext
     $context->setContext($mainContext);
     // set the mode to MobileContext
     $context->setUseFormat($mode);
     // if there are any XAnalytics items, add them
     foreach ($mfXAnalyticsItems as $key => $val) {
         $context->addAnalyticsLogItem($key, $val);
     }
     // set the newly created MobileContext object as the current instance to use
     MobileContext::setInstance($context);
     // return the stuff
     return array('out' => $out, 'sk' => $sk, 'context' => $context);
 }
Example #15
0
 /**
  * Finish printing and output buffered data.
  */
 public function closePrinter()
 {
     if ($this->mDisabled) {
         return;
     }
     $mime = $this->getMimeType();
     if ($this->getIsHtml() && $mime !== null) {
         $format = $this->getFormat();
         $lcformat = strtolower($format);
         $result = $this->getBuffer();
         $context = new DerivativeContext($this->getMain());
         $context->setSkin(SkinFactory::getDefaultInstance()->makeSkin('apioutput'));
         $context->setTitle(SpecialPage::getTitleFor('ApiHelp'));
         $out = new OutputPage($context);
         $context->setOutput($out);
         $out->addModuleStyles('mediawiki.apipretty');
         $out->setPageTitle($context->msg('api-format-title'));
         if (!$this->getIsWrappedHtml()) {
             // When the format without suffix 'fm' is defined, there is a non-html version
             if ($this->getMain()->getModuleManager()->isDefined($lcformat, 'format')) {
                 $msg = $context->msg('api-format-prettyprint-header')->params($format, $lcformat);
             } else {
                 $msg = $context->msg('api-format-prettyprint-header-only-html')->params($format);
             }
             $header = $msg->parseAsBlock();
             $out->addHTML(Html::rawElement('div', ['class' => 'api-pretty-header'], ApiHelp::fixHelpLinks($header)));
         }
         if (Hooks::run('ApiFormatHighlight', [$context, $result, $mime, $format])) {
             $out->addHTML(Html::element('pre', ['class' => 'api-pretty-content'], $result));
         }
         if ($this->getIsWrappedHtml()) {
             // This is a special output mode mainly intended for ApiSandbox use
             $time = microtime(true) - $this->getConfig()->get('RequestTime');
             $json = FormatJson::encode(['html' => $out->getHTML(), 'modules' => array_values(array_unique(array_merge($out->getModules(), $out->getModuleScripts(), $out->getModuleStyles()))), 'time' => round($time * 1000)], false, FormatJson::ALL_OK);
             // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
             // Flash, but what it does isn't friendly for the API, so we need to
             // work around it.
             if (preg_match('/\\<\\s*cross-domain-policy\\s*\\>/i', $json)) {
                 $json = preg_replace('/\\<(\\s*cross-domain-policy\\s*)\\>/i', '\\u003C$1\\u003E', $json);
             }
             echo $json;
         } else {
             // API handles its own clickjacking protection.
             // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
             $out->allowClickjacking();
             $out->output();
         }
     } else {
         // For non-HTML output, clear all errors that might have been
         // displayed if display_errors=On
         ob_clean();
         echo $this->getBuffer();
     }
 }
Example #16
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     if ($title === null) {
         $titleProvided = false;
         // A title is needed for parsing, so arbitrarily choose one
         $title = 'API';
     } else {
         $titleProvided = true;
     }
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     $model = $params['contentmodel'];
     $format = $params['contentformat'];
     if (!is_null($page) && (!is_null($text) || $titleProvided)) {
         $this->dieUsage('The page parameter cannot be used together with the text and title parameters', 'params');
     }
     $prop = array_flip($params['prop']);
     if (isset($params['section'])) {
         $this->section = $params['section'];
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     // TODO: Does this still need $wgTitle?
     global $wgParser, $wgTitle;
     // Currently unnecessary, code to act as a safeguard against any change
     // in current behavior of uselang
     $oldLang = null;
     if (isset($params['uselang']) && $params['uselang'] != $this->getContext()->getLanguage()->getCode()) {
         $oldLang = $this->getContext()->getLanguage();
         // Backup language
         $this->getContext()->setLanguage(Language::factory($params['uselang']));
     }
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromID($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             $this->checkReadPermissions($rev->getTitle());
             if (!$rev->userCan(Revision::DELETED_TEXT, $this->getUser())) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $pageObj = WikiPage::factory($titleObj);
             $popts = $this->makeParserOptions($pageObj, $params);
             // If for some reason the "oldid" is actually the current revision, it may be cached
             if ($rev->isCurrent()) {
                 // May get from/save to parser cache
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->content = $rev->getContent(Revision::FOR_THIS_USER, $this->getUser());
                 if ($this->section !== false) {
                     $this->content = $this->getSectionContent($this->content, 'r' . $rev->getId());
                 }
                 // Should we save old revision parses to the parser cache?
                 $p_result = $this->content->getParserOutput($titleObj, $rev->getId(), $popts);
             }
         } else {
             // Not $oldid, but $pageid or $page
             if ($params['redirects']) {
                 $reqParams = array('action' => 'query', 'redirects' => '');
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $main->execute();
                 $data = $main->getResultData();
                 $redirValues = isset($data['query']['redirects']) ? $data['query']['redirects'] : array();
                 $to = $page;
                 foreach ((array) $redirValues as $r) {
                     $to = $r['to'];
                 }
                 $pageParams = array('title' => $to);
             } elseif (!is_null($pageid)) {
                 $pageParams = array('pageid' => $pageid);
             } else {
                 // $page
                 $pageParams = array('title' => $page);
             }
             $pageObj = $this->getTitleOrPageId($pageParams, 'fromdb');
             $titleObj = $pageObj->getTitle();
             if (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $this->checkReadPermissions($titleObj);
             $wgTitle = $titleObj;
             if (isset($prop['revid'])) {
                 $oldid = $pageObj->getLatest();
             }
             $popts = $this->makeParserOptions($pageObj, $params);
             // Potentially cached
             $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         $titleObj = Title::newFromText($title);
         if (!$titleObj || $titleObj->isExternal()) {
             $this->dieUsageMsg(array('invalidtitle', $title));
         }
         $wgTitle = $titleObj;
         if ($titleObj->canExist()) {
             $pageObj = WikiPage::factory($titleObj);
         } else {
             // Do like MediaWiki::initializeArticle()
             $article = Article::newFromTitle($titleObj, $this->getContext());
             $pageObj = $article->getPage();
         }
         $popts = $this->makeParserOptions($pageObj, $params);
         $textProvided = !is_null($text);
         if (!$textProvided) {
             if ($titleProvided && ($prop || $params['generatexml'])) {
                 $this->setWarning("'title' used without 'text', and parsed page properties were requested " . "(did you mean to use 'page' instead of 'title'?)");
             }
             // Prevent warning from ContentHandler::makeContent()
             $text = '';
         }
         // If we are parsing text, do not use the content model of the default
         // API title, but default to wikitext to keep BC.
         if ($textProvided && !$titleProvided && is_null($model)) {
             $model = CONTENT_MODEL_WIKITEXT;
             $this->setWarning("No 'title' or 'contentmodel' was given, assuming {$model}.");
         }
         try {
             $this->content = ContentHandler::makeContent($text, $titleObj, $model, $format);
         } catch (MWContentSerializationException $ex) {
             $this->dieUsage($ex->getMessage(), 'parseerror');
         }
         if ($this->section !== false) {
             $this->content = $this->getSectionContent($this->content, $titleObj->getText());
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstContent = $this->content->preSaveTransform($titleObj, $this->getUser(), $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array = array();
             $result_array['text'] = array();
             ApiResult::setContent($result_array['text'], $this->pstContent->serialize($format));
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = array();
                 ApiResult::setContent($result_array['wikitext'], $this->content->serialize($format));
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         // Not cached (save or load)
         if ($params['pst']) {
             $p_result = $this->pstContent->getParserOutput($titleObj, null, $popts);
         } else {
             $p_result = $this->content->getParserOutput($titleObj, null, $popts);
         }
     }
     $result_array = array();
     $result_array['title'] = $titleObj->getPrefixedText();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if ($params['disabletoc']) {
         $p_result->setTOCEnabled(false);
     }
     if (isset($prop['text'])) {
         $result_array['text'] = array();
         ApiResult::setContent($result_array['text'], $p_result->getText());
     }
     if (!is_null($params['summary'])) {
         $result_array['parsedsummary'] = array();
         ApiResult::setContent($result_array['parsedsummary'], Linker::formatComment($params['summary'], $titleObj));
     }
     if (isset($prop['langlinks']) || isset($prop['languageshtml'])) {
         $langlinks = $p_result->getLanguageLinks();
         if ($params['effectivelanglinks']) {
             // Link flags are ignored for now, but may in the future be
             // included in the result.
             $linkFlags = array();
             wfRunHooks('LanguageLinks', array($titleObj, &$langlinks, &$linkFlags));
         }
     } else {
         $langlinks = false;
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($langlinks);
     }
     if (isset($prop['languageshtml'])) {
         $languagesHtml = $this->languagesHtml($langlinks);
         $result_array['languageshtml'] = array();
         ApiResult::setContent($result_array['languageshtml'], $languagesHtml);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $categoriesHtml = $this->categoriesHtml($p_result->getCategories());
         $result_array['categorieshtml'] = array();
         ApiResult::setContent($result_array['categorieshtml'], $categoriesHtml);
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ? $p_result->getDisplayTitle() : $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems']) || isset($prop['headhtml'])) {
         $context = new DerivativeContext($this->getContext());
         $context->setTitle($titleObj);
         $context->setWikiPage($pageObj);
         // We need an OutputPage tied to $context, not to the
         // RequestContext at the root of the stack.
         $output = new OutputPage($context);
         $output->addParserOutputNoText($p_result);
         if (isset($prop['headitems'])) {
             $headItems = $this->formatHeadItems($p_result->getHeadItems());
             $css = $this->formatCss($output->buildCssLinksArray());
             $scripts = array($output->getHeadScripts());
             $result_array['headitems'] = array_merge($headItems, $css, $scripts);
         }
         if (isset($prop['headhtml'])) {
             $result_array['headhtml'] = array();
             ApiResult::setContent($result_array['headhtml'], $output->headElement($context->getSkin()));
         }
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = array();
         ApiResult::setContent($result_array['wikitext'], $this->content->serialize($format));
         if (!is_null($this->pstContent)) {
             $result_array['psttext'] = array();
             ApiResult::setContent($result_array['psttext'], $this->pstContent->serialize($format));
         }
     }
     if (isset($prop['properties'])) {
         $result_array['properties'] = $this->formatProperties($p_result->getProperties());
     }
     if (isset($prop['limitreportdata'])) {
         $result_array['limitreportdata'] = $this->formatLimitReportData($p_result->getLimitReportData());
     }
     if (isset($prop['limitreporthtml'])) {
         $limitreportHtml = EditPage::getPreviewLimitReport($p_result);
         $result_array['limitreporthtml'] = array();
         ApiResult::setContent($result_array['limitreporthtml'], $limitreportHtml);
     }
     if ($params['generatexml']) {
         if ($this->content->getModel() != CONTENT_MODEL_WIKITEXT) {
             $this->dieUsage("generatexml is only supported for wikitext content", "notwikitext");
         }
         $wgParser->startExternalParse($titleObj, $popts, OT_PREPROCESS);
         $dom = $wgParser->preprocessToDom($this->content->getNativeData());
         if (is_callable(array($dom, 'saveXML'))) {
             $xml = $dom->saveXML();
         } else {
             $xml = $dom->__toString();
         }
         $result_array['parsetree'] = array();
         ApiResult::setContent($result_array['parsetree'], $xml);
     }
     $result_mapping = array('redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi', 'properties' => 'pp', 'limitreportdata' => 'lr');
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
     if (!is_null($oldLang)) {
         $this->getContext()->setLanguage($oldLang);
         // Reset language to $oldLang
     }
 }
 /**
  * Extract information from the Revision
  *
  * @param Revision $revision
  * @param object $row Should have a field 'ts_tags' if $this->fld_tags is set
  * @return array
  */
 protected function extractRevisionInfo(Revision $revision, $row)
 {
     $title = $revision->getTitle();
     $user = $this->getUser();
     $vals = array();
     $anyHidden = false;
     if ($this->fld_ids) {
         $vals['revid'] = intval($revision->getId());
         if (!is_null($revision->getParentId())) {
             $vals['parentid'] = intval($revision->getParentId());
         }
     }
     if ($this->fld_flags) {
         $vals['minor'] = $revision->isMinor();
     }
     if ($this->fld_user || $this->fld_userid) {
         if ($revision->isDeleted(Revision::DELETED_USER)) {
             $vals['userhidden'] = true;
             $anyHidden = true;
         }
         if ($revision->userCan(Revision::DELETED_USER, $user)) {
             if ($this->fld_user) {
                 $vals['user'] = $revision->getUserText(Revision::RAW);
             }
             $userid = $revision->getUser(Revision::RAW);
             if (!$userid) {
                 $vals['anon'] = true;
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $userid;
             }
         }
     }
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp());
     }
     if ($this->fld_size) {
         if (!is_null($revision->getSize())) {
             $vals['size'] = intval($revision->getSize());
         } else {
             $vals['size'] = 0;
         }
     }
     if ($this->fld_sha1) {
         if ($revision->isDeleted(Revision::DELETED_TEXT)) {
             $vals['sha1hidden'] = true;
             $anyHidden = true;
         }
         if ($revision->userCan(Revision::DELETED_TEXT, $user)) {
             if ($revision->getSha1() != '') {
                 $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40);
             } else {
                 $vals['sha1'] = '';
             }
         }
     }
     if ($this->fld_contentmodel) {
         $vals['contentmodel'] = $revision->getContentModel();
     }
     if ($this->fld_comment || $this->fld_parsedcomment) {
         if ($revision->isDeleted(Revision::DELETED_COMMENT)) {
             $vals['commenthidden'] = true;
             $anyHidden = true;
         }
         if ($revision->userCan(Revision::DELETED_COMMENT, $user)) {
             $comment = $revision->getComment(Revision::RAW);
             if ($this->fld_comment) {
                 $vals['comment'] = $comment;
             }
             if ($this->fld_parsedcomment) {
                 $vals['parsedcomment'] = Linker::formatComment($comment, $title);
             }
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             ApiResult::setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     $content = null;
     global $wgParser;
     if ($this->fetchContent) {
         $content = $revision->getContent(Revision::FOR_THIS_USER, $this->getUser());
         // Expand templates after getting section content because
         // template-added sections don't count and Parser::preprocess()
         // will have less input
         if ($content && $this->section !== false) {
             $content = $content->getSection($this->section, false);
             if (!$content) {
                 $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection');
             }
         }
         if ($revision->isDeleted(Revision::DELETED_TEXT)) {
             $vals['texthidden'] = true;
             $anyHidden = true;
         } elseif (!$content) {
             $vals['textmissing'] = true;
         }
     }
     if ($this->fld_content && $content) {
         $text = null;
         if ($this->generateXML) {
             if ($content->getModel() === CONTENT_MODEL_WIKITEXT) {
                 $t = $content->getNativeData();
                 # note: don't set $text
                 $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), Parser::OT_PREPROCESS);
                 $dom = $wgParser->preprocessToDom($t);
                 if (is_callable(array($dom, 'saveXML'))) {
                     $xml = $dom->saveXML();
                 } else {
                     $xml = $dom->__toString();
                 }
                 $vals['parsetree'] = $xml;
             } else {
                 $vals['badcontentformatforparsetree'] = true;
                 $this->setWarning("Conversion to XML is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel());
             }
         }
         if ($this->expandTemplates && !$this->parseContent) {
             #XXX: implement template expansion for all content types in ContentHandler?
             if ($content->getModel() === CONTENT_MODEL_WIKITEXT) {
                 $text = $content->getNativeData();
                 $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext()));
             } else {
                 $this->setWarning("Template expansion is supported for wikitext only, " . $title->getPrefixedDBkey() . " uses content model " . $content->getModel());
                 $vals['badcontentformat'] = true;
                 $text = false;
             }
         }
         if ($this->parseContent) {
             $po = $content->getParserOutput($title, $revision->getId(), ParserOptions::newFromContext($this->getContext()));
             $text = $po->getText();
         }
         if ($text === null) {
             $format = $this->contentFormat ? $this->contentFormat : $content->getDefaultFormat();
             $model = $content->getModel();
             if (!$content->isSupportedFormat($format)) {
                 $name = $title->getPrefixedDBkey();
                 $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}");
                 $vals['badcontentformat'] = true;
                 $text = false;
             } else {
                 $text = $content->serialize($format);
                 // always include format and model.
                 // Format is needed to deserialize, model is needed to interpret.
                 $vals['contentformat'] = $format;
                 $vals['contentmodel'] = $model;
             }
         }
         if ($text !== false) {
             ApiResult::setContentValue($vals, 'content', $text);
         }
     }
     if ($content && (!is_null($this->diffto) || !is_null($this->difftotext))) {
         static $n = 0;
         // Number of uncached diffs we've had
         if ($n < $this->getConfig()->get('APIMaxUncachedDiffs')) {
             $vals['diff'] = array();
             $context = new DerivativeContext($this->getContext());
             $context->setTitle($title);
             $handler = $revision->getContentHandler();
             if (!is_null($this->difftotext)) {
                 $model = $title->getContentModel();
                 if ($this->contentFormat && !ContentHandler::getForModelID($model)->isSupportedFormat($this->contentFormat)) {
                     $name = $title->getPrefixedDBkey();
                     $this->setWarning("The requested format {$this->contentFormat} is not " . "supported for content model {$model} used by {$name}");
                     $vals['diff']['badcontentformat'] = true;
                     $engine = null;
                 } else {
                     $difftocontent = ContentHandler::makeContent($this->difftotext, $title, $model, $this->contentFormat);
                     $engine = $handler->createDifferenceEngine($context);
                     $engine->setContent($content, $difftocontent);
                 }
             } else {
                 $engine = $handler->createDifferenceEngine($context, $revision->getID(), $this->diffto);
                 $vals['diff']['from'] = $engine->getOldid();
                 $vals['diff']['to'] = $engine->getNewid();
             }
             if ($engine) {
                 $difftext = $engine->getDiffBody();
                 ApiResult::setContentValue($vals['diff'], 'body', $difftext);
                 if (!$engine->wasCacheHit()) {
                     $n++;
                 }
             }
         } else {
             $vals['diff']['notcached'] = true;
         }
     }
     if ($anyHidden && $revision->isDeleted(Revision::DELETED_RESTRICTED)) {
         $vals['suppressed'] = true;
     }
     return $vals;
 }
 /**
  * Generates a form from the given request.
  * @param AuthenticationRequest[] $requests
  * @param string $action AuthManager action name
  * @param string|Message $msg
  * @param string $msgType
  * @return HTMLForm
  */
 protected function getAuthForm(array $requests, $action, $msg = '', $msgType = 'error')
 {
     global $wgSecureLogin, $wgLoginLanguageSelector;
     // FIXME merge this with parent
     if (isset($this->authForm)) {
         return $this->authForm;
     }
     $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
     // get basic form description from the auth logic
     $fieldInfo = AuthenticationRequest::mergeFieldInfo($requests);
     $fakeTemplate = $this->getFakeTemplate($msg, $msgType);
     $this->fakeTemplate = $fakeTemplate;
     // FIXME there should be a saner way to pass this to the hook
     // this will call onAuthChangeFormFields()
     $formDescriptor = static::fieldInfoToFormDescriptor($requests, $fieldInfo, $this->authAction);
     $this->postProcessFormDescriptor($formDescriptor);
     $context = $this->getContext();
     if ($context->getRequest() !== $this->getRequest()) {
         // We have overridden the request, need to make sure the form uses that too.
         $context = new DerivativeContext($this->getContext());
         $context->setRequest($this->getRequest());
     }
     $form = HTMLForm::factory('vform', $formDescriptor, $context);
     $form->addHiddenField('authAction', $this->authAction);
     if ($wgLoginLanguageSelector) {
         $form->addHiddenField('uselang', $this->mLanguage);
     }
     $form->addHiddenField('force', $this->securityLevel);
     $form->addHiddenField($this->getTokenName(), $this->getToken()->toString());
     if ($wgSecureLogin) {
         // If using HTTPS coming from HTTP, then the 'fromhttp' parameter must be preserved
         if (!$this->isSignup()) {
             $form->addHiddenField('wpForceHttps', (int) $this->mStickHTTPS);
             $form->addHiddenField('wpFromhttp', $usingHTTPS);
         }
     }
     // set properties of the form itself
     $form->setAction($this->getPageTitle()->getLocalURL($this->getReturnToQueryStringFragment()));
     $form->setName('userlogin' . ($this->isSignup() ? '2' : ''));
     if ($this->isSignup()) {
         $form->setId('userlogin2');
     }
     // add pre/post text
     // header used by ConfirmEdit, CondfirmAccount, Persona, WikimediaIncubator, SemanticSignup
     // should be above the error message but HTMLForm doesn't support that
     $form->addHeaderText($fakeTemplate->html('header'));
     // FIXME the old form used this for error/warning messages which does not play well with
     // HTMLForm (maybe it could with a subclass?); for now only display it for signups
     // (where the JS username validation needs it) and alway empty
     if ($this->isSignup()) {
         // used by the mediawiki.special.userlogin.signup.js module
         $statusAreaAttribs = ['id' => 'mw-createacct-status-area'];
         // $statusAreaAttribs += $msg ? [ 'class' => "{$msgType}box" ] : [ 'style' => 'display: none;' ];
         $form->addHeaderText(Html::element('div', $statusAreaAttribs));
     }
     // header used by MobileFrontend
     $form->addHeaderText($fakeTemplate->html('formheader'));
     // blank signup footer for site customization
     if ($this->isSignup() && $this->showExtraInformation()) {
         // Use signupend-https for HTTPS requests if it's not blank, signupend otherwise
         $signupendMsg = $this->msg('signupend');
         $signupendHttpsMsg = $this->msg('signupend-https');
         if (!$signupendMsg->isDisabled()) {
             $signupendText = $usingHTTPS && !$signupendHttpsMsg->isBlank() ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
             $form->addPostText(Html::rawElement('div', ['id' => 'signupend'], $signupendText));
         }
     }
     // warning header for non-standard workflows (e.g. security reauthentication)
     if (!$this->isSignup() && $this->getUser()->isLoggedIn()) {
         $reauthMessage = $this->securityLevel ? 'userlogin-reauth' : 'userlogin-loggedin';
         $form->addHeaderText(Html::rawElement('div', ['class' => 'warningbox'], $this->msg($reauthMessage)->params($this->getUser()->getName())->parse()));
     }
     if (!$this->isSignup() && $this->showExtraInformation()) {
         $passwordReset = new PasswordReset($this->getConfig(), AuthManager::singleton());
         if ($passwordReset->isAllowed($this->getUser())) {
             $form->addFooterText(Html::rawElement('div', ['class' => 'mw-ui-vform-field mw-form-related-link-container'], Linker::link(SpecialPage::getTitleFor('PasswordReset'), $this->msg('userlogin-resetpassword-link')->escaped())));
         }
         // Don't show a "create account" link if the user can't.
         if ($this->showCreateAccountLink()) {
             // link to the other action
             $linkTitle = $this->getTitleFor($this->isSignup() ? 'Userlogin' : 'CreateAccount');
             $linkq = $this->getReturnToQueryStringFragment();
             // Pass any language selection on to the mode switch link
             if ($wgLoginLanguageSelector && $this->mLanguage) {
                 $linkq .= '&uselang=' . $this->mLanguage;
             }
             $createOrLoginHref = $linkTitle->getLocalURL($linkq);
             if ($this->getUser()->isLoggedIn()) {
                 $createOrLoginHtml = Html::rawElement('div', ['class' => 'mw-ui-vform-field'], Html::element('a', ['id' => 'mw-createaccount-join', 'href' => $createOrLoginHref, 'tabindex' => 100], $this->msg('userlogin-createanother')->escaped()));
             } else {
                 $createOrLoginHtml = Html::rawElement('div', ['id' => 'mw-createaccount-cta', 'class' => 'mw-ui-vform-field'], $this->msg('userlogin-noaccount')->escaped() . Html::element('a', ['id' => 'mw-createaccount-join', 'href' => $createOrLoginHref, 'class' => 'mw-ui-button', 'tabindex' => 100], $this->msg('userlogin-joinproject')->escaped()));
             }
             $form->addFooterText($createOrLoginHtml);
         }
     }
     $form->suppressDefaultSubmit();
     $this->authForm = $form;
     return $form;
 }
Example #19
0
 public function execute($par)
 {
     $out = $this->getOutput();
     $out->addModuleStyles('mediawiki.special');
     $this->mTarget = is_null($par) ? $this->getRequest()->getVal('wpTarget', $this->getRequest()->getVal('target', '')) : $par;
     // This needs to be below assignment of $this->mTarget because
     // getDescription() needs it to determine the correct page title.
     $this->setHeaders();
     $this->outputHeader();
     // error out if sending user cannot do this
     $error = self::getPermissionsError($this->getUser(), $this->getRequest()->getVal('wpEditToken'), $this->getConfig());
     switch ($error) {
         case null:
             # Wahey!
             break;
         case 'badaccess':
             throw new PermissionsError('sendemail');
         case 'blockedemailuser':
             throw new UserBlockedError($this->getUser()->mBlock);
         case 'actionthrottledtext':
             throw new ThrottledError();
         case 'mailnologin':
         case 'usermaildisabled':
             throw new ErrorPageError($error, "{$error}text");
         default:
             # It's a hook error
             list($title, $msg, $params) = $error;
             throw new ErrorPageError($title, $msg, $params);
     }
     // Got a valid target user name? Else ask for one.
     $ret = self::getTarget($this->mTarget);
     if (!$ret instanceof User) {
         if ($this->mTarget != '') {
             // Messages used here: notargettext, noemailtext, nowikiemailtext
             $ret = $ret == 'notarget' ? 'emailnotarget' : $ret . 'text';
             $out->wrapWikiMsg("<p class='error'>\$1</p>", $ret);
         }
         $out->addHTML($this->userForm($this->mTarget));
         return;
     }
     $this->mTargetObj = $ret;
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle());
     // Remove subpage
     $form = new HTMLForm($this->getFormFields(), $context);
     // By now we are supposed to be sure that $this->mTarget is a user name
     $form->addPreText($this->msg('emailpagetext', $this->mTarget)->parse());
     $form->setSubmitTextMsg('emailsend');
     $form->setSubmitCallback(array(__CLASS__, 'uiSubmit'));
     $form->setWrapperLegendMsg('email-legend');
     $form->loadData();
     if (!Hooks::run('EmailUserForm', array(&$form))) {
         return;
     }
     $result = $form->show();
     if ($result === true || $result instanceof Status && $result->isGood()) {
         $out->setPageTitle($this->msg('emailsent'));
         $out->addWikiMsg('emailsenttext', $this->mTarget);
         $out->returnToMain(false, $this->mTargetObj->getUserPage());
     }
 }
Example #20
0
 private function extractRowInfo($row)
 {
     $revision = new Revision($row);
     $title = $revision->getTitle();
     $vals = array();
     if ($this->fld_ids) {
         $vals['revid'] = intval($revision->getId());
         // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed?
         if (!is_null($revision->getParentId())) {
             $vals['parentid'] = intval($revision->getParentId());
         }
     }
     if ($this->fld_flags && $revision->isMinor()) {
         $vals['minor'] = '';
     }
     if ($this->fld_user || $this->fld_userid) {
         if ($revision->isDeleted(Revision::DELETED_USER)) {
             $vals['userhidden'] = '';
         } else {
             if ($this->fld_user) {
                 $vals['user'] = $revision->getUserText();
             }
             $userid = $revision->getUser();
             if (!$userid) {
                 $vals['anon'] = '';
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $userid;
             }
         }
     }
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp());
     }
     if ($this->fld_size) {
         if (!is_null($revision->getSize())) {
             $vals['size'] = intval($revision->getSize());
         } else {
             $vals['size'] = 0;
         }
     }
     if ($this->fld_sha1) {
         if ($revision->getSha1() != '') {
             $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40);
         } else {
             $vals['sha1'] = '';
         }
     }
     if ($this->fld_comment || $this->fld_parsedcomment) {
         if ($revision->isDeleted(Revision::DELETED_COMMENT)) {
             $vals['commenthidden'] = '';
         } else {
             $comment = $revision->getComment();
             if ($this->fld_comment) {
                 $vals['comment'] = $comment;
             }
             if ($this->fld_parsedcomment) {
                 $vals['parsedcomment'] = Linker::formatComment($comment, $title);
             }
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             $this->getResult()->setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     if (!is_null($this->token)) {
         $tokenFunctions = $this->getTokenFunctions();
         foreach ($this->token as $t) {
             $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision);
             if ($val === false) {
                 $this->setWarning("Action '{$t}' is not allowed for the current user");
             } else {
                 $vals[$t . 'token'] = $val;
             }
         }
     }
     $text = null;
     global $wgParser;
     if ($this->fld_content || !is_null($this->difftotext)) {
         $text = $revision->getText();
         // Expand templates after getting section content because
         // template-added sections don't count and Parser::preprocess()
         // will have less input
         if ($this->section !== false) {
             $text = $wgParser->getSection($text, $this->section, false);
             if ($text === false) {
                 $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection');
             }
         }
     }
     if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) {
         if ($this->generateXML) {
             $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS);
             $dom = $wgParser->preprocessToDom($text);
             if (is_callable(array($dom, 'saveXML'))) {
                 $xml = $dom->saveXML();
             } else {
                 $xml = $dom->__toString();
             }
             $vals['parsetree'] = $xml;
         }
         if ($this->expandTemplates && !$this->parseContent) {
             $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext()));
         }
         if ($this->parseContent) {
             $text = $wgParser->parse($text, $title, ParserOptions::newFromContext($this->getContext()))->getText();
         }
         ApiResult::setContent($vals, $text);
     } elseif ($this->fld_content) {
         $vals['texthidden'] = '';
     }
     if (!is_null($this->diffto) || !is_null($this->difftotext)) {
         global $wgAPIMaxUncachedDiffs;
         static $n = 0;
         // Number of uncached diffs we've had
         if ($n < $wgAPIMaxUncachedDiffs) {
             $vals['diff'] = array();
             $context = new DerivativeContext($this->getContext());
             $context->setTitle($title);
             if (!is_null($this->difftotext)) {
                 $engine = new DifferenceEngine($context);
                 $engine->setText($text, $this->difftotext);
             } else {
                 $engine = new DifferenceEngine($context, $revision->getID(), $this->diffto);
                 $vals['diff']['from'] = $engine->getOldid();
                 $vals['diff']['to'] = $engine->getNewid();
             }
             $difftext = $engine->getDiffBody();
             ApiResult::setContent($vals['diff'], $difftext);
             if (!$engine->wasCacheHit()) {
                 $n++;
             }
         } else {
             $vals['diff']['notcached'] = '';
         }
     }
     return $vals;
 }
Example #21
0
 public function execute()
 {
     // The data is hot but user-dependent, like page views, so we set vary cookies
     $this->getMain()->setCacheMode('anon-public-user-private');
     // Get parameters
     $params = $this->extractRequestParams();
     $text = $params['text'];
     $title = $params['title'];
     if ($title === null) {
         $titleProvided = false;
         // A title is needed for parsing, so arbitrarily choose one
         $title = 'API';
     } else {
         $titleProvided = true;
     }
     $page = $params['page'];
     $pageid = $params['pageid'];
     $oldid = $params['oldid'];
     $model = $params['contentmodel'];
     $format = $params['contentformat'];
     if (!is_null($page) && (!is_null($text) || $titleProvided)) {
         $this->dieUsage('The page parameter cannot be used together with the text and title parameters', 'params');
     }
     $prop = array_flip($params['prop']);
     if (isset($params['section'])) {
         $this->section = $params['section'];
         if (!preg_match('/^((T-)?\\d+|new)$/', $this->section)) {
             $this->dieUsage('The section parameter must be a valid section id or "new"', 'invalidsection');
         }
     } else {
         $this->section = false;
     }
     // The parser needs $wgTitle to be set, apparently the
     // $title parameter in Parser::parse isn't enough *sigh*
     // TODO: Does this still need $wgTitle?
     global $wgParser, $wgTitle;
     $redirValues = null;
     // Return result
     $result = $this->getResult();
     if (!is_null($oldid) || !is_null($pageid) || !is_null($page)) {
         if ($this->section === 'new') {
             $this->dieUsage('section=new cannot be combined with oldid, pageid or page parameters. ' . 'Please use text', 'params');
         }
         if (!is_null($oldid)) {
             // Don't use the parser cache
             $rev = Revision::newFromId($oldid);
             if (!$rev) {
                 $this->dieUsage("There is no revision ID {$oldid}", 'missingrev');
             }
             $this->checkReadPermissions($rev->getTitle());
             if (!$rev->userCan(Revision::DELETED_TEXT, $this->getUser())) {
                 $this->dieUsage("You don't have permission to view deleted revisions", 'permissiondenied');
             }
             $titleObj = $rev->getTitle();
             $wgTitle = $titleObj;
             $pageObj = WikiPage::factory($titleObj);
             list($popts, $reset, $suppressCache) = $this->makeParserOptions($pageObj, $params);
             // If for some reason the "oldid" is actually the current revision, it may be cached
             // Deliberately comparing $pageObj->getLatest() with $rev->getId(), rather than
             // checking $rev->isCurrent(), because $pageObj is what actually ends up being used,
             // and if its ->getLatest() is outdated, $rev->isCurrent() won't tell us that.
             if (!$suppressCache && $rev->getId() == $pageObj->getLatest()) {
                 // May get from/save to parser cache
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             } else {
                 // This is an old revision, so get the text differently
                 $this->content = $rev->getContent(Revision::FOR_THIS_USER, $this->getUser());
                 if ($this->section !== false) {
                     $this->content = $this->getSectionContent($this->content, 'r' . $rev->getId());
                 }
                 // Should we save old revision parses to the parser cache?
                 $p_result = $this->content->getParserOutput($titleObj, $rev->getId(), $popts);
             }
         } else {
             // Not $oldid, but $pageid or $page
             if ($params['redirects']) {
                 $reqParams = ['redirects' => ''];
                 if (!is_null($pageid)) {
                     $reqParams['pageids'] = $pageid;
                 } else {
                     // $page
                     $reqParams['titles'] = $page;
                 }
                 $req = new FauxRequest($reqParams);
                 $main = new ApiMain($req);
                 $pageSet = new ApiPageSet($main);
                 $pageSet->execute();
                 $redirValues = $pageSet->getRedirectTitlesAsResult($this->getResult());
                 $to = $page;
                 foreach ($pageSet->getRedirectTitles() as $title) {
                     $to = $title->getFullText();
                 }
                 $pageParams = ['title' => $to];
             } elseif (!is_null($pageid)) {
                 $pageParams = ['pageid' => $pageid];
             } else {
                 // $page
                 $pageParams = ['title' => $page];
             }
             $pageObj = $this->getTitleOrPageId($pageParams, 'fromdb');
             $titleObj = $pageObj->getTitle();
             if (!$titleObj || !$titleObj->exists()) {
                 $this->dieUsage("The page you specified doesn't exist", 'missingtitle');
             }
             $this->checkReadPermissions($titleObj);
             $wgTitle = $titleObj;
             if (isset($prop['revid'])) {
                 $oldid = $pageObj->getLatest();
             }
             list($popts, $reset, $suppressCache) = $this->makeParserOptions($pageObj, $params);
             // Don't pollute the parser cache when setting options that aren't
             // in ParserOptions::optionsHash()
             /// @todo: This should be handled closer to the actual cache instead of here, see T110269
             $suppressCache = $suppressCache || $params['disablepp'] || $params['disablelimitreport'] || $params['preview'] || $params['sectionpreview'] || $params['disabletidy'];
             if ($suppressCache) {
                 $this->content = $this->getContent($pageObj, $pageid);
                 $p_result = $this->content->getParserOutput($titleObj, null, $popts);
             } else {
                 // Potentially cached
                 $p_result = $this->getParsedContent($pageObj, $popts, $pageid, isset($prop['wikitext']));
             }
         }
     } else {
         // Not $oldid, $pageid, $page. Hence based on $text
         $titleObj = Title::newFromText($title);
         if (!$titleObj || $titleObj->isExternal()) {
             $this->dieUsageMsg(['invalidtitle', $title]);
         }
         $wgTitle = $titleObj;
         if ($titleObj->canExist()) {
             $pageObj = WikiPage::factory($titleObj);
         } else {
             // Do like MediaWiki::initializeArticle()
             $article = Article::newFromTitle($titleObj, $this->getContext());
             $pageObj = $article->getPage();
         }
         list($popts, $reset) = $this->makeParserOptions($pageObj, $params);
         $textProvided = !is_null($text);
         if (!$textProvided) {
             if ($titleProvided && ($prop || $params['generatexml'])) {
                 $this->setWarning("'title' used without 'text', and parsed page properties were requested " . "(did you mean to use 'page' instead of 'title'?)");
             }
             // Prevent warning from ContentHandler::makeContent()
             $text = '';
         }
         // If we are parsing text, do not use the content model of the default
         // API title, but default to wikitext to keep BC.
         if ($textProvided && !$titleProvided && is_null($model)) {
             $model = CONTENT_MODEL_WIKITEXT;
             $this->setWarning("No 'title' or 'contentmodel' was given, assuming {$model}.");
         }
         try {
             $this->content = ContentHandler::makeContent($text, $titleObj, $model, $format);
         } catch (MWContentSerializationException $ex) {
             $this->dieUsage($ex->getMessage(), 'parseerror');
         }
         if ($this->section !== false) {
             if ($this->section === 'new') {
                 // Insert the section title above the content.
                 if (!is_null($params['sectiontitle']) && $params['sectiontitle'] !== '') {
                     $this->content = $this->content->addSectionHeader($params['sectiontitle']);
                 }
             } else {
                 $this->content = $this->getSectionContent($this->content, $titleObj->getPrefixedText());
             }
         }
         if ($params['pst'] || $params['onlypst']) {
             $this->pstContent = $this->content->preSaveTransform($titleObj, $this->getUser(), $popts);
         }
         if ($params['onlypst']) {
             // Build a result and bail out
             $result_array = [];
             $result_array['text'] = $this->pstContent->serialize($format);
             $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
             if (isset($prop['wikitext'])) {
                 $result_array['wikitext'] = $this->content->serialize($format);
                 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
             }
             if (!is_null($params['summary']) || !is_null($params['sectiontitle']) && $this->section === 'new') {
                 $result_array['parsedsummary'] = $this->formatSummary($titleObj, $params);
                 $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
             }
             $result->addValue(null, $this->getModuleName(), $result_array);
             return;
         }
         // Not cached (save or load)
         if ($params['pst']) {
             $p_result = $this->pstContent->getParserOutput($titleObj, null, $popts);
         } else {
             $p_result = $this->content->getParserOutput($titleObj, null, $popts);
         }
     }
     $result_array = [];
     $result_array['title'] = $titleObj->getPrefixedText();
     $result_array['pageid'] = $pageid ?: $pageObj->getId();
     if (!is_null($oldid)) {
         $result_array['revid'] = intval($oldid);
     }
     if ($params['redirects'] && !is_null($redirValues)) {
         $result_array['redirects'] = $redirValues;
     }
     if ($params['disabletoc']) {
         $p_result->setTOCEnabled(false);
     }
     if (isset($prop['text'])) {
         $result_array['text'] = $p_result->getText();
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'text';
     }
     if (!is_null($params['summary']) || !is_null($params['sectiontitle']) && $this->section === 'new') {
         $result_array['parsedsummary'] = $this->formatSummary($titleObj, $params);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsedsummary';
     }
     if (isset($prop['langlinks'])) {
         $langlinks = $p_result->getLanguageLinks();
         if ($params['effectivelanglinks']) {
             // Link flags are ignored for now, but may in the future be
             // included in the result.
             $linkFlags = [];
             Hooks::run('LanguageLinks', [$titleObj, &$langlinks, &$linkFlags]);
         }
     } else {
         $langlinks = false;
     }
     if (isset($prop['langlinks'])) {
         $result_array['langlinks'] = $this->formatLangLinks($langlinks);
     }
     if (isset($prop['categories'])) {
         $result_array['categories'] = $this->formatCategoryLinks($p_result->getCategories());
     }
     if (isset($prop['categorieshtml'])) {
         $result_array['categorieshtml'] = $this->categoriesHtml($p_result->getCategories());
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'categorieshtml';
     }
     if (isset($prop['links'])) {
         $result_array['links'] = $this->formatLinks($p_result->getLinks());
     }
     if (isset($prop['templates'])) {
         $result_array['templates'] = $this->formatLinks($p_result->getTemplates());
     }
     if (isset($prop['images'])) {
         $result_array['images'] = array_keys($p_result->getImages());
     }
     if (isset($prop['externallinks'])) {
         $result_array['externallinks'] = array_keys($p_result->getExternalLinks());
     }
     if (isset($prop['sections'])) {
         $result_array['sections'] = $p_result->getSections();
     }
     if (isset($prop['displaytitle'])) {
         $result_array['displaytitle'] = $p_result->getDisplayTitle() ?: $titleObj->getPrefixedText();
     }
     if (isset($prop['headitems'])) {
         $result_array['headitems'] = $this->formatHeadItems($p_result->getHeadItems());
         $this->logFeatureUsage('action=parse&prop=headitems');
         $this->setWarning('headitems is deprecated since MediaWiki 1.28. ' . 'Use prop=headhtml when creating new HTML documents, or ' . 'prop=modules|jsconfigvars when updating a document client-side.');
     }
     if (isset($prop['headhtml'])) {
         $context = new DerivativeContext($this->getContext());
         $context->setTitle($titleObj);
         $context->setWikiPage($pageObj);
         // We need an OutputPage tied to $context, not to the
         // RequestContext at the root of the stack.
         $output = new OutputPage($context);
         $output->addParserOutputMetadata($p_result);
         $result_array['headhtml'] = $output->headElement($context->getSkin());
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'headhtml';
     }
     if (isset($prop['modules'])) {
         $result_array['modules'] = array_values(array_unique($p_result->getModules()));
         $result_array['modulescripts'] = array_values(array_unique($p_result->getModuleScripts()));
         $result_array['modulestyles'] = array_values(array_unique($p_result->getModuleStyles()));
     }
     if (isset($prop['jsconfigvars'])) {
         $result_array['jsconfigvars'] = ApiResult::addMetadataToResultVars($p_result->getJsConfigVars());
     }
     if (isset($prop['encodedjsconfigvars'])) {
         $result_array['encodedjsconfigvars'] = FormatJson::encode($p_result->getJsConfigVars(), false, FormatJson::ALL_OK);
         $result_array[ApiResult::META_SUBELEMENTS][] = 'encodedjsconfigvars';
     }
     if (isset($prop['modules']) && !isset($prop['jsconfigvars']) && !isset($prop['encodedjsconfigvars'])) {
         $this->setWarning('Property "modules" was set but not "jsconfigvars" ' . 'or "encodedjsconfigvars". Configuration variables are necessary ' . 'for proper module usage.');
     }
     if (isset($prop['indicators'])) {
         $result_array['indicators'] = (array) $p_result->getIndicators();
         ApiResult::setArrayType($result_array['indicators'], 'BCkvp', 'name');
     }
     if (isset($prop['iwlinks'])) {
         $result_array['iwlinks'] = $this->formatIWLinks($p_result->getInterwikiLinks());
     }
     if (isset($prop['wikitext'])) {
         $result_array['wikitext'] = $this->content->serialize($format);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'wikitext';
         if (!is_null($this->pstContent)) {
             $result_array['psttext'] = $this->pstContent->serialize($format);
             $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'psttext';
         }
     }
     if (isset($prop['properties'])) {
         $result_array['properties'] = (array) $p_result->getProperties();
         ApiResult::setArrayType($result_array['properties'], 'BCkvp', 'name');
     }
     if (isset($prop['limitreportdata'])) {
         $result_array['limitreportdata'] = $this->formatLimitReportData($p_result->getLimitReportData());
     }
     if (isset($prop['limitreporthtml'])) {
         $result_array['limitreporthtml'] = EditPage::getPreviewLimitReport($p_result);
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'limitreporthtml';
     }
     if (isset($prop['parsetree']) || $params['generatexml']) {
         if ($this->content->getModel() != CONTENT_MODEL_WIKITEXT) {
             $this->dieUsage('parsetree is only supported for wikitext content', 'notwikitext');
         }
         $wgParser->startExternalParse($titleObj, $popts, Parser::OT_PREPROCESS);
         $dom = $wgParser->preprocessToDom($this->content->getNativeData());
         if (is_callable([$dom, 'saveXML'])) {
             $xml = $dom->saveXML();
         } else {
             $xml = $dom->__toString();
         }
         $result_array['parsetree'] = $xml;
         $result_array[ApiResult::META_BC_SUBELEMENTS][] = 'parsetree';
     }
     $result_mapping = ['redirects' => 'r', 'langlinks' => 'll', 'categories' => 'cl', 'links' => 'pl', 'templates' => 'tl', 'images' => 'img', 'externallinks' => 'el', 'iwlinks' => 'iw', 'sections' => 's', 'headitems' => 'hi', 'modules' => 'm', 'indicators' => 'ind', 'modulescripts' => 'm', 'modulestyles' => 'm', 'properties' => 'pp', 'limitreportdata' => 'lr'];
     $this->setIndexedTagNames($result_array, $result_mapping);
     $result->addValue(null, $this->getModuleName(), $result_array);
 }
 /**
  * Show the Special:ChangePassword form, with custom message
  * @param Message $msg
  */
 protected function resetLoginForm(Message $msg)
 {
     // Allow hooks to explain this password reset in more detail
     Hooks::run('LoginPasswordResetMessage', array(&$msg, $this->mUsername));
     $reset = new SpecialChangePassword();
     $derivative = new DerivativeContext($this->getContext());
     $derivative->setTitle($reset->getPageTitle());
     $reset->setContext($derivative);
     if (!$this->mTempPasswordUsed) {
         $reset->setOldPasswordMessage('oldpassword');
     }
     $reset->setChangeMessage($msg);
     $reset->execute(null);
 }
Example #23
0
 /**
  * Parse a 'continue' parameter and return status information.
  *
  * This must be balanced by a call to endContinuation().
  *
  * @since 1.24
  * @deprecated since 1.25, use ApiContinuationManager instead
  * @param string|null $continue
  * @param ApiBase[] $allModules
  * @param array $generatedModules
  * @return array
  */
 public function beginContinuation($continue, array $allModules = array(), array $generatedModules = array())
 {
     wfDeprecated(__METHOD__, '1.25');
     if ($this->mainForContinuation->getContinuationManager()) {
         throw new UnexpectedValueException(__METHOD__ . ': Continuation already in progress from ' . $this->mainForContinuation->getContinuationManager()->getSource());
     }
     // Ugh. If $continue doesn't match that in the request, temporarily
     // replace the request when creating the ApiContinuationManager.
     if ($continue === null) {
         $continue = '';
     }
     if ($this->mainForContinuation->getVal('continue', '') !== $continue) {
         $oldCtx = $this->mainForContinuation->getContext();
         $newCtx = new DerivativeContext($oldCtx);
         $newCtx->setRequest(new DerivativeRequest($oldCtx->getRequest(), array('continue' => $continue) + $oldCtx->getRequest()->getValues(), $oldCtx->getRequest()->wasPosted()));
         $this->mainForContinuation->setContext($newCtx);
         $reset = new ScopedCallback(array($this->mainForContinuation, 'setContext'), array($oldCtx));
     }
     $manager = new ApiContinuationManager($this->mainForContinuation, $allModules, $generatedModules);
     $reset = null;
     $this->mainForContinuation->setContinuationManager($manager);
     return array($manager->isGeneratorDone(), $manager->getRunModules());
 }
Example #24
0
 /**
  * Get an UploadForm instance with title and text properly set.
  *
  * @param string $message HTML string to add to the form
  * @param string $sessionKey Session key in case this is a stashed upload
  * @param bool $hideIgnoreWarning Whether to hide "ignore warning" check box
  * @return UploadForm
  */
 protected function getUploadForm($message = '', $sessionKey = '', $hideIgnoreWarning = false)
 {
     # Initialize form
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle());
     // Remove subpage
     $form = new UploadForm(array('watch' => $this->getWatchCheck(), 'forreupload' => $this->mForReUpload, 'sessionkey' => $sessionKey, 'hideignorewarning' => $hideIgnoreWarning, 'destwarningack' => (bool) $this->mDestWarningAck, 'description' => $this->mComment, 'texttop' => $this->uploadFormTextTop, 'textaftersummary' => $this->uploadFormTextAfterSummary, 'destfile' => $this->mDesiredDestName), $context);
     # Check the token, but only if necessary
     if (!$this->mTokenOk && !$this->mCancelUpload && ($this->mUpload && $this->mUploadClicked)) {
         $form->addPreText($this->msg('session_fail_preview')->parse());
     }
     # Give a notice if the user is uploading a file that has been deleted or moved
     # Note that this is independent from the message 'filewasdeleted' that requires JS
     $desiredTitleObj = Title::makeTitleSafe(NS_FILE, $this->mDesiredDestName);
     $delNotice = '';
     // empty by default
     if ($desiredTitleObj instanceof Title && !$desiredTitleObj->exists()) {
         LogEventsList::showLogExtract($delNotice, array('delete', 'move'), $desiredTitleObj, '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('upload-recreate-warning')));
     }
     $form->addPreText($delNotice);
     # Add text to form
     $form->addPreText('<div id="uploadtext">' . $this->msg('uploadtext', array($this->mDesiredDestName))->parseAsBlock() . '</div>');
     # Add upload error message
     $form->addPreText($message);
     # Add footer to form
     $uploadFooter = $this->msg('uploadfooter');
     if (!$uploadFooter->isDisabled()) {
         $form->addPostText('<div id="mw-upload-footer-message">' . $uploadFooter->parseAsBlock() . "</div>\n");
     }
     return $form;
 }
 /**
  * Get a form for clearing the watchlist
  *
  * @return HTMLForm
  */
 protected function getClearForm()
 {
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getPageTitle('clear'));
     // Reset subpage
     $form = new HTMLForm(array(), $context);
     $form->setSubmitTextMsg('watchlistedit-clear-submit');
     # Used message keys: 'accesskey-watchlistedit-clear-submit', 'tooltip-watchlistedit-clear-submit'
     $form->setSubmitTooltip('watchlistedit-clear-submit');
     $form->setWrapperLegendMsg('watchlistedit-clear-legend');
     $form->addHeaderText($this->msg('watchlistedit-clear-explain')->parse());
     $form->setSubmitCallback(array($this, 'submitClear'));
     $form->setSubmitDestructive();
     return $form;
 }
Example #26
0
 /**
  * Flatten an array, using the content language for any messages.
  *
  * @param array $vals Array of values
  * @param string $type Type of array (either lang, ul, ol).
  *   lang = language assoc array with keys being the lang code
  *   ul = unordered list, ol = ordered list
  *   type can also come from the '_type' member of $vals.
  * @param bool $noHtml If to avoid returning anything resembling HTML.
  *   (Ugly hack for backwards compatibility with old MediaWiki).
  * @param bool|IContextSource $context
  * @return string Single value (in wiki-syntax).
  * @since 1.23
  */
 public static function flattenArrayContentLang($vals, $type = 'ul', $noHtml = false, $context = false)
 {
     global $wgContLang;
     $obj = new FormatMetadata();
     if ($context) {
         $obj->setContext($context);
     }
     $context = new DerivativeContext($obj->getContext());
     $context->setLanguage($wgContLang);
     $obj->setContext($context);
     return $obj->flattenArrayReal($vals, $type, $noHtml);
 }
Example #27
0
 function getForm()
 {
     $fields = array('like' => array('type' => 'text', 'label-message' => 'newimages-label', 'name' => 'like'), 'showbots' => array('type' => 'check', 'label-message' => 'newimages-showbots', 'name' => 'showbots'), 'limit' => array('type' => 'hidden', 'default' => $this->mLimit, 'name' => 'limit'), 'offset' => array('type' => 'hidden', 'default' => $this->getRequest()->getText('offset'), 'name' => 'offset'));
     if ($this->getConfig()->get('MiserMode')) {
         unset($fields['like']);
     }
     $context = new DerivativeContext($this->getContext());
     $context->setTitle($this->getTitle());
     // Remove subpage
     $form = new HTMLForm($fields, $context);
     $form->setSubmitTextMsg('ilsubmit');
     $form->setMethod('get');
     $form->setWrapperLegendMsg('newimages-legend');
     return $form;
 }
 /**
  * @param AuthenticationRequest[] $requests
  * @param string $action AuthManager action name (one of the AuthManager::ACTION_* constants)
  * @return HTMLForm
  */
 protected function getAuthForm(array $requests, $action)
 {
     $formDescriptor = $this->getAuthFormDescriptor($requests, $action);
     $context = $this->getContext();
     if ($context->getRequest() !== $this->getRequest()) {
         // We have overridden the request, need to make sure the form uses that too.
         $context = new DerivativeContext($this->getContext());
         $context->setRequest($this->getRequest());
     }
     $form = HTMLForm::factory('ooui', $formDescriptor, $context);
     $form->setAction($this->getFullTitle()->getFullURL($this->getPreservedParams()));
     $form->addHiddenField($this->getTokenName(), $this->getToken()->toString());
     $form->addHiddenField('authAction', $this->authAction);
     $form->suppressDefaultSubmit(!$this->needsSubmitButton($formDescriptor));
     return $form;
 }
Example #29
0
 /**
  * Executes the log-in attempt using the parameters passed. If
  * the log-in succeeeds, it attaches a cookie to the session
  * and outputs the user id, username, and session token. If a
  * log-in fails, as the result of a bad password, a nonexistent
  * user, or any other reason, the host is cached with an expiry
  * and no log-in attempts will be accepted until that expiry
  * is reached. The expiry is $this->mLoginThrottle.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $result = array();
     // Init session if necessary
     if (session_id() == '') {
         wfSetupSession();
     }
     $context = new DerivativeContext($this->getContext());
     $context->setRequest(new DerivativeRequest($this->getContext()->getRequest(), array('wpName' => $params['name'], 'wpPassword' => $params['password'], 'wpDomain' => $params['domain'], 'wpLoginToken' => $params['token'], 'wpRemember' => '')));
     $loginForm = new LoginForm();
     $loginForm->setContext($context);
     global $wgCookiePrefix, $wgPasswordAttemptThrottle;
     $authRes = $loginForm->authenticateUserData();
     switch ($authRes) {
         case LoginForm::SUCCESS:
             $user = $context->getUser();
             $this->getContext()->setUser($user);
             $user->setOption('rememberpassword', 1);
             $user->setCookies($this->getRequest());
             ApiQueryInfo::resetTokenCache();
             // Run hooks.
             // @todo FIXME: Split back and frontend from this hook.
             // @todo FIXME: This hook should be placed in the backend
             $injected_html = '';
             wfRunHooks('UserLoginComplete', array(&$user, &$injected_html));
             $result['result'] = 'Success';
             $result['lguserid'] = intval($user->getId());
             $result['lgusername'] = $user->getName();
             $result['lgtoken'] = $user->getToken();
             $result['cookieprefix'] = $wgCookiePrefix;
             $result['sessionid'] = session_id();
             break;
         case LoginForm::NEED_TOKEN:
             $result['result'] = 'NeedToken';
             $result['token'] = $loginForm->getLoginToken();
             $result['cookieprefix'] = $wgCookiePrefix;
             $result['sessionid'] = session_id();
             break;
         case LoginForm::WRONG_TOKEN:
             $result['result'] = 'WrongToken';
             break;
         case LoginForm::NO_NAME:
             $result['result'] = 'NoName';
             break;
         case LoginForm::ILLEGAL:
             $result['result'] = 'Illegal';
             break;
         case LoginForm::WRONG_PLUGIN_PASS:
             $result['result'] = 'WrongPluginPass';
             break;
         case LoginForm::NOT_EXISTS:
             $result['result'] = 'NotExists';
             break;
         case LoginForm::RESET_PASS:
             // bug 20223 - Treat a temporary password as wrong. Per SpecialUserLogin - "The e-mailed temporary password should not be used for actual logins;"
         // bug 20223 - Treat a temporary password as wrong. Per SpecialUserLogin - "The e-mailed temporary password should not be used for actual logins;"
         case LoginForm::WRONG_PASS:
             $result['result'] = 'WrongPass';
             break;
         case LoginForm::EMPTY_PASS:
             $result['result'] = 'EmptyPass';
             break;
         case LoginForm::CREATE_BLOCKED:
             $result['result'] = 'CreateBlocked';
             $result['details'] = 'Your IP address is blocked from account creation';
             break;
         case LoginForm::THROTTLED:
             $result['result'] = 'Throttled';
             $result['wait'] = intval($wgPasswordAttemptThrottle['seconds']);
             break;
         case LoginForm::USER_BLOCKED:
             $result['result'] = 'Blocked';
             break;
         case LoginForm::ABORTED:
             $result['result'] = 'Aborted';
             $result['reason'] = $loginForm->mAbortLoginErrorMsg;
             break;
         default:
             ApiBase::dieDebug(__METHOD__, "Unhandled case value: {$authRes}");
     }
     $this->getResult()->addValue(null, 'login', $result);
 }
 protected function diffWikitext($title, $wikitext)
 {
     $apiParams = array('action' => 'query', 'prop' => 'revisions', 'titles' => $title->getPrefixedDBkey(), 'rvdifftotext' => $this->pstWikitext($title, $wikitext));
     $api = new ApiMain(new DerivativeRequest($this->getRequest(), $apiParams, false), false);
     $api->execute();
     if (defined('ApiResult::META_CONTENT')) {
         $result = $api->getResult()->getResultData(null, array('BC' => array(), 'Types' => array()));
     } else {
         $result = $api->getResultData();
     }
     if (!isset($result['query']['pages'][$title->getArticleID()]['revisions'][0]['diff']['*'])) {
         return array('result' => 'fail');
     }
     $diffRows = $result['query']['pages'][$title->getArticleID()]['revisions'][0]['diff']['*'];
     if ($diffRows !== '') {
         $context = new DerivativeContext($this->getContext());
         $context->setTitle($title);
         $engine = new DifferenceEngine($context);
         return array('result' => 'success', 'diff' => $engine->addHeader($diffRows, $context->msg('currentrev')->parse(), $context->msg('yourtext')->parse()));
     } else {
         return array('result' => 'nochanges');
     }
 }