* Initialize the main Article object for "standard" actions (view, etc)
* Create an Article object for the page, following redirects if needed.
*
- * @return mixed An Article, or a string to redirect to another URL
+ * @return Article|string An Article, or a string to redirect to another URL
*/
private function initializeArticle() {
-
$title = $this->context->getTitle();
if ( $this->context->canUseWikiPage() ) {
// Try to use request context wiki page, as there
// is already data from db saved in per process
// cache there from this->getAction() call.
$page = $this->context->getWikiPage();
- $article = Article::newFromWikiPage( $page, $this->context );
} else {
// This case should not happen, but just in case.
- $article = Article::newFromTitle( $title, $this->context );
- $this->context->setWikiPage( $article->getPage() );
+ // @TODO: remove this or use an exception
+ $page = WikiPage::factory( $title );
+ $this->context->setWikiPage( $page );
+ wfWarn( "RequestContext::canUseWikiPage() returned false" );
}
+ // Make GUI wrapper for the WikiPage
+ $article = Article::newFromWikiPage( $page, $this->context );
+
// Skip some unnecessary code if the content model doesn't support redirects
if ( !ContentHandler::getForTitle( $title )->supportsRedirects() ) {
return $article;
// Namespace might change when using redirects
// Check for redirects ...
$action = $request->getVal( 'action', 'view' );
- $file = ( $title->getNamespace() == NS_FILE ) ? $article->getFile() : null;
+ $file = ( $page instanceof WikiFilePage ) ? $page->getFile() : null;
if ( ( $action == 'view' || $action == 'render' ) // ... for actions that show content
&& !$request->getVal( 'oldid' ) // ... and are not old revisions
&& !$request->getVal( 'diff' ) // ... and not when showing diff
Hooks::run( 'InitializeArticleMaybeRedirect',
array( &$title, &$request, &$ignoreRedirect, &$target, &$article ) );
+ $page = $article->getPage(); // reflect any hook changes
// Follow redirects only for... redirects.
// If $target is set, then a hook wanted to redirect.
- if ( !$ignoreRedirect && ( $target || $article->isRedirect() ) ) {
+ if ( !$ignoreRedirect && ( $target || $page->isRedirect() ) ) {
// Is the target already set by an extension?
- $target = $target ? $target : $article->followRedirect();
+ $target = $target ? $target : $page->followRedirect();
if ( is_string( $target ) ) {
if ( !$this->config->get( 'DisableHardRedirects' ) ) {
// we'll need to redirect
}
if ( is_object( $target ) ) {
// Rewrite environment to redirected article
- $rarticle = Article::newFromTitle( $target, $this->context );
- $rarticle->loadPageData();
- if ( $rarticle->exists() || ( is_object( $file ) && !$file->isLocal() ) ) {
+ $rpage = WikiPage::factory( $target );
+ $rpage->loadPageData();
+ if ( $rpage->exists() || ( is_object( $file ) && !$file->isLocal() ) ) {
+ $rarticle = Article::newFromWikiPage( $rpage, $this->context );
$rarticle->setRedirectedFrom( $title );
+
$article = $rarticle;
$this->context->setTitle( $target );
$this->context->setWikiPage( $article->getPage() );
}
}
} else {
+ // Article may have been changed by hook
$this->context->setTitle( $article->getTitle() );
$this->context->setWikiPage( $article->getPage() );
}
$config = $context->getConfig();
$factory = wfGetLBFactory();
- // Check if any transaction was too big
- $limit = $config->get( 'MaxUserDBWriteDuration' );
- $factory->forEachLB( function ( LoadBalancer $lb ) use ( $limit ) {
- $lb->forEachOpenConnection( function ( IDatabase $db ) use ( $limit ) {
- $time = $db->pendingWriteQueryDuration();
- if ( $limit > 0 && $time > $limit ) {
- throw new DBTransactionError(
- $db,
- wfMessage( 'transaction-duration-limit-exceeded', $time, $limit )->text()
- );
- }
- } );
- } );
// Commit all changes
- $factory->commitMasterChanges( __METHOD__ );
+ $factory->commitMasterChanges(
+ __METHOD__,
+ // Abort if any transaction was too big
+ array( 'maxWriteDuration' => $config->get( 'MaxUserDBWriteDuration' ) )
+ );
// Record ChronologyProtector positions
$factory->shutdown();
wfDebug( __METHOD__ . ': all transactions committed' );
DeferredUpdates::doUpdates( 'enqueue', DeferredUpdates::PRESEND );
wfDebug( __METHOD__ . ': pre-send deferred updates completed' );
- // Set a cookie to tell all CDN edge nodes to "stick" the user to the
- // DC that handles this POST request (e.g. the "master" data center)
+ // Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this
+ // POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so
+ // ChronologyProtector works for cacheable URLs.
$request = $context->getRequest();
if ( $request->wasPosted() && $factory->hasOrMadeRecentMasterChanges() ) {
$expires = time() + $config->get( 'DataCenterUpdateStickTTL' );
$request->response()->setCookie( 'UseCDNCache', 'false', $expires, $options );
}
- // Avoid letting a few seconds of slave lag cause a month of stale data
+ // Avoid letting a few seconds of slave lag cause a month of stale data. This logic is
+ // also intimately related to the value of $wgCdnReboundPurgeDelay.
if ( $factory->laggedSlaveUsed() ) {
$maxAge = $config->get( 'CdnMaxageLagged' );
$context->getOutput()->lowerCdnMaxage( $maxAge );
if (
$request->getProtocol() == 'http' &&
(
- $request->getSession()->shouldForceHTTPS() ||
- // Check the cookie manually, for paranoia
$request->getCookie( 'forceHTTPS', '' ) ||
- // check for prefixed version that was used for a time in older MW versions
+ // check for prefixed version for currently logged in users
$request->getCookie( 'forceHTTPS' ) ||
// Avoid checking the user and groups unless it's enabled.
(