function __construct(IContextSource $context, $par = null) { $this->like = $context->getRequest()->getText('like'); $this->showbots = $context->getRequest()->getBool('showbots', 0); if (is_numeric($par)) { $this->setLimit($par); } parent::__construct($context); }
/** * Generates a brief review form for a page * @param \IContextSource|\RequestContext $context * @param FlaggableWikiPage $article * @param Revision $rev */ public function __construct(IContextSource $context, FlaggableWikiPage $article, Revision $rev) { $this->user = $context->getUser(); $this->request = $context->getRequest(); $this->article = $article; $this->rev = $rev; }
/** * Check if pages can be cached for this request/user * @param $context IContextSource * @return bool */ public static function useFileCache(IContextSource $context) { global $wgUseFileCache, $wgShowIPinHeader, $wgDebugToolbar, $wgContLang; if (!$wgUseFileCache) { return false; } if ($wgShowIPinHeader || $wgDebugToolbar) { wfDebug("HTML file cache skipped. Either \$wgShowIPinHeader and/or \$wgDebugToolbar on\n"); return false; } // Get all query values $queryVals = $context->getRequest()->getValues(); foreach ($queryVals as $query => $val) { if ($query === 'title' || $query === 'curid') { continue; // note: curid sets title // Normal page view in query form can have action=view. } elseif ($query === 'action' && in_array($val, self::cacheablePageActions())) { continue; // Below are header setting params } elseif ($query === 'maxage' || $query === 'smaxage') { continue; } return false; } $user = $context->getUser(); // Check for non-standard user language; this covers uselang, // and extensions for auto-detecting user language. $ulang = $context->getLanguage()->getCode(); $clang = $wgContLang->getCode(); // Check that there are no other sources of variation return !$user->getId() && !$user->getNewtalk() && $ulang == $clang; }
/** * Checks if the request should abort due to a lagged server, * for given maxlag parameter. * * @param boolean $abort True if this class should abort the * script execution. False to return the result as a boolean. * @return boolean True if we passed the check, false if we surpass the maxlag */ private function checkMaxLag($abort) { global $wgShowHostnames; wfProfileIn(__METHOD__); $maxLag = $this->context->getRequest()->getVal('maxlag'); if (!is_null($maxLag)) { $lb = wfGetLB(); // foo()->bar() is not supported in PHP4 list($host, $lag) = $lb->getMaxLag(); if ($lag > $maxLag) { if ($abort) { $resp = $this->context->getRequest()->response(); $resp->header('HTTP/1.1 503 Service Unavailable'); $resp->header('Retry-After: ' . max(intval($maxLag), 5)); $resp->header('X-Database-Lag: ' . intval($lag)); $resp->header('Content-Type: text/plain'); if ($wgShowHostnames) { echo "Waiting for {$host}: {$lag} seconds lagged\n"; } else { echo "Waiting for a database server: {$lag} seconds lagged\n"; } } wfProfileOut(__METHOD__); if (!$abort) { return false; } exit; } } wfProfileOut(__METHOD__); return true; }
function __construct(IContextSource $context, $userName = null, $search = '', $including = false) { global $wgMiserMode; $this->mIncluding = $including; if ($userName) { $nt = Title::newFromText($userName, NS_USER); if (!is_null($nt)) { $this->mUserName = $nt->getText(); $this->mQueryConds['img_user_text'] = $this->mUserName; } } if ($search != '' && !$wgMiserMode) { $this->mSearch = $search; $nt = Title::newFromURL($this->mSearch); if ($nt) { $dbr = wfGetDB(DB_SLAVE); $this->mQueryConds[] = 'LOWER(img_name)' . $dbr->buildLike($dbr->anyString(), strtolower($nt->getDBkey()), $dbr->anyString()); } } if (!$including) { if ($context->getRequest()->getText('sort', 'img_date') == 'img_date') { $this->mDefaultDirection = true; } else { $this->mDefaultDirection = false; } } else { $this->mDefaultDirection = true; } parent::__construct($context); }
/** * Check whether external edit or diff should be used. * * @param $context IContextSource context to use * @param $type String can be either 'edit' or 'diff' * @return Bool */ public static function useExternalEngine(IContextSource $context, $type) { global $wgUseExternalEditor; if (!$wgUseExternalEditor) { return false; } $pref = $type == 'diff' ? 'externaldiff' : 'externaleditor'; $request = $context->getRequest(); return !$request->getVal('internaledit') && ($context->getUser()->getOption($pref) || $request->getVal('externaledit')); }
/** * Fetch an appropriate changes list class for the specified context * Some users might want to use an enhanced list format, for instance * * @param $context IContextSource to use * @return ChangesList|EnhancedChangesList|OldChangesList derivative */ public static function newFromContext( IContextSource $context ) { $user = $context->getUser(); $sk = $context->getSkin(); $list = null; if ( wfRunHooks( 'FetchChangesList', array( $user, &$sk, &$list ) ) ) { $new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) ); return $new ? new EnhancedChangesList( $context ) : new OldChangesList( $context ); } else { return $list; } }
private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things $title = Title::makeTitle(NS_MAIN, 'AJAX'); $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } $this->performRequest(); // Now commit any transactions, so that unreported errors after // output() don't roll back the whole DB transaction wfGetLBFactory()->commitMasterChanges(); // Output everything! $this->context->getOutput()->output(); wfProfileOut(__METHOD__); }
private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things // Wikia change - start // @author macbre, wladek $title = Wikia::createTitleFromRequest($request); // Wikia change - end $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } $this->performRequest(); $this->finalCleanup(); wfProfileOut(__METHOD__); }
private function main() { global $wgTitle; $output = $this->context->getOutput(); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($this->config->get('UseAjax') && $request->getVal('action') === 'ajax') { // Set a dummy title, because $wgTitle == null might break things $title = Title::makeTitle(NS_SPECIAL, 'Badtitle/performing an AJAX call in ' . __METHOD__); $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher($this->config); $dispatcher->performAction($this->context->getUser()); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; // Set DB query expectations for this HTTP request $trxLimits = $this->config->get('TrxProfilerLimits'); $trxProfiler = Profiler::instance()->getTransactionProfiler(); $trxProfiler->setLogger(LoggerFactory::getInstance('DBPerformance')); if ($request->hasSafeMethod()) { $trxProfiler->setExpectations($trxLimits['GET'], __METHOD__); } else { $trxProfiler->setExpectations($trxLimits['POST'], __METHOD__); } // If the user has forceHTTPS set to true, or if the user // is in a group requiring HTTPS, or if they have the HTTPS // preference set, redirect them to HTTPS. // Note: Do this after $wgTitle is setup, otherwise the hooks run from // isLoggedIn() will do all sorts of weird stuff. if ($request->getProtocol() == 'http' && preg_match('#^https://#', wfExpandUrl($request->getRequestURL(), PROTO_HTTPS)) && ($request->getSession()->shouldForceHTTPS() || $request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS())) { $oldUrl = $request->getFullRequestURL(); $redirUrl = preg_replace('#^http://#', 'https://', $oldUrl); // ATTENTION: This hook is likely to be removed soon due to overall design of the system. if (Hooks::run('BeforeHttpsRedirect', [$this->context, &$redirUrl])) { if ($request->wasPosted()) { // This is weird and we'd hope it almost never happens. This // means that a POST came in via HTTP and policy requires us // redirecting to HTTPS. It's likely such a request is going // to fail due to post data being lost, but let's try anyway // and just log the instance. // @todo FIXME: See if we could issue a 307 or 308 here, need // to see how clients (automated & browser) behave when we do wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}"); } // Setup dummy Title, otherwise OutputPage::redirect will fail $title = Title::newFromText('REDIR', NS_MAIN); $this->context->setTitle($title); // Since we only do this redir to change proto, always send a vary header $output->addVaryHeader('X-Forwarded-Proto'); $output->redirect($redirUrl); $output->output(); return; } } if ($title->canExist() && HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = new HTMLFileCache($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$output->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff, assuming user is viewing the // latest revision (which should always be the case for file cache) $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $output->disable(); return; } } // Actually do the work of the request and build up any output $this->performRequest(); // GUI-ify and stash the page output in MediaWiki::doPreOutputCommit() while // ChronologyProtector synchronizes DB positions or slaves accross all datacenters. $buffer = null; $outputWork = function () use($output, &$buffer) { if ($buffer === null) { $buffer = $output->output(true); } return $buffer; }; // Now commit any transactions, so that unreported errors after // output() don't roll back the whole DB transaction and so that // we avoid having both success and error text in the response $this->doPreOutputCommit($outputWork); // Now send the actual output print $outputWork(); }
/** * Get the action that will be executed, not necessarily the one passed * passed through the "action" request parameter. Actions disabled in * $wgActions will be replaced by "nosuchaction". * * @since 1.19 * @param $context IContextSource * @return string: action name */ final public static function getActionName( IContextSource $context ) { global $wgActions; $request = $context->getRequest(); $actionName = $request->getVal( 'action', 'view' ); // Check for disabled actions if ( isset( $wgActions[$actionName] ) && $wgActions[$actionName] === false ) { $actionName = 'nosuchaction'; } // Workaround for bug #20966: inability of IE to provide an action dependent // on which submit button is clicked. if ( $actionName === 'historysubmit' ) { if ( $request->getBool( 'revisiondelete' ) ) { $actionName = 'revisiondelete'; } else { $actionName = 'view'; } } elseif ( $actionName == 'editredlink' ) { $actionName = 'edit'; } // Trying to get a WikiPage for NS_SPECIAL etc. will result // in WikiPage::factory throwing "Invalid or virtual namespace -1 given." // For SpecialPages et al, default to action=view. if ( !$context->canUseWikiPage() ) { return 'view'; } $action = Action::factory( $actionName, $context->getWikiPage(), $context ); if ( $action instanceof Action ) { return $action->getName(); } return 'nosuchaction'; }
/** * Returns the HTML to add to the page for the toolbar * * @param IContextSource $context * @return array */ public static function getDebugInfo(IContextSource $context) { if (!self::$enabled) { return array(); } global $wgVersion, $wgRequestTime; $request = $context->getRequest(); // HHVM's reported memory usage from memory_get_peak_usage() // is not useful when passing false, but we continue passing // false for consistency of historical data in zend. // see: https://github.com/facebook/hhvm/issues/2257#issuecomment-39362246 $realMemoryUsage = wfIsHHVM(); return array('mwVersion' => $wgVersion, 'phpEngine' => wfIsHHVM() ? 'HHVM' : 'PHP', 'phpVersion' => wfIsHHVM() ? HHVM_VERSION : PHP_VERSION, 'gitRevision' => GitInfo::headSHA1(), 'gitBranch' => GitInfo::currentBranch(), 'gitViewUrl' => GitInfo::headViewUrl(), 'time' => microtime(true) - $wgRequestTime, 'log' => self::$log, 'debugLog' => self::$debug, 'queries' => self::$query, 'request' => array('method' => $request->getMethod(), 'url' => $request->getRequestURL(), 'headers' => $request->getAllHeaders(), 'params' => $request->getValues()), 'memory' => $context->getLanguage()->formatSize(memory_get_usage($realMemoryUsage)), 'memoryPeak' => $context->getLanguage()->formatSize(memory_get_peak_usage($realMemoryUsage)), 'includes' => self::getFilesIncluded($context)); }
/** * Returns the HTML to add to the page for the toolbar * * @param $context IContextSource * @return array */ public static function getDebugInfo(IContextSource $context) { if (!self::$enabled) { return array(); } global $wgVersion, $wgRequestTime; $request = $context->getRequest(); return array('mwVersion' => $wgVersion, 'phpVersion' => PHP_VERSION, 'gitRevision' => GitInfo::headSHA1(), 'gitBranch' => GitInfo::currentBranch(), 'gitViewUrl' => GitInfo::headViewUrl(), 'time' => microtime(true) - $wgRequestTime, 'log' => self::$log, 'debugLog' => self::$debug, 'queries' => self::$query, 'request' => array('method' => $request->getMethod(), 'url' => $request->getRequestURL(), 'headers' => $request->getAllHeaders(), 'params' => $request->getValues()), 'memory' => $context->getLanguage()->formatSize(memory_get_usage()), 'memoryPeak' => $context->getLanguage()->formatSize(memory_get_peak_usage()), 'includes' => self::getFilesIncluded($context)); }
private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things $title = Title::makeTitle(NS_MAIN, 'AJAX'); $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; // If the user has forceHTTPS set to true, or if the user // is in a group requiring HTTPS, or if they have the HTTPS // preference set, redirect them to HTTPS. // Note: Do this after $wgTitle is setup, otherwise the hooks run from // isLoggedIn() will do all sorts of weird stuff. if (($request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS()) && $request->getProtocol() == 'http') { $oldUrl = $request->getFullRequestURL(); $redirUrl = str_replace('http://', 'https://', $oldUrl); if ($request->wasPosted()) { // This is weird and we'd hope it almost never happens. This // means that a POST came in via HTTP and policy requires us // redirecting to HTTPS. It's likely such a request is going // to fail due to post data being lost, but let's try anyway // and just log the instance. // // @todo @fixme See if we could issue a 307 or 308 here, need // to see how clients (automated & browser) behave when we do wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}"); } // Setup dummy Title, otherwise OutputPage::redirect will fail $title = Title::newFromText(NS_MAIN, 'REDIR'); $this->context->setTitle($title); $output = $this->context->getOutput(); // Since we only do this redir to change proto, always send a vary header $output->addVaryHeader('X-Forwarded-Proto'); $output->redirect($redirUrl); $output->output(); wfProfileOut(__METHOD__); return; } if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff // Assume we're viewing the latest revision (this should always be the case with file cache) $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } // Actually do the work of the request and build up any output $this->performRequest(); // Either all DB and deferred updates should happen or none. // The later should not be cancelled due to client disconnect. ignore_user_abort(true); // Now commit any transactions, so that unreported errors after // output() don't roll back the whole DB transaction wfGetLBFactory()->commitMasterChanges(); // Output everything! $this->context->getOutput()->output(); wfProfileOut(__METHOD__); }
/** * Save submitted protection form * * @return bool Success */ function save() { # Permission check! if ($this->disabled) { $this->show(); return false; } $request = $this->mContext->getRequest(); $user = $this->mContext->getUser(); $out = $this->mContext->getOutput(); $token = $request->getVal('wpEditToken'); if (!$user->matchEditToken($token, ['protect', $this->mTitle->getPrefixedDBkey()])) { $this->show(['sessionfailure']); return false; } # Create reason string. Use list and/or custom string. $reasonstr = $this->mReasonSelection; if ($reasonstr != 'other' && $this->mReason != '') { // Entry from drop down menu + additional comment $reasonstr .= $this->mContext->msg('colon-separator')->text() . $this->mReason; } elseif ($reasonstr == 'other') { $reasonstr = $this->mReason; } $expiry = []; foreach ($this->mApplicableTypes as $action) { $expiry[$action] = $this->getExpiry($action); if (empty($this->mRestrictions[$action])) { continue; // unprotected } if (!$expiry[$action]) { $this->show(['protect_expiry_invalid']); return false; } if ($expiry[$action] < wfTimestampNow()) { $this->show(['protect_expiry_old']); return false; } } $this->mCascade = $request->getBool('mwProtect-cascade'); $status = $this->mArticle->doUpdateRestrictions($this->mRestrictions, $expiry, $this->mCascade, $reasonstr, $user); if (!$status->isOK()) { $this->show($out->parseInline($status->getWikiText())); return false; } /** * Give extensions a change to handle added form items * * @since 1.19 you can (and you should) return false to abort saving; * you can also return an array of message name and its parameters */ $errorMsg = ''; if (!Hooks::run('ProtectionForm::save', [$this->mArticle, &$errorMsg, $reasonstr])) { if ($errorMsg == '') { $errorMsg = ['hookaborted']; } } if ($errorMsg != '') { $this->show($errorMsg); return false; } WatchAction::doWatchOrUnwatch($request->getCheck('mwProtectWatch'), $this->mTitle, $user); return true; }
/** * Returns the HTML to add to the page for the toolbar * * @param $context IContextSource * @return string */ public static function getDebugHTML(IContextSource $context) { if (!self::$enabled) { return ''; } global $wgVersion, $wgRequestTime; MWDebug::log('MWDebug output complete'); $request = $context->getRequest(); $debugInfo = array('mwVersion' => $wgVersion, 'phpVersion' => PHP_VERSION, 'time' => microtime(true) - $wgRequestTime, 'log' => self::$log, 'debugLog' => self::$debug, 'queries' => self::$query, 'request' => array('method' => $_SERVER['REQUEST_METHOD'], 'url' => $request->getRequestURL(), 'headers' => $request->getAllHeaders(), 'params' => $request->getValues()), 'memory' => $context->getLanguage()->formatSize(memory_get_usage()), 'memoryPeak' => $context->getLanguage()->formatSize(memory_get_peak_usage()), 'includes' => self::getFilesIncluded($context)); // Cannot use OutputPage::addJsConfigVars because those are already outputted // by the time this method is called. $html = Html::inlineScript(ResourceLoader::makeLoaderConditionalScript(ResourceLoader::makeConfigSetScript(array('debugInfo' => $debugInfo)))); return $html; }
/** * Returns a message that notifies the user he/she is looking at * a cached version of the page, including a refresh link. * * @since 1.20 * * @param IContextSource $context * @param boolean $includePurgeLink * * @return string */ public function getCachedNotice(IContextSource $context, $includePurgeLink = true) { if ($this->cacheExpiry < 86400 * 3650) { $message = $context->msg('cachedspecial-viewing-cached-ttl', $context->getLanguage()->formatDuration($this->cacheExpiry))->escaped(); } else { $message = $context->msg('cachedspecial-viewing-cached-ts')->escaped(); } if ($includePurgeLink) { $refreshArgs = $context->getRequest()->getQueryValues(); unset($refreshArgs['title']); $refreshArgs['action'] = 'purge'; $subPage = $context->getTitle()->getFullText(); $subPage = explode('/', $subPage, 2); $subPage = count($subPage) > 1 ? $subPage[1] : false; $message .= ' ' . Linker::link($context->getTitle($subPage), $context->msg('cachedspecial-refresh-now')->escaped(), array(), $refreshArgs); } return $message; }
function __construct(IContextSource $context, $userName = null, $search = '', $including = false, $showAll = false) { $this->mIncluding = $including; $this->mShowAll = $showAll; if ($userName) { $nt = Title::newFromText($userName, NS_USER); if (!is_null($nt)) { $this->mUserName = $nt->getText(); } } if ($search !== '' && !$this->getConfig()->get('MiserMode')) { $this->mSearch = $search; $nt = Title::newFromURL($this->mSearch); if ($nt) { $dbr = wfGetDB(DB_SLAVE); $this->mQueryConds[] = 'LOWER(img_name)' . $dbr->buildLike($dbr->anyString(), strtolower($nt->getDBkey()), $dbr->anyString()); } } if (!$including) { if ($context->getRequest()->getText('sort', 'img_date') == 'img_date') { $this->mDefaultDirection = IndexPager::DIR_DESCENDING; } else { $this->mDefaultDirection = IndexPager::DIR_ASCENDING; } } else { $this->mDefaultDirection = IndexPager::DIR_DESCENDING; } parent::__construct($context); }
/** * Get the key and parameters for the corresponding error message. * * @since 1.22 * @param IContextSource $context * @return array */ public function getPermissionsError(IContextSource $context) { $blocker = $this->getBlocker(); if ($blocker instanceof User) { // local user $blockerUserpage = $blocker->getUserPage(); $link = "[[{$blockerUserpage->getPrefixedText()}|{$blockerUserpage->getText()}]]"; } else { // foreign user $link = $blocker; } $reason = $this->mReason; if ($reason == '') { $reason = $context->msg('blockednoreason')->text(); } /* $ip returns who *is* being blocked, $intended contains who was meant to be blocked. * This could be a username, an IP range, or a single IP. */ $intended = $this->getTarget(); $lang = $context->getLanguage(); return array($this->mAuto ? 'autoblockedtext' : 'blockedtext', $link, $reason, $context->getRequest()->getIP(), $this->getByName(), $this->getId(), $lang->formatExpiry($this->mExpiry), (string) $intended, $lang->userTimeAndDate($this->mTimestamp, $context->getUser())); }
/** * Handler for non-standard (edit/log) entries that need IP data * * @param $context IContextSource * @param $data Array * @return bool */ protected static function onLoggableUserIPData(IContextSource $context, array $data) { $user = $context->getUser(); $request = $context->getRequest(); // Get IP address $ip = $request->getIP(); // Get XFF header $xff = $request->getHeader('X-Forwarded-For'); list($xff_ip, $isSquidOnly) = IP::getClientIPfromXFF($xff); // Get agent $agent = $request->getHeader('User-Agent'); $dbw = wfGetDB(DB_MASTER); $cuc_id = $dbw->nextSequenceValue('cu_changes_cu_id_seq'); $rcRow = array('cuc_id' => $cuc_id, 'cuc_page_id' => $data['pageid'], 'cuc_namespace' => $data['namespace'], 'cuc_title' => $data['title'], 'cuc_minor' => 0, 'cuc_user' => $user->getId(), 'cuc_user_text' => $user->getName(), 'cuc_actiontext' => $data['action'], 'cuc_comment' => $data['comment'], 'cuc_this_oldid' => 0, 'cuc_last_oldid' => 0, 'cuc_type' => RC_LOG, 'cuc_timestamp' => $dbw->timestamp($data['timestamp']), 'cuc_ip' => IP::sanitizeIP($ip), 'cuc_ip_hex' => $ip ? IP::toHex($ip) : null, 'cuc_xff' => !$isSquidOnly ? $xff : '', 'cuc_xff_hex' => $xff_ip && !$isSquidOnly ? IP::toHex($xff_ip) : null, 'cuc_agent' => $agent); $dbw->insert('cu_changes', $rcRow, __METHOD__); return true; }
/** * Edit a Collaboration Hub via the edit API * @param $title Title * @param $displayName string * @param $icon string * @param $colour string * @param $introduction string * @param $footer string * @param $content array * @param $summary string Message key for edit summary * @param $context IContextSource The calling context * @return Status */ public static function edit(Title $title, $displayName, $image, $colour, $introduction, $footer, $content, $summary, IContextSource $context) { $contentBlock = ['display_name' => $displayName, 'introduction' => $introduction, 'footer' => $footer, 'image' => $image, 'colour' => $colour, 'content' => $content]; // TODO Do content $jsonText = FormatJson::encode($contentBlock); if ($jsonText === null) { return Status::newFatal('collaborationkit-hub-edit-tojsonerror'); } // Ensure that a valid context is provided to the API in unit tests $der = new DerivativeContext($context); $request = new DerivativeRequest($context->getRequest(), ['action' => 'edit', 'title' => $title->getFullText(), 'contentmodel' => 'CollaborationHubContent', 'text' => $jsonText, 'summary' => $summary, 'token' => $context->getUser()->getEditToken()], true); $der->setRequest($request); try { $api = new ApiMain($der, true); $api->execute(); } catch (UsageException $e) { return Status::newFatal($context->msg('collaborationkit-hub-edit-apierror', $e->getCodeString())); } return Status::newGood(); }
function __construct(IContextSource $context, $par = null) { $this->like = $context->getRequest()->getText('like'); $this->showbots = $context->getRequest()->getBool('showbots', 0); parent::__construct($context); }
/** * Check if pages can be cached for this request/user * @param IContextSource $context * @param integer $mode One of the HTMLFileCache::MODE_* constants (since 1.28) * @return bool */ public static function useFileCache(IContextSource $context, $mode = self::MODE_NORMAL) { $config = MediaWikiServices::getInstance()->getMainConfig(); if (!$config->get('UseFileCache') && $mode !== self::MODE_REBUILD) { return false; } elseif ($config->get('DebugToolbar')) { wfDebug("HTML file cache skipped. \$wgDebugToolbar on\n"); return false; } // Get all query values $queryVals = $context->getRequest()->getValues(); foreach ($queryVals as $query => $val) { if ($query === 'title' || $query === 'curid') { continue; // note: curid sets title // Normal page view in query form can have action=view. } elseif ($query === 'action' && in_array($val, self::cacheablePageActions())) { continue; // Below are header setting params } elseif ($query === 'maxage' || $query === 'smaxage') { continue; } return false; } $user = $context->getUser(); // Check for non-standard user language; this covers uselang, // and extensions for auto-detecting user language. $ulang = $context->getLanguage(); // Check that there are no other sources of variation if ($user->getId() || $ulang->getCode() !== $config->get('LanguageCode')) { return false; } if ($mode === self::MODE_NORMAL) { if ($user->getNewtalk()) { return false; } } // Allow extensions to disable caching return Hooks::run('HTMLFileCache::useFileCache', [$context]); }
/** * Backend function for confirmEdit() and confirmEditAPI() * @param WikiPage $page * @param $newtext string * @param $section * @param IContextSource $context * @return bool false if the CAPTCHA is rejected, true otherwise */ private function doConfirmEdit(WikiPage $page, $newtext, $section, IContextSource $context) { $request = $context->getRequest(); if ($request->getVal('captchaid')) { $request->setVal('wpCaptchaId', $request->getVal('captchaid')); } if ($request->getVal('captchaword')) { $request->setVal('wpCaptchaWord', $request->getVal('captchaword')); } if ($this->shouldCheck($page, $newtext, $section, $context)) { return $this->passCaptchaLimited(); } else { wfDebug("ConfirmEdit: no need to show captcha.\n"); return true; } }
/** * Just like executePath() but will override global variables and execute * the page in "inclusion" mode. Returns true if the execution was * successful or false if there was no such special page, or a title object * if it was a redirect. * * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang * variables so that the special page will get the context it'd expect on a * normal request, and then restores them to their previous values after. * * @param Title $title * @param IContextSource $context * @return string HTML fragment */ public static function capturePath(Title $title, IContextSource $context) { global $wgTitle, $wgOut, $wgRequest, $wgUser, $wgLang; $main = RequestContext::getMain(); // Save current globals and main context $glob = ['title' => $wgTitle, 'output' => $wgOut, 'request' => $wgRequest, 'user' => $wgUser, 'language' => $wgLang]; $ctx = ['title' => $main->getTitle(), 'output' => $main->getOutput(), 'request' => $main->getRequest(), 'user' => $main->getUser(), 'language' => $main->getLanguage()]; // Override $wgTitle = $title; $wgOut = $context->getOutput(); $wgRequest = $context->getRequest(); $wgUser = $context->getUser(); $wgLang = $context->getLanguage(); $main->setTitle($title); $main->setOutput($context->getOutput()); $main->setRequest($context->getRequest()); $main->setUser($context->getUser()); $main->setLanguage($context->getLanguage()); // The useful part $ret = self::executePath($title, $context, true); // Restore old globals and context $wgTitle = $glob['title']; $wgOut = $glob['output']; $wgRequest = $glob['request']; $wgUser = $glob['user']; $wgLang = $glob['language']; $main->setTitle($ctx['title']); $main->setOutput($ctx['output']); $main->setRequest($ctx['request']); $main->setUser($ctx['user']); $main->setLanguage($ctx['language']); return $ret; }
/** * Get the WebRequest being used for this instance. * IndexPager extends ContextSource as of 1.19. * * @since 0.1 * * @return WebRequest */ public function getRequest() { return $this->context->getRequest(); }
/** * Just like executePath() but will override global variables and execute * the page in "inclusion" mode. Returns true if the execution was * successful or false if there was no such special page, or a title object * if it was a redirect. * * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang * variables so that the special page will get the context it'd expect on a * normal request, and then restores them to their previous values after. * * @param $title Title * @param $context IContextSource * * @return String: HTML fragment */ static function capturePath(Title $title, IContextSource $context) { global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang; // Save current globals $oldTitle = $wgTitle; $oldOut = $wgOut; $oldRequest = $wgRequest; $oldUser = $wgUser; $oldLang = $wgLang; // Set the globals to the current context $wgTitle = $title; $wgOut = $context->getOutput(); $wgRequest = $context->getRequest(); $wgUser = $context->getUser(); $wgLang = $context->getLanguage(); // The useful part $ret = self::executePath($title, $context, true); // And restore the old globals $wgTitle = $oldTitle; $wgOut = $oldOut; $wgRequest = $oldRequest; $wgUser = $oldUser; $wgLang = $oldLang; return $ret; }
/** * Attempt to validate and submit this data to the DB * @param $context IContextSource * @return array( true or error key string, html error msg or null ) */ public function submit(IContextSource $context) { global $wgAuth, $wgAccountRequestThrottle, $wgMemc, $wgContLang; global $wgConfirmAccountRequestFormItems; $formConfig = $wgConfirmAccountRequestFormItems; // convience $reqUser = $this->requester; # Make sure that basic permissions are checked $block = ConfirmAccount::getAccountRequestBlock($reqUser); if ($block) { return array('accountreq_permission_denied', $context->msg('badaccess-group0')->escaped()); } elseif (wfReadOnly()) { return array('accountreq_readonly', $context->msg('badaccess-group0')->escaped()); } # Now create a dummy user ($u) and check if it is valid if ($this->userName === '') { return array('accountreq_no_name', $context->msg('noname')->escaped()); } $u = User::newFromName($this->userName, 'creatable'); if (!$u) { return array('accountreq_invalid_name', $context->msg('noname')->escaped()); } # No request spamming... if ($wgAccountRequestThrottle && $reqUser->isPingLimitable()) { $key = wfMemcKey('acctrequest', 'ip', $this->ip); $value = (int) $wgMemc->get($key); if ($value > $wgAccountRequestThrottle) { return array('accountreq_throttled', $context->msg('acct_request_throttle_hit', $wgAccountRequestThrottle)->text()); } } # Make sure user agrees to policy here if ($formConfig['TermsOfService']['enabled'] && !$this->tosAccepted) { return array('acct_request_skipped_tos', $context->msg('requestaccount-agree')->escaped()); } # Validate email address if (!Sanitizer::validateEmail($this->email)) { return array('acct_request_invalid_email', $context->msg('invalidemailaddress')->escaped()); } # Check if biography is long enough if ($formConfig['Biography']['enabled'] && str_word_count($this->bio) < $formConfig['Biography']['minWords']) { $minWords = $formConfig['Biography']['minWords']; return array('acct_request_short_bio', $context->msg('requestaccount-tooshort')->numParams($minWords)->text()); } # Per security reasons, file dir cannot be pulled from client, # so ask them to resubmit it then... # If the extra fields are off, then uploads are off $allowFiles = $formConfig['CV']['enabled']; if ($allowFiles && $this->attachmentPrevName && !$this->attachmentSrcName) { # If the user is submitting forgotAttachment as true with no file, # then they saw the notice and choose not to re-select the file. # Assume that they don't want to send one anymore. if (!$this->attachmentDidNotForget) { $this->attachmentPrevName = ''; $this->attachmentDidNotForget = 0; return array(false, $context->msg('requestaccount-resub')->escaped()); } } # Check if already in use if (0 != $u->idForName() || $wgAuth->userExists($u->getName())) { return array('accountreq_username_exists', $context->msg('userexists')->escaped()); } # Set email and real name $u->setEmail($this->email); $u->setRealName($this->realName); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); // ready to acquire locks # Check pending accounts for name use if (!UserAccountRequest::acquireUsername($u->getName())) { $dbw->rollback(); return array('accountreq_username_pending', $context->msg('requestaccount-inuse')->escaped()); } # Check if someone else has an account request with the same email if (!UserAccountRequest::acquireEmail($u->getEmail())) { $dbw->rollback(); return array('acct_request_email_exists', $context->msg('requestaccount-emaildup')->escaped()); } # Process upload... if ($allowFiles && $this->attachmentSrcName) { global $wgAccountRequestExts, $wgConfirmAccountFSRepos; $ext = explode('.', $this->attachmentSrcName); $finalExt = $ext[count($ext) - 1]; # File must have size. if (trim($this->attachmentSrcName) == '' || empty($this->attachmentSize)) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_empty_file', $context->msg('emptyfile')->escaped()); } # Look at the contents of the file; if we can recognize the # type but it's corrupt or data of the wrong type, we should # probably not accept it. if (!in_array($finalExt, $wgAccountRequestExts)) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_bad_file_ext', $context->msg('requestaccount-exts')->escaped()); } $veri = ConfirmAccount::verifyAttachment($this->attachmentTempPath, $finalExt); if (!$veri->isGood()) { $this->attachmentPrevName = ''; $dbw->rollback(); return array('acct_request_corrupt_file', $context->msg('verification-error')->escaped()); } # Start a transaction, move file from temp to account request directory. $repo = new FSRepo($wgConfirmAccountFSRepos['accountreqs']); $key = sha1_file($this->attachmentTempPath) . '.' . $finalExt; $pathRel = UserAccountRequest::relPathFromKey($key); $triplet = array($this->attachmentTempPath, 'public', $pathRel); $status = $repo->storeBatch(array($triplet), FSRepo::OVERWRITE_SAME); // save! if (!$status->isOk()) { $dbw->rollback(); return array('acct_request_file_store_error', $context->msg('filecopyerror', $this->attachmentTempPath, $pathRel)->escaped()); } } $expires = null; // passed by reference $token = ConfirmAccount::getConfirmationToken($u, $expires); # Insert into pending requests... $req = UserAccountRequest::newFromArray(array('name' => $u->getName(), 'email' => $u->getEmail(), 'real_name' => $u->getRealName(), 'registration' => $this->registration, 'bio' => $this->bio, 'notes' => $this->notes, 'urls' => $this->urls, 'filename' => isset($this->attachmentSrcName) ? $this->attachmentSrcName : null, 'type' => $this->type, 'areas' => $this->areas, 'storage_key' => isset($key) ? $key : null, 'comment' => '', 'email_token' => md5($token), 'email_token_expires' => $expires, 'ip' => $this->ip, 'xff' => $this->xff, 'agent' => $this->agent)); $req->insertOn(); # Send confirmation, required! $result = ConfirmAccount::sendConfirmationMail($u, $this->ip, $token, $expires); if (!$result->isOK()) { $dbw->rollback(); // nevermind if (isset($repo) && isset($pathRel)) { // remove attachment $repo->cleanupBatch(array(array('public', $pathRel))); } $param = $context->getOutput()->parse($result->getWikiText()); return array('acct_request_mail_failed', $context->msg('mailerror')->rawParams($param)->escaped()); } $dbw->commit(); # Clear cache for notice of how many account requests there are ConfirmAccount::clearAccountRequestCountCache(); # No request spamming... if ($wgAccountRequestThrottle && $reqUser->isPingLimitable()) { $ip = $context->getRequest()->getIP(); $key = wfMemcKey('acctrequest', 'ip', $ip); $value = $wgMemc->incr($key); if (!$value) { $wgMemc->set($key, 1, 86400); } } # Done! return array(true, null); }
/** * @param $user User * @param $context IContextSource * @param $defaultPreferences * @return void */ static function profilePreferences( $user, IContextSource $context, &$defaultPreferences ) { global $wgAuth, $wgContLang, $wgParser, $wgCookieExpiration, $wgLanguageCode, $wgDisableTitleConversion, $wgDisableLangConversion, $wgMaxSigChars, $wgEnableEmail, $wgEmailConfirmToEdit, $wgEnableUserEmail, $wgEmailAuthentication, $wgEnotifWatchlist, $wgEnotifUserTalk, $wgEnotifRevealEditorAddress, $wgSecureLogin; // retrieving user name for GENDER and misc. $userName = $user->getName(); ## User info ##################################### // Information panel $defaultPreferences['username'] = array( 'type' => 'info', 'label-message' => array( 'username', $userName ), 'default' => $userName, 'section' => 'personal/info', ); $defaultPreferences['userid'] = array( 'type' => 'info', 'label-message' => array( 'uid', $userName ), 'default' => $user->getId(), 'section' => 'personal/info', ); # Get groups to which the user belongs $userEffectiveGroups = $user->getEffectiveGroups(); $userGroups = $userMembers = array(); foreach ( $userEffectiveGroups as $ueg ) { if ( $ueg == '*' ) { // Skip the default * group, seems useless here continue; } $groupName = User::getGroupName( $ueg ); $userGroups[] = User::makeGroupLinkHTML( $ueg, $groupName ); $memberName = User::getGroupMember( $ueg, $userName ); $userMembers[] = User::makeGroupLinkHTML( $ueg, $memberName ); } asort( $userGroups ); asort( $userMembers ); $lang = $context->getLanguage(); $defaultPreferences['usergroups'] = array( 'type' => 'info', 'label' => $context->msg( 'prefs-memberingroups' )->numParams( count( $userGroups ) )->params( $userName )->parse(), 'default' => $context->msg( 'prefs-memberingroups-type', $lang->commaList( $userGroups ), $lang->commaList( $userMembers ) )->plain(), 'raw' => true, 'section' => 'personal/info', ); $editCount = Linker::link( SpecialPage::getTitleFor( "Contributions", $userName ), $lang->formatNum( $user->getEditCount() ) ); $defaultPreferences['editcount'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'prefs-edits', 'default' => $editCount, 'section' => 'personal/info', ); if ( $user->getRegistration() ) { $displayUser = $context->getUser(); $userRegistration = $user->getRegistration(); $defaultPreferences['registrationdate'] = array( 'type' => 'info', 'label-message' => 'prefs-registration', 'default' => $context->msg( 'prefs-registration-date-time', $lang->userTimeAndDate( $userRegistration, $displayUser ), $lang->userDate( $userRegistration, $displayUser ), $lang->userTime( $userRegistration, $displayUser ) )->parse(), 'section' => 'personal/info', ); } $canViewPrivateInfo = $user->isAllowed( 'viewmyprivateinfo' ); $canEditPrivateInfo = $user->isAllowed( 'editmyprivateinfo' ); // Actually changeable stuff $defaultPreferences['realname'] = array( // (not really "private", but still shouldn't be edited without permission) 'type' => $canEditPrivateInfo && $wgAuth->allowPropChange( 'realname' ) ? 'text' : 'info', 'default' => $user->getRealName(), 'section' => 'personal/info', 'label-message' => 'yourrealname', 'help-message' => 'prefs-help-realname', ); if ( $canEditPrivateInfo && $wgAuth->allowPasswordChange() ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangePassword' ), $context->msg( 'prefs-resetpass' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $defaultPreferences['password'] = array( 'type' => 'info', 'raw' => true, 'default' => $link, 'label-message' => 'yourpassword', 'section' => 'personal/info', ); } if ( $wgCookieExpiration > 0 ) { $defaultPreferences['rememberpassword'] = array( 'type' => 'toggle', 'label' => $context->msg( 'tog-rememberpassword' )->numParams( ceil( $wgCookieExpiration / ( 3600 * 24 ) ) )->text(), 'section' => 'personal/info', ); } // Only show preferhttps if secure login is turned on if ( $wgSecureLogin && wfCanIPUseHTTPS( $context->getRequest()->getIP() ) ) { $defaultPreferences['prefershttps'] = array( 'type' => 'toggle', 'label-message' => 'tog-prefershttps', 'help-message' => 'prefs-help-prefershttps', 'section' => 'personal/info' ); } // Language $languages = Language::fetchLanguageNames( null, 'mw' ); if ( !array_key_exists( $wgLanguageCode, $languages ) ) { $languages[$wgLanguageCode] = $wgLanguageCode; } ksort( $languages ); $options = array(); foreach ( $languages as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['language'] = array( 'type' => 'select', 'section' => 'personal/i18n', 'options' => $options, 'label-message' => 'yourlanguage', ); $defaultPreferences['gender'] = array( 'type' => 'radio', 'section' => 'personal/i18n', 'options' => array( $context->msg( 'parentheses', $context->msg( 'gender-unknown' )->text() )->text() => 'unknown', $context->msg( 'gender-female' )->text() => 'female', $context->msg( 'gender-male' )->text() => 'male', ), 'label-message' => 'yourgender', 'help-message' => 'prefs-help-gender', ); // see if there are multiple language variants to choose from if ( !$wgDisableLangConversion ) { foreach ( LanguageConverter::$languagesWithVariants as $langCode ) { if ( $langCode == $wgContLang->getCode() ) { $variants = $wgContLang->getVariants(); if ( count( $variants ) <= 1 ) { continue; } $variantArray = array(); foreach ( $variants as $v ) { $v = str_replace( '_', '-', strtolower( $v ) ); $variantArray[$v] = $lang->getVariantname( $v, false ); } $options = array(); foreach ( $variantArray as $code => $name ) { $display = wfBCP47( $code ) . ' - ' . $name; $options[$display] = $code; } $defaultPreferences['variant'] = array( 'label-message' => 'yourvariant', 'type' => 'select', 'options' => $options, 'section' => 'personal/i18n', 'help-message' => 'prefs-help-variant', ); if ( !$wgDisableTitleConversion ) { $defaultPreferences['noconvertlink'] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => 'tog-noconvertlink', ); } } else { $defaultPreferences["variant-$langCode"] = array( 'type' => 'api', ); } } } // Stuff from Language::getExtraUserToggles() // FIXME is this dead code? $extraUserToggles doesn't seem to be defined for any language $toggles = $wgContLang->getExtraUserToggles(); foreach ( $toggles as $toggle ) { $defaultPreferences[$toggle] = array( 'type' => 'toggle', 'section' => 'personal/i18n', 'label-message' => "tog-$toggle", ); } // show a preview of the old signature first $oldsigWikiText = $wgParser->preSaveTransform( "~~~", $context->getTitle(), $user, ParserOptions::newFromContext( $context ) ); $oldsigHTML = $context->getOutput()->parseInline( $oldsigWikiText, true, true ); $defaultPreferences['oldsig'] = array( 'type' => 'info', 'raw' => true, 'label-message' => 'tog-oldsig', 'default' => $oldsigHTML, 'section' => 'personal/signature', ); $defaultPreferences['nickname'] = array( 'type' => $wgAuth->allowPropChange( 'nickname' ) ? 'text' : 'info', 'maxlength' => $wgMaxSigChars, 'label-message' => 'yournick', 'validation-callback' => array( 'Preferences', 'validateSignature' ), 'section' => 'personal/signature', 'filter-callback' => array( 'Preferences', 'cleanSignature' ), ); $defaultPreferences['fancysig'] = array( 'type' => 'toggle', 'label-message' => 'tog-fancysig', 'help-message' => 'prefs-help-signature', // show general help about signature at the bottom of the section 'section' => 'personal/signature' ); ## Email stuff if ( $wgEnableEmail ) { if ( $canViewPrivateInfo ) { $helpMessages[] = $wgEmailConfirmToEdit ? 'prefs-help-email-required' : 'prefs-help-email'; if ( $wgEnableUserEmail ) { // additional messages when users can send email to each other $helpMessages[] = 'prefs-help-email-others'; } $emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : ''; if ( $canEditPrivateInfo && $wgAuth->allowPropChange( 'emailaddress' ) ) { $link = Linker::link( SpecialPage::getTitleFor( 'ChangeEmail' ), $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->escaped(), array(), array( 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ) ); $emailAddress .= $emailAddress == '' ? $link : ( $context->msg( 'word-separator' )->plain() . $context->msg( 'parentheses' )->rawParams( $link )->plain() ); } $defaultPreferences['emailaddress'] = array( 'type' => 'info', 'raw' => true, 'default' => $emailAddress, 'label-message' => 'youremail', 'section' => 'personal/email', 'help-messages' => $helpMessages, # 'cssclass' chosen below ); } $disableEmailPrefs = false; if ( $wgEmailAuthentication ) { $emailauthenticationclass = 'mw-email-not-authenticated'; if ( $user->getEmail() ) { if ( $user->getEmailAuthenticationTimestamp() ) { // date and time are separate parameters to facilitate localisation. // $time is kept for backward compat reasons. // 'emailauthenticated' is also used in SpecialConfirmemail.php $displayUser = $context->getUser(); $emailTimestamp = $user->getEmailAuthenticationTimestamp(); $time = $lang->userTimeAndDate( $emailTimestamp, $displayUser ); $d = $lang->userDate( $emailTimestamp, $displayUser ); $t = $lang->userTime( $emailTimestamp, $displayUser ); $emailauthenticated = $context->msg( 'emailauthenticated', $time, $d, $t )->parse() . '<br />'; $disableEmailPrefs = false; $emailauthenticationclass = 'mw-email-authenticated'; } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '<br />' . Linker::linkKnown( SpecialPage::getTitleFor( 'Confirmemail' ), $context->msg( 'emailconfirmlink' )->escaped() ) . '<br />'; $emailauthenticationclass = "mw-email-not-authenticated"; } } else { $disableEmailPrefs = true; $emailauthenticated = $context->msg( 'noemailprefs' )->escaped(); $emailauthenticationclass = 'mw-email-none'; } if ( $canViewPrivateInfo ) { $defaultPreferences['emailauthentication'] = array( 'type' => 'info', 'raw' => true, 'section' => 'personal/email', 'label-message' => 'prefs-emailconfirm-label', 'default' => $emailauthenticated, # Apply the same CSS class used on the input to the message: 'cssclass' => $emailauthenticationclass, ); $defaultPreferences['emailaddress']['cssclass'] = $emailauthenticationclass; } } if ( $wgEnableUserEmail && $user->isAllowed( 'sendemail' ) ) { $defaultPreferences['disablemail'] = array( 'type' => 'toggle', 'invert' => true, 'section' => 'personal/email', 'label-message' => 'allowemail', 'disabled' => $disableEmailPrefs, ); $defaultPreferences['ccmeonemails'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-ccmeonemails', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifWatchlist ) { $defaultPreferences['enotifwatchlistpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifwatchlistpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk ) { $defaultPreferences['enotifusertalkpages'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifusertalkpages', 'disabled' => $disableEmailPrefs, ); } if ( $wgEnotifUserTalk || $wgEnotifWatchlist ) { $defaultPreferences['enotifminoredits'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifminoredits', 'disabled' => $disableEmailPrefs, ); if ( $wgEnotifRevealEditorAddress ) { $defaultPreferences['enotifrevealaddr'] = array( 'type' => 'toggle', 'section' => 'personal/email', 'label-message' => 'tog-enotifrevealaddr', 'disabled' => $disableEmailPrefs, ); } } } }
/** * @param $title Title * @param $summary string * @param $context IContextSource * @todo rework this to use a generic CollaborationList editor function once it exists */ public static function postMemberList(Title $title, $summary, IContextSource $context) { $username = $context->getUser()->getName(); $collabList = self::makeMemberList($username, $context->msg('collaborationkit-hub-members-description')); // Ensure that a valid context is provided to the API in unit tests $der = new DerivativeContext($context); $request = new DerivativeRequest($context->getRequest(), ['action' => 'edit', 'title' => $title->getFullText(), 'contentmodel' => 'CollaborationListContent', 'contentformat' => 'application/json', 'text' => $collabList->serialize(), 'summary' => $summary, 'token' => $context->getUser()->getEditToken()], true); $der->setRequest($request); try { $api = new ApiMain($der, true); $api->execute(); } catch (UsageException $e) { return Status::newFatal($context->msg('collaborationkit-hub-edit-apierror', $e->getCodeString())); } return Status::newGood(); }