/** * Show a return link or redirect to it. * Extensions can change where the link should point or inject content into the page * (which will change it from redirect to link mode). * * @param string $type One of the following: * - error: display a return to link ignoring $wgRedirectOnLogin * - success: display a return to link using $wgRedirectOnLogin if needed * - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed * @param string $returnTo * @param array|string $returnToQuery * @param bool $stickHTTPS Keep redirect link on HTTPS */ public function showReturnToPage($type, $returnTo = '', $returnToQuery = '', $stickHTTPS = false) { global $wgRedirectOnLogin, $wgSecureLogin; if ($type !== 'error' && $wgRedirectOnLogin !== null) { $returnTo = $wgRedirectOnLogin; $returnToQuery = []; } elseif (is_string($returnToQuery)) { $returnToQuery = wfCgiToArray($returnToQuery); } // Allow modification of redirect behavior Hooks::run('PostLoginRedirect', [&$returnTo, &$returnToQuery, &$type]); $returnToTitle = Title::newFromText($returnTo) ?: Title::newMainPage(); if ($wgSecureLogin && !$stickHTTPS) { $options = ['http']; $proto = PROTO_HTTP; } elseif ($wgSecureLogin) { $options = ['https']; $proto = PROTO_HTTPS; } else { $options = []; $proto = PROTO_RELATIVE; } if ($type === 'successredirect') { $redirectUrl = $returnToTitle->getFullURL($returnToQuery, false, $proto); $this->getOutput()->redirect($redirectUrl); } else { $this->getOutput()->addReturnTo($returnToTitle, $returnToQuery, null, $options); } }
/** @dataProvider provideTokenClasses */ public function testTokenRetrieval($id, $class) { // Make sure we have the right to get the token global $wgGroupPermissions; $wgGroupPermissions['*'][$class::getRight()] = true; RequestContext::getMain()->getUser()->clearInstanceCache(); // Reread above global // We should be getting anonymous user token $expected = $class::getToken(); $this->assertNotSame(false, $expected, 'We did not get a valid token'); $actionString = TranslateUtils::getTokenAction($id); $params = wfCgiToArray($actionString); $req = new FauxRequest($params); $api = new ApiMain($req); $api->execute(); if (defined('ApiResult::META_CONTENT')) { $data = $api->getResult()->getResultData(null, array('Strip' => 'all')); } else { $data = $api->getResultData(); } if (isset($data['query'])) { foreach ($data['query']['pages'] as $page) { $this->assertSame($expected, $page[$id . 'token']); } } else { $this->assertArrayHasKey('tokens', $data, 'Result has tokens'); $this->assertSame($expected, $data['tokens'][$id . 'token']); } }
public function testPostEditRedirect() { $t = new ModerationTestsuite(); $t->loginAs($t->unprivilegedUser); $req = $t->doTestEdit(); $t->fetchSpecial(); $this->assertTrue($req->status->isOK()); $this->assertTrue($req->isRedirect(), "testPostEditRedirect(): User hasn't been redirected after the edit"); # Check the redirect URL $url = $req->getResponseHeader("Location"); $params = wfCgiToArray(preg_replace('/^.*?\\?/', '', $url)); $this->assertArrayHasKey('title', $params); $this->assertArrayHasKey('modqueued', $params); $this->assertCount(2, $params, "testPostEditRedirect(): redirect URL has parameters other than 'title' and 'modqueued'"); $this->assertEquals($t->lastEdit['Title'], preg_replace('/_/', ' ', $params['title']), "testPostEditRedirect(): Title in the redirect URL doesn't match the title of page we edited"); $this->assertEquals(1, $params['modqueued'], "testPostEditRedirect(): parameter modqueued=1 not found in the redirect URL"); # Check the page where the user is being redirected to $list = $t->html->getLoaderModulesList($url); $this->assertContains('ext.moderation.notify', $list, "testPostEditRedirect(): Module ext.moderation.notify wasn't loaded"); # Usual checks on whether the edit not via API was intercepted. $this->assertCount(1, $t->new_entries, "testPostEditRedirect(): One edit was queued for moderation, but number of added entries in Pending folder isn't 1"); $this->assertCount(0, $t->deleted_entries, "testPostEditRedirect(): Something was deleted from Pending folder during the queueing"); $this->assertEquals($t->lastEdit['User'], $t->new_entries[0]->user); $this->assertEquals($t->lastEdit['Title'], $t->new_entries[0]->title); }
/** * Build the login page * @todo Refactor this into parent template */ public function execute() { $action = $this->data['action']; $token = $this->data['token']; $watchArticle = $this->getArticleTitleToWatch(); $stickHTTPS = $this->doStickHTTPS() ? Html::input('wpStickHTTPS', 'true', 'hidden') : ''; $username = strlen($this->data['name']) ? $this->data['name'] : null; // @TODO make sure this also includes returnto and returntoquery from the request $query = array('type' => 'signup'); // Security: $action is already filtered by SpecialUserLogin $actionQuery = wfCgiToArray($action); if (isset($actionQuery['returnto'])) { $query['returnto'] = $actionQuery['returnto']; } if (isset($actionQuery['returntoquery'])) { $query['returntoquery'] = $actionQuery['returntoquery']; // Allow us to distinguish sign ups from the left nav to logins. // This allows us to show them an edit tutorial when they return to the page. if ($query['returntoquery'] === 'welcome=yes') { $query['returntoquery'] = 'campaign=leftNavSignup'; } } // For Extension:Campaigns $campaign = $this->getSkin()->getRequest()->getText('campaign'); if ($campaign) { $query['campaign'] = $campaign; } // Check for permission to create new account first $user = $this->getRequestContext()->getUser(); if ($user->isAllowed('createaccount')) { $signupLink = Linker::link(SpecialPage::getTitleFor('Userlogin'), wfMessage('mobile-frontend-main-menu-account-create')->text(), array('class' => 'mw-mf-create-account mw-ui-block'), $query); } else { $signupLink = ''; } // Check for permission to reset password first if ($this->data['canreset'] && $this->data['useemail'] && $this->data['resetlink'] === true) { $passwordReset = Html::element('a', array('class' => 'mw-userlogin-help mw-ui-block', 'href' => SpecialPage::getTitleFor('PasswordReset')->getLocalUrl()), wfMessage('passwordreset')->text()); } else { $passwordReset = ''; } $login = Html::openElement('div', array('id' => 'mw-mf-login', 'class' => 'content')); $form = Html::openElement('div', array()) . Html::openElement('form', array('name' => 'userlogin', 'class' => 'user-login', 'method' => 'post', 'action' => $action)) . Html::openElement('div', array('class' => 'inputs-box')) . Html::input('wpName', $username, 'text', array('class' => 'loginText', 'placeholder' => wfMessage('mobile-frontend-username-placeholder')->text(), 'id' => 'wpName1', 'tabindex' => '1', 'size' => '20', 'required')) . Html::input('wpPassword', null, 'password', array('class' => 'loginPassword', 'placeholder' => wfMessage('mobile-frontend-password-placeholder')->text(), 'id' => 'wpPassword1', 'tabindex' => '2', 'size' => '20')) . Html::closeElement('div') . Html::input('wpRemember', '1', 'hidden') . Html::input('wpLoginAttempt', wfMessage('mobile-frontend-login')->text(), 'submit', array('id' => 'wpLoginAttempt', 'class' => $baseClass = MobileUI::buttonClass('constructive'), 'tabindex' => '3')) . Html::input('wpLoginToken', $token, 'hidden') . Html::input('watch', $watchArticle, 'hidden') . $stickHTTPS . Html::closeElement('form') . $passwordReset . $signupLink . Html::closeElement('div'); echo $login; $this->renderGuiderMessage(); $this->renderMessageHtml(); echo $form; echo Html::closeElement('div'); }
/** * @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; }
/** * Parse tracking_data param into something meaningful to PayflowPro gateway * * @param array $tracking_data An array of tracking data - expects 'referrer' and 'url' * @return array of cleaned up, PayflowPro Gateway-consumable tracking data */ protected function parseTrackingData($unparsed_tracking_data) { // get the query string from the URL and turn it into an associative array $url_bits = wfParseUrl(urldecode($unparsed_tracking_data['url'])); $tracking_data = wfCgiToArray($url_bits['query']); // add the referrer to the tracked_data array $tracking_data['referrer'] = urldecode($unparsed_tracking_data['pageref']); //DonationData handles the utm normalization now. return $tracking_data; }
/** * Take an arbitrary query and rewrite the present URL to include it * @param string $query query string fragment; do not include initial '?' * * @return String */ public function appendQuery($query) { return $this->appendQueryArray(wfCgiToArray($query)); }
/** * Render a forced-blue link inline; protect against double expansion of * URLs if we're in a mode that prepends full URL prefixes to internal links. * Since this little disaster has to split off the trail text to avoid * breaking URLs in the following text without breaking trails on the * wiki links, it's been made into a horrible function. * * @param Title $nt * @param string $text * @param array|string $query * @param string $trail * @param string $prefix * @return string HTML-wikitext mix oh yuck */ function makeKnownLinkHolder($nt, $text = '', $query = array(), $trail = '', $prefix = '') { list($inside, $trail) = Linker::splitTrail($trail); if (is_string($query)) { $query = wfCgiToArray($query); } if ($text == '') { $text = htmlspecialchars($nt->getPrefixedText()); } $link = Linker::linkKnown($nt, "{$prefix}{$text}{$inside}", array(), $query); return $this->armorLinks($link) . $trail; }
/** * Make a "broken" link to an image * * @param Title $title * @param string $label Link label (plain text) * @param string $query Query string * @param string $unused1 Unused parameter kept for b/c * @param string $unused2 Unused parameter kept for b/c * @param bool $time A file of a certain timestamp was requested * @return string */ public static function makeBrokenImageLinkObj($title, $label = '', $query = '', $unused1 = '', $unused2 = '', $time = false) { if (!$title instanceof Title) { wfWarn(__METHOD__ . ': Requires $title to be a Title object.'); return "<!-- ERROR -->" . htmlspecialchars($label); } global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl; if ($label == '') { $label = $title->getPrefixedText(); } $encLabel = htmlspecialchars($label); $currentExists = $time ? wfFindFile($title) != false : false; if (($wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads) && !$currentExists) { $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect($title); if ($redir) { return self::linkKnown($title, $encLabel, array(), wfCgiToArray($query)); } $href = self::getUploadUrl($title, $query); return '<a href="' . htmlspecialchars($href) . '" class="new" title="' . htmlspecialchars($title->getPrefixedText(), ENT_QUOTES) . '">' . $encLabel . '</a>'; } return self::linkKnown($title, $encLabel, array(), wfCgiToArray($query)); }
public function onSuccess() { $request = $this->getRequest(); $titleObj = Title::newFromText($request->getVal('returnto')); if (!$titleObj instanceof Title) { $titleObj = Title::newMainPage(); } $query = $request->getVal('returntoquery'); if ($this->status->value === true) { $this->getOutput()->redirect($titleObj->getFullURL($query)); } elseif ($this->status->value === 'eauth') { # Notify user that a confirmation email has been sent... $this->getOutput()->wrapWikiMsg("<div class='error' style='clear: both;'>\n\$1\n</div>", 'eauthentsent', $this->getUser()->getName()); // just show the link to go back $this->getOutput()->addReturnTo($titleObj, wfCgiToArray($query)); } }
/** * Generate (prev x| next x) (20|50|100...) type links for paging * * @param $offset String * @param $limit Integer * @param $link String * @param $query String: optional URL query parameter string * @param $atend Bool: optional param for specified if this is the last page * @return String * @deprecated in 1.19; use Language::viewPrevNext() instead */ function wfViewPrevNext($offset, $limit, $link, $query = '', $atend = false) { wfDeprecated(__METHOD__, '1.19'); global $wgLang; $query = wfCgiToArray($query); if (is_object($link)) { $title = $link; } else { $title = Title::newFromText($link); if (is_null($title)) { return false; } } return $wgLang->viewPrevNext($title, $offset, $limit, $query, $atend); }
/** * @deprecated Use link() * * Make a red link to the edit page of a given title. * * @param $nt Title object of the target page * @param $text String: Link text * @param $query String: Optional query part * @param $trail String: Optional trail. Alphabetic characters at the start of this string will * be included in the link text. Other characters will be appended after * the end of the link. */ function makeBrokenLinkObj($title, $text = '', $query = '', $trail = '', $prefix = '') { wfProfileIn(__METHOD__); list($inside, $trail) = Linker::splitTrail($trail); if ($text === '') { $text = $this->linkText($title); } $nt = $this->normaliseSpecialPage($title); $ret = $this->link($title, "{$prefix}{$text}{$inside}", array(), wfCgiToArray($query), 'broken') . $trail; wfProfileOut(__METHOD__); return $ret; }
public function testMerge() { $t = new ModerationTestsuite(); $this->makeEditConflict($t); # Done: attempt to approve the edit by $t->unprivilegedUser # will cause an edit conflict. $t->fetchSpecial(); $this->assertFalse($t->new_entries[0]->conflict, "testMerge(): Edit with not-yet-detected conflict is marked with class='modconflict'"); $error = $t->html->getModerationError($t->new_entries[0]->approveLink); $this->assertEquals('(moderation-edit-conflict)', $error, "testMerge(): Edit conflict not detected by modaction=approve"); $t->fetchSpecial(); $this->assertCount(0, $t->new_entries, "testMerge(): Something was added into Pending folder when modaction=approve detected edit conflict"); $this->assertCount(0, $t->deleted_entries, "testMerge(): Something was deleted from Rejected folder when modaction=approve detected edit conflict"); $t->assumeFolderIsEmpty(); $t->fetchSpecial(); $entry = $t->new_entries[0]; $id = $entry->id; $this->assertTrue($entry->conflict, "testMerge(): Edit with detected conflict is not marked with class='modconflict'"); $this->assertNotNull($entry->mergeLink, "testMerge(): Merge link not found for edit with detected conflict"); $this->assertNotNull($entry->rejectLink, "testMerge(): Reject link not found for edit with detected conflict"); $this->assertNotNull($entry->rejectAllLink, "testMerge(): RejectAll link not found for edit with detected conflict"); $this->assertNotNull($entry->showLink, "testMerge(): Show link not found for edit with detected conflict"); $this->assertNotNull($entry->blockLink, "testMerge(): Block link not found for edit with detected conflict"); $this->assertNull($entry->approveLink, "testMerge(): Approve link found for edit with detected conflict"); $this->assertNull($entry->approveAllLink, "testMerge(): ApproveAll link found for edit with detected conflict"); $this->assertNull($entry->mergedDiffLink, "testMerge(): MergedDiff link found for not yet merged edit"); $this->assertNull($entry->rejected_by_user, "testMerge(): Not yet rejected edit with detected conflict is marked rejected"); $this->assertFalse($entry->rejected_batch, "testMerge(): Not yet rejected edit with detected conflict has rejected_batch flag ON"); $this->assertFalse($entry->rejected_auto, "testMerge(): Not yet rejected edit with detected conflict has rejected_auto flag ON"); $title = $t->html->getTitle($entry->mergeLink); $this->assertRegExp('/\\(editconflict: ' . $t->lastEdit['Title'] . '\\)/', $title, "testMerge(): Wrong HTML title from modaction=merge"); $this->assertEquals($this->text2, $t->html->getElementById('wpTextbox1')->textContent, "testMerge(): The upper textarea doesn't contain the current page text"); $this->assertEquals($this->text1, $t->html->getElementById('wpTextbox2')->textContent, "testMerge(): The lower textarea doesn't contain the text we attempted to approve"); $form = $t->html->getElementById('editform'); $this->assertNotNull($form, "testMerge(): Edit form isn't shown by the Merge link\n"); $inputs = $t->html->getFormElements($form); $this->assertArrayHasKey('wpIgnoreBlankSummary', $inputs, "testMerge(): Edit form doesn't contain wpIgnoreBlankSummary field"); $this->assertEquals(1, $inputs['wpIgnoreBlankSummary'], "testMerge(): Value of wpIgnoreBlankSummary field isn't 1"); $this->assertArrayHasKey('wpMergeID', $inputs, "testMerge(): Edit form doesn't contain wpMergeID field"); $this->assertEquals($id, $inputs['wpMergeID'], "testMerge(): Value of wpMergeID field doesn't match the entry id"); # Try to edit now $req = $t->nonApiEdit($this->page, $this->text3, "Wow, I merged an edit", array('wpMergeID' => $id)); $this->assertNotNull($req->getResponseHeader('location'), "testMerge(): non-API edit with wpMergeID failed"); $rev = $t->getLastRevision($this->page); $this->assertEquals($t->moderator->getName(), $rev['user']); # Was the edit moved into the 'merged' folder? $t->fetchSpecial(); $this->assertCount(0, $t->new_entries, "testMerge(): Something was added into Pending folder when the edit was merged"); $this->assertCount(1, $t->deleted_entries, "testMerge(): One edit was merged, but number of deleted entries in Pending folder isn't 1"); $this->assertEquals($id, $t->deleted_entries[0]->id); $t->fetchSpecial('merged'); $this->assertCount(1, $t->new_entries, "testMerge(): One edit was merged, but number of new entries in Merged folder isn't 1"); $this->assertCount(0, $t->deleted_entries, "testMerge(): Something was deleted from Merged folder when the edit was merged"); $entry = $t->new_entries[0]; $this->assertEquals($id, $entry->id); $this->assertNull($entry->rejectLink, "testMerge(): Reject link found for already merged edit"); $this->assertNull($entry->rejectAllLink, "testMerge(): RejectAll link found for already merged edit"); $this->assertNull($entry->approveLink, "testMerge(): Approve link found for already merged edit"); $this->assertNull($entry->approveAllLink, "testMerge(): ApproveAll link found for already merged edit"); $this->assertNull($entry->mergeLink, "testMerge(): Merge link found for already merged edit"); $this->assertNotNull($entry->showLink, "testMerge(): Show link not found for already merged edit"); $this->assertNotNull($entry->blockLink, "testMerge(): Block link not found for already merged edit"); $this->assertNotNull($entry->mergedDiffLink, "testMerge(): MergedDiff link not found for already merged edit"); $params = wfCgiToArray(preg_replace('/^.*?\\?/', '', $entry->mergedDiffLink)); $this->assertArrayHasKey('diff', $params); $this->assertEquals($rev['revid'], $params['diff'], "testMerge(): diff parameter doesn't match revid of the last revision on the page we edited"); }
/** * Add a "return to" link or redirect to it. * * @param $type string, one of the following: * - error: display a return to link ignoring $wgRedirectOnLogin * - success: display a return to link using $wgRedirectOnLogin if needed * - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed */ private function executeReturnTo($type) { global $wgRedirectOnLogin, $wgSecureLogin; if ($type != 'error' && $wgRedirectOnLogin !== null) { $returnTo = $wgRedirectOnLogin; $returnToQuery = array(); } else { $returnTo = $this->mReturnTo; $returnToQuery = wfCgiToArray($this->mReturnToQuery); } $returnToTitle = Title::newFromText($returnTo); if (!$returnToTitle) { $returnToTitle = Title::newMainPage(); } if ($wgSecureLogin && !$this->mStickHTTPS) { $options = array('http'); $proto = PROTO_HTTP; } elseif ($wgSecureLogin) { $options = array('https'); $proto = PROTO_HTTPS; } else { $options = array(); $proto = PROTO_RELATIVE; } if ($type == 'successredirect') { //forwarding to forums? if ($returnTo == 'vanilla') { global $wgForumLink; $redirectUrl = $wgForumLink; } else { $redirectUrl = $returnToTitle->getFullURL($returnToQuery, false, $proto); } $this->getOutput()->redirect($redirectUrl); } else { $this->getOutput()->addReturnTo($returnToTitle, $returnToQuery, null, $options); } }
/** * Gets the message that should guide a user who is creating an account or * logging in to an account. * @return array First element is header of message and second is the content. */ protected function getGuiderMessage() { $req = $this->getRequestContext()->getRequest(); // omit UserLogin's own messages in this template to avoid duplicate messages - bug T73771, T86031 if ($this->data['messagetype'] !== 'error') { $this->data['message'] = ''; } if ($req->getVal('returnto') && ($title = Title::newFromText($req->getVal('returnto')))) { list($returnto, ) = SpecialPageFactory::resolveAlias($title->getDBkey()); $title = $title->getText(); } else { $returnto = ''; $title = ''; } $returnToQuery = wfCgiToArray($req->getVal('returntoquery')); if (isset($returnToQuery['article_action'])) { $action = $returnToQuery['article_action']; } else { $action = ''; } $heading = ''; $content = ''; if (isset($this->pageMessageHeaders[$returnto])) { $heading = wfMessage($this->pageMessageHeaders[$returnto])->parse(); if (isset($this->pageMessages[$returnto])) { $content = wfMessage($this->pageMessages[$returnto])->parse(); } } elseif (isset($this->actionMessageHeaders[$action])) { $heading = wfMessage($this->actionMessageHeaders[$action], $title)->parse(); if (isset($this->actionMessages[$action])) { $content = wfMessage($this->actionMessages[$action], $title)->parse(); } } return array($heading, $content); }
/** * @deprecated since 1.16 Use link(); warnings since 1.21 * * Make a link for a title which definitely exists. This is faster than makeLinkObj because * it doesn't have to do a database query. It's also valid for interwiki titles and special * pages. * * @param Title $title Title object of target page * @param string $text Text to replace the title * @param string $query Link target * @param string $trail Text after link * @param string $prefix Text before link text * @param string $aprops Extra attributes to the a-element * @param string $style Style to apply - if empty, use getInternalLinkAttributesObj instead * @return string The a-element */ static function makeKnownLinkObj($title, $text = '', $query = '', $trail = '', $prefix = '', $aprops = '', $style = '') { wfDeprecated(__METHOD__, '1.21'); if ($text == '') { $text = self::linkText($title); } $attribs = Sanitizer::mergeAttributes(Sanitizer::decodeTagAttributes($aprops), Sanitizer::decodeTagAttributes($style)); $query = wfCgiToArray($query); list($inside, $trail) = self::splitTrail($trail); $ret = self::link($title, "{$prefix}{$text}{$inside}", $attribs, $query, array('known', 'noclasses')) . $trail; return $ret; }
public function showStatsList($regex_id) { global $wgOut, $wgLang; wfProfileIn(__METHOD__); $regexData = new TextRegexCore($this->subList, $regex_id); $regexInfo = $regexData->getOneRegex(); $numStatResults = $regexData->fetchNbrStatResults(); #--- if (!empty($regexInfo)) { $regexStats = array(); if ($numStatResults > 0) { $regexStats = $regexData->getRegexStats(); } $filter = 'action=stats&id=' . urlencode($regex_id); $pager = $wgLang->viewPrevNext(SpecialPage::getTitleFor('TextRegex/' . $this->subList), $this->offset, $this->limit, wfCgiToArray($filter), $numStatResults - $this->offset <= $this->limit); $action = htmlspecialchars($this->oTitle->getLocalURL($this->getListBits())); $wgOut->setSubTitle(wfMsgExt('textregex-return-mainpage', 'parse', $action)); $oTmpl = new EasyTemplate(dirname(__FILE__) . "/templates/"); $oTmpl->set_vars(array("pager" => $pager, "stats_list" => $regexStats, "lang" => $wgLang, "skin" => RequestContext::getMain()->getSkin(), "oTitle" => $this->oTitle, "regexInfo" => $regexInfo, "action" => $action, "numStatResults" => $numStatResults)); $wgOut->addHTML($oTmpl->render("textregex-stats")); } else { $wgOut->addHTML(wfMsg('textregex-invalid-regexid')); } wfProfileOut(__METHOD__); return 1; }
public function __construct($url, array $cookies = array()) { $this->url = $url; $query = array(); if ($url) { $params = wfParseUrl(wfExpandUrl($url)); if (isset($params['query'])) { $query = wfCgiToArray($params['query']); } } parent::__construct($query); $this->cookies = $cookies; $this->response = new FauxResponse(); }
/** * @deprecated since 1.16 Use link() * * Make a red link to the edit page of a given title. * * @param $title Title object of the target page * @param $text String: Link text * @param $query String: Optional query part * @param $trail String: Optional trail. Alphabetic characters at the start of this string will * be included in the link text. Other characters will be appended after * the end of the link. * @param $prefix String: Optional prefix */ static function makeBrokenLinkObj($title, $text = '', $query = '', $trail = '', $prefix = '') { wfDeprecated(__METHOD__, '1.16'); wfProfileIn(__METHOD__); list($inside, $trail) = self::splitTrail($trail); if ($text === '') { $text = self::linkText($title); } # wikia change begin global $wgWikiaEnableSharedHelpExt; if ($wgWikiaEnableSharedHelpExt && NS_HELP == $title->getNamespace() && SharedHelpArticleExists($title)) { wfProfileOut(__METHOD__); return self::link($title, "{$prefix}{$text}{$inside}", array(), wfCgiToArray($query), 'known') . $trail; } $attribs = array(); global $wgWikiaUseNoFollow, $wgWikiaEnableAutoPageCreateExt; $condition = !empty($wgWikiaUseNoFollow) && (empty($wgWikiaEnableAutoPageCreateExt) && !empty($wgWikiaUseNoFollowForContent) || !$title->isContentPage()); if ($condition) { $attribs['rel'] = 'nofollow'; } # wikia change end $ret = self::link($title, "{$prefix}{$text}{$inside}", $attribs, wfCgiToArray($query), 'broken') . $trail; wfProfileOut(__METHOD__); return $ret; }
/** * @depends testLogin */ function testUploadChunkDoneDuplicate( $data ) { global $wgUser, $wgVerifyMimeType; $this->markTestIncomplete("Not working yet"); $wgVerifyMimeType = false; $wgUser = User::newFromName( self::$userName ); $data[2]['wsEditToken'] = $data[2]['wsToken']; $token = md5( $data[2]['wsToken'] ) . EDIT_TOKEN_SUFFIX; $data = $this->doApiRequest( array( 'filename' => 'twar.png', 'action' => 'resumableupload', 'token' => $token ), $data ); $url = $data[0]['uploadUrl']; $params = wfCgiToArray( substr( $url, strpos( $url, "?" ) ) ); $size = 0; $gotException = false; for ( $i = 0; $i < 30; $i++ ) { $this->makeChunk( "123" ); $size += $_FILES['chunk']['size']; try { $data = $this->doApiRequest( $params, $data ); } catch (UsageException $e) { $arr = $e->getMessageArray(); $this->assertArrayHasKey( "code", $arr ); $this->assertEquals( "internal-error", $arr['code'] ); $this->assertEquals( "fileexistserror", $arr[0][0] ); $gotException = true; } } $this->cleanChunk(); $this->assertTrue($gotException); }
/** * Add a "return to" link or redirect to it. * * @param string $type One of the following: * - error: display a return to link ignoring $wgRedirectOnLogin * - signup: display a return to link using $wgRedirectOnLogin if needed * - success: display a return to link using $wgRedirectOnLogin if needed * - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed */ private function executeReturnTo($type) { global $wgRedirectOnLogin, $wgSecureLogin; if ($type != 'error' && $wgRedirectOnLogin !== null) { $returnTo = $wgRedirectOnLogin; $returnToQuery = array(); } else { $returnTo = $this->mReturnTo; $returnToQuery = wfCgiToArray($this->mReturnToQuery); } // Allow modification of redirect behavior Hooks::run('PostLoginRedirect', array(&$returnTo, &$returnToQuery, &$type)); $returnToTitle = Title::newFromText($returnTo); if (!$returnToTitle) { $returnToTitle = Title::newMainPage(); } if ($wgSecureLogin && !$this->mStickHTTPS) { $options = array('http'); $proto = PROTO_HTTP; } elseif ($wgSecureLogin) { $options = array('https'); $proto = PROTO_HTTPS; } else { $options = array(); $proto = PROTO_RELATIVE; } if ($type == 'successredirect') { $redirectUrl = $returnToTitle->getFullURL($returnToQuery, false, $proto); $this->getOutput()->redirect($redirectUrl); } else { $this->getOutput()->addReturnTo($returnToTitle, $returnToQuery, null, $options); } }
/** * Run any hooks registered for logins, then display a message welcoming * the user. * @param bool $direct True if the action was successful just now; false if that happened * pre-redirection (so this handler was called already) * @param StatusValue|null $extraMessages */ protected function successfulAction($direct = false, $extraMessages = null) { $session = $this->getRequest()->getSession(); $user = $this->targetUser ?: $this->getUser(); if ($direct) { # Only save preferences if the user is not creating an account for someone else. if (!$this->proxyAccountCreation) { Hooks::run('AddNewAccount', [$user, false]); // If the user does not have a session cookie at this point, they probably need to // do something to their browser. if (!$this->hasSessionCookie()) { $this->mainLoginForm([], $session->getProvider()->whyNoSession()); // TODO something more specific? This used to use nocookiesnew // FIXME should redirect to login page instead? return; } } else { $byEmail = false; // FIXME no way to set this Hooks::run('AddNewAccount', [$user, $byEmail]); $out = $this->getOutput(); $out->setPageTitle($this->msg($byEmail ? 'accmailtitle' : 'accountcreated')); if ($byEmail) { $out->addWikiMsg('accmailtext', $user->getName(), $user->getEmail()); } else { $out->addWikiMsg('accountcreatedtext', $user->getName()); } $rt = Title::newFromText($this->mReturnTo); $out->addReturnTo($rt && !$rt->isExternal() ? $rt : $this->getPageTitle(), wfCgiToArray($this->mReturnToQuery)); return; } } $this->clearToken(); # Run any hooks; display injected HTML $injected_html = ''; $welcome_creation_msg = 'welcomecreation-msg'; Hooks::run('UserLoginComplete', [&$user, &$injected_html, $direct]); /** * Let any extensions change what message is shown. * @see https://www.mediawiki.org/wiki/Manual:Hooks/BeforeWelcomeCreation * @since 1.18 */ Hooks::run('BeforeWelcomeCreation', [&$welcome_creation_msg, &$injected_html]); $this->showSuccessPage('signup', $this->msg('welcomeuser', $this->getUser()->getName()), $welcome_creation_msg, $injected_html, $extraMessages); }
/** * @dataProvider provideCgiRoundTrip * @covers ::wfArrayToCgi */ public function testCgiRoundTrip($cgi) { $this->assertEquals($cgi, wfArrayToCgi(wfCgiToArray($cgi))); }
/** * Performs view change as requested vy toggleView() */ public function doToggling() { $mobileUrlTemplate = $this->getMobileUrlTemplate(); if (!$this->viewChange) { return; } $url = $this->getRequest()->getFullRequestURL(); $parsed = wfParseUrl($url); $query = isset($parsed['query']) ? wfCgiToArray($parsed['query']) : array(); unset($query['mobileaction']); unset($query['useformat']); unset($query['title']); $url = $this->getTitle()->getFullURL($query, false, PROTO_CURRENT); if ($this->viewChange == 'mobile') { // unset stopMobileRedirect cookie // @TODO is this necessary with unsetting the cookie via JS? $this->unsetStopMobileRedirectCookie(); // if no mobileurl template, set mobile cookie if (!strlen(trim($mobileUrlTemplate))) { $this->setUseFormatCookie(); } else { // else redirect to mobile domain $mobileUrl = $this->getMobileUrl($url); $this->getOutput()->redirect($mobileUrl, 301); } } elseif ($this->viewChange == 'desktop') { // set stopMobileRedirect cookie $this->setStopMobileRedirectCookie(); // unset useformat cookie if ($this->getUseFormatCookie() == "true") { $this->unsetUseFormatCookie(); } if (strlen(trim($mobileUrlTemplate))) { // if mobileurl template, redirect to desktop domain $desktopUrl = $this->getDesktopUrl($url); $this->getOutput()->redirect($desktopUrl, 301); } } }
/** * Take an arbitrary query and rewrite the present URL to include it * @deprecated Use appendQueryValue/appendQueryArray instead * @param string $query Query string fragment; do not include initial '?' * @return string */ public function appendQuery($query) { wfDeprecated(__METHOD__, '1.25'); return $this->appendQueryArray(wfCgiToArray($query)); }
/** * Add a "return to" link or redirect to it. * * @param $type string, one of the following: * - error: display a return to link ignoring $wgRedirectOnLogin * - success: display a return to link using $wgRedirectOnLogin if needed * - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed */ private function executeReturnTo($type) { global $wgRedirectOnLogin, $wgSecureLogin; if ($type != 'error' && $wgRedirectOnLogin !== null) { $returnTo = $wgRedirectOnLogin; $returnToQuery = array(); } else { $returnTo = $this->mReturnTo; $returnToQuery = wfCgiToArray($this->mReturnToQuery); } $returnToTitle = Title::newFromText($returnTo); if (!$returnToTitle) { $returnToTitle = Title::newMainPage(); } if ($type == 'successredirect') { $redirectUrl = $returnToTitle->getFullURL($returnToQuery); if ($wgSecureLogin && !$this->mStickHTTPS) { $redirectUrl = preg_replace('/^https:/', 'http:', $redirectUrl); } $this->getOutput()->redirect($redirectUrl); } else { $this->getOutput()->addReturnTo($returnToTitle, $returnToQuery); } }
/** * @deprecated since 1.16 Use link() * * Make a red link to the edit page of a given title. * * @param $title Title object of the target page * @param $text String: Link text * @param $query String: Optional query part * @param $trail String: Optional trail. Alphabetic characters at the start of this string will * be included in the link text. Other characters will be appended after * the end of the link. * @param $prefix String: Optional prefix */ static function makeBrokenLinkObj($title, $text = '', $query = '', $trail = '', $prefix = '') { wfProfileIn(__METHOD__); list($inside, $trail) = self::splitTrail($trail); if ($text === '') { $text = self::linkText($title); } $ret = self::link($title, "{$prefix}{$text}{$inside}", array(), wfCgiToArray($query), 'broken') . $trail; wfProfileOut(__METHOD__); return $ret; }
/** * Returns a suitable text string for displaying this link in HTML or wiki, depending * on whether $outputformat is SMW_OUTPUT_WIKI or SMW_OUTPUT_HTML. * * The parameter $linker controls linking of values such as titles and should * be some Linker object (for HTML output). Some default linker will be created * if needed and not provided. */ public function getText($outputformat, $linker = null) { if ($this->mStyle !== false) { SMWOutputs::requireResource('ext.smw.style'); $start = "<span class=\"{$this->mStyle}\">"; $end = '</span>'; } else { $start = ''; $end = ''; } if ($this->mInternal) { if (count($this->mParams) > 0) { $titletext = $this->mTarget . '/' . self::encodeParameters($this->mParams); } else { $titletext = $this->mTarget; } $title = Title::newFromText($titletext); if (!is_null($title)) { if ($outputformat == SMW_OUTPUT_WIKI) { $link = "[[{$titletext}|{$this->mCaption}]]"; } else { // SMW_OUTPUT_HTML, SMW_OUTPUT_FILE $link = $this->getLinker($linker)->link($title, $this->mCaption); } } else { // Title creation failed, maybe illegal symbols or too long; make a direct URL link // (only possible if offending target parts belong to some parameter // that can be separated from title text, // e.g. as in Special:Bla/il<leg>al -> Special:Bla&p=il<leg>al) $title = Title::newFromText($this->mTarget); if (!is_null($title)) { if ($outputformat == SMW_OUTPUT_WIKI) { $link = '[' . $title->getFullURL(self::encodeParameters($this->mParams, false)) . " {$this->mCaption}]"; } else { // SMW_OUTPUT_HTML, SMW_OUTPUT_FILE // #511, requires an array $query = wfCgiToArray(self::encodeParameters($this->mParams, false)); $link = $this->getLinker($linker)->link($title, $this->mCaption, array(), $query); } } else { return ''; // the title was bad, normally this would indicate a software bug } } } else { $target = $this->getURL(); if ($outputformat == SMW_OUTPUT_WIKI) { $link = "[{$target} {$this->mCaption}]"; } else { // SMW_OUTPUT_HTML, SMW_OUTPUT_FILE $link = '<a href="' . htmlspecialchars($target) . "\">{$this->mCaption}</a>"; } } return $start . $link . $end; }
/** * Add a "return to" link pointing to a specified title, * or the title indicated in the request, or else the main page * * @param mixed $unused * @param Title|string $returnto Title or String to return to * @param string $returntoquery Query string for the return to link */ public function returnToMain($unused = null, $returnto = null, $returntoquery = null) { if ($returnto == null) { $returnto = $this->getRequest()->getText('returnto'); } if ($returntoquery == null) { $returntoquery = $this->getRequest()->getText('returntoquery'); } if ($returnto === '') { $returnto = Title::newMainPage(); } if (is_object($returnto)) { $titleObj = $returnto; } else { $titleObj = Title::newFromText($returnto); } if (!is_object($titleObj)) { $titleObj = Title::newMainPage(); } $this->addReturnTo($titleObj, wfCgiToArray($returntoquery)); }
/** * Determine the 'no cache' form action * * This mostly exists to ensure that the form does not try to use AJAX to * overwrite certain hidden form params that are normally overwitten for * cached versions of the form. * @return string $url The full URL for the form to post to */ protected function getNoCacheAction() { $url = $this->gatewayPage->getRequest()->getFullRequestURL(); $url_parts = wfParseUrl($url); if (isset($url_parts['query'])) { $query_array = wfCgiToArray($url_parts['query']); } else { $query_array = array(); } // ensure that _cache_ does not get set in the URL unset($query_array['_cache_']); // make sure no other data that might overwrite posted data makes it into the URL $all_form_data = $this->gateway->getData_Unstaged_Escaped(); $keys_we_need_for_form_loading = array('form_name', 'ffname', 'country', 'currency', 'language'); $form_data_keys = array_keys($all_form_data); foreach ($query_array as $key => $value) { if (in_array($key, $form_data_keys)) { if (!in_array($key, $keys_we_need_for_form_loading)) { unset($query_array[$key]); } else { $query_array[$key] = $all_form_data[$key]; } } } // construct the submission url $title = $this->gatewayPage->getPageTitle(); return wfAppendQuery($title->getLocalURL(), $query_array); }