Update oyejorge/less.php to 1.7.0.10
[lhc/web/wiklou.git] / includes / MediaWiki.php
index be0073d..8385a06 100644 (file)
@@ -379,23 +379,26 @@ class MediaWiki {
         * 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;
@@ -406,7 +409,7 @@ class MediaWiki {
                // 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
@@ -419,12 +422,13 @@ class MediaWiki {
 
                        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
@@ -433,16 +437,19 @@ class MediaWiki {
                                }
                                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() );
                        }
@@ -458,7 +465,6 @@ class MediaWiki {
         * @param Title $requestTitle The original title, before any redirects were applied
         */
        private function performAction( Page $page, Title $requestTitle ) {
-
                $request = $this->context->getRequest();
                $output = $this->context->getOutput();
                $title = $this->context->getTitle();
@@ -471,10 +477,16 @@ class MediaWiki {
                }
 
                $act = $this->getAction();
-
                $action = Action::factory( $act, $page, $this->context );
 
                if ( $action instanceof Action ) {
+                       // Narrow DB query expectations for this HTTP request
+                       $trxLimits = $this->config->get( 'TrxProfilerLimits' );
+                       $trxProfiler = Profiler::instance()->getTransactionProfiler();
+                       if ( $request->wasPosted() && !$action->doesWrites() ) {
+                               $trxProfiler->setExpectations( $trxLimits['POST-nonwrite'], __METHOD__ );
+                       }
+
                        # Let CDN cache things if we can purge them.
                        if ( $this->config->get( 'UseSquid' ) &&
                                in_array(
@@ -494,7 +506,6 @@ class MediaWiki {
                        $output->setStatusCode( 404 );
                        $output->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
                }
-
        }
 
        /**
@@ -540,21 +551,12 @@ class MediaWiki {
                $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();
+               $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' );
@@ -562,15 +564,19 @@ class MediaWiki {
                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( 'UseDC', 'master', $expires, array( 'prefix' => '' ) );
+                       $options = array( 'prefix' => '' );
+                       $request->response()->setCookie( 'UseDC', 'master', $expires, $options );
+                       $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 );
@@ -623,7 +629,7 @@ class MediaWiki {
        }
 
        private function main() {
-               global $wgTitle, $wgTrxProfilerLimits;
+               global $wgTitle;
 
                $request = $this->context->getRequest();
 
@@ -647,13 +653,14 @@ class MediaWiki {
                $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->wasPosted() ) {
-                       $trxProfiler->setExpectations( $wgTrxProfilerLimits['POST'], __METHOD__ );
+                       $trxProfiler->setExpectations( $trxLimits['POST'], __METHOD__ );
                } else {
-                       $trxProfiler->setExpectations( $wgTrxProfilerLimits['GET'], __METHOD__ );
+                       $trxProfiler->setExpectations( $trxLimits['GET'], __METHOD__ );
                }
 
                // If the user has forceHTTPS set to true, or if the user
@@ -664,8 +671,10 @@ class MediaWiki {
                if (
                        $request->getProtocol() == 'http' &&
                        (
+                               $request->getSession()->shouldForceHTTPS() ||
+                               // Check the cookie manually, for paranoia
                                $request->getCookie( 'forceHTTPS', '' ) ||
-                               // check for prefixed version for currently logged in users
+                               // check for prefixed version that was used for a time in older MW versions
                                $request->getCookie( 'forceHTTPS' ) ||
                                // Avoid checking the user and groups unless it's enabled.
                                (
@@ -741,7 +750,7 @@ class MediaWiki {
         */
        public function restInPeace( $mode = 'fast' ) {
                // Assure deferred updates are not in the main transaction
-               wfGetLBFactory()->commitMasterChanges();
+               wfGetLBFactory()->commitMasterChanges( __METHOD__ );
 
                // Ignore things like master queries/connections on GET requests
                // as long as they are in deferred updates (which catch errors).
@@ -764,7 +773,7 @@ class MediaWiki {
 
                // Commit and close up!
                $factory = wfGetLBFactory();
-               $factory->commitMasterChanges();
+               $factory->commitMasterChanges( __METHOD__ );
                $factory->shutdown( LBFactory::SHUTDOWN_NO_CHRONPROT );
 
                wfDebug( "Request ended normally\n" );