Merge "Fix CONTENT-LENGTH header in WebRequestUpload"
[lhc/web/wiklou.git] / includes / diff / DifferenceEngine.php
index 2c63dfb..d588d51 100644 (file)
@@ -388,7 +388,8 @@ class DifferenceEngine extends ContextSource {
                $rdel = $this->revisionDeleteLink( $this->mNewRev );
 
                # Allow extensions to define their own revision tools
-               Hooks::run( 'DiffRevisionTools', array( $this->mNewRev, &$revisionTools, $this->mOldRev ) );
+               Hooks::run( 'DiffRevisionTools',
+                       array( $this->mNewRev, &$revisionTools, $this->mOldRev, $user ) );
                $formattedRevisionTools = array();
                // Put each one in parentheses (poor man's button)
                foreach ( $revisionTools as $key => $tool ) {
@@ -432,7 +433,7 @@ class DifferenceEngine extends ContextSource {
                                        array( $msg ) );
                        } else {
                                # Give explanation and add a link to view the diff...
-                               $query = $this->getRequest()->appendQueryValue( 'unhide', '1', true );
+                               $query = $this->getRequest()->appendQueryValue( 'unhide', '1' );
                                $link = $this->getTitle()->getFullURL( $query );
                                $msg = $suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff';
                                $out->wrapWikiMsg(
@@ -458,75 +459,93 @@ class DifferenceEngine extends ContextSource {
        }
 
        /**
-        * Get a link to mark the change as patrolled, or '' if there's either no
-        * revision to patrol or the user is not allowed to to it.
+        * Build a link to mark a change as patrolled.
+        *
+        * Returns empty string if there's either no revision to patrol or the user is not allowed to.
         * Side effect: When the patrol link is build, this method will call
         * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
         *
-        * @return string
+        * @return string HTML or empty string
         */
        protected function markPatrolledLink() {
+               if ( $this->mMarkPatrolledLink === null ) {
+                       $linkInfo = $this->getMarkPatrolledLinkInfo();
+                       // If false, there is no patrol link needed/allowed
+                       if ( !$linkInfo ) {
+                               $this->mMarkPatrolledLink = '';
+                       } else {
+                               $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown(
+                                       $this->mNewPage,
+                                       $this->msg( 'markaspatrolleddiff' )->escaped(),
+                                       array(),
+                                       array(
+                                               'action' => 'markpatrolled',
+                                               'rcid' => $linkInfo['rcid'],
+                                               'token' => $linkInfo['token'],
+                                       )
+                               ) . ']</span>';
+                       }
+               }
+               return $this->mMarkPatrolledLink;
+       }
+
+       /**
+        * Returns an array of meta data needed to build a "mark as patrolled" link and
+        * adds the mediawiki.page.patrol.ajax to the output.
+        *
+        * @return array|false An array of meta data for a patrol link (rcid & token)
+        *  or false if no link is needed
+        */
+       protected function getMarkPatrolledLinkInfo() {
                global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
+
                $user = $this->getUser();
 
-               if ( $this->mMarkPatrolledLink === null ) {
-                       // Prepare a change patrol link, if applicable
-                       if (
-                               // Is patrolling enabled and the user allowed to?
-                               $wgUseRCPatrol && $this->mNewPage->quickUserCan( 'patrol', $user ) &&
-                               // Only do this if the revision isn't more than 6 hours older
-                               // than the Max RC age (6h because the RC might not be cleaned out regularly)
-                               RecentChange::isInRCLifespan( $this->mNewRev->getTimestamp(), 21600 )
-                       ) {
-                               // Look for an unpatrolled change corresponding to this diff
-
-                               $db = wfGetDB( DB_SLAVE );
-                               $change = RecentChange::newFromConds(
-                                       array(
-                                               'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
-                                               'rc_this_oldid' => $this->mNewid,
-                                               'rc_patrolled' => 0
-                                       ),
-                                       __METHOD__,
-                                       array( 'USE INDEX' => 'rc_timestamp' )
-                               );
+               // Prepare a change patrol link, if applicable
+               if (
+                       // Is patrolling enabled and the user allowed to?
+                       $wgUseRCPatrol && $this->mNewPage->quickUserCan( 'patrol', $user ) &&
+                       // Only do this if the revision isn't more than 6 hours older
+                       // than the Max RC age (6h because the RC might not be cleaned out regularly)
+                       RecentChange::isInRCLifespan( $this->mNewRev->getTimestamp(), 21600 )
+               ) {
+                       // Look for an unpatrolled change corresponding to this diff
+                       $db = wfGetDB( DB_SLAVE );
+                       $change = RecentChange::newFromConds(
+                               array(
+                                       'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
+                                       'rc_this_oldid' => $this->mNewid,
+                                       'rc_patrolled' => 0
+                               ),
+                               __METHOD__
+                       );
 
-                               if ( $change && !$change->getPerformer()->equals( $user ) ) {
-                                       $rcid = $change->getAttribute( 'rc_id' );
-                               } else {
-                                       // None found or the page has been created by the current user.
-                                       // If the user could patrol this it already would be patrolled
-                                       $rcid = 0;
+                       if ( $change && !$change->getPerformer()->equals( $user ) ) {
+                               $rcid = $change->getAttribute( 'rc_id' );
+                       } else {
+                               // None found or the page has been created by the current user.
+                               // If the user could patrol this it already would be patrolled
+                               $rcid = 0;
+                       }
+                       // Build the link
+                       if ( $rcid ) {
+                               $this->getOutput()->preventClickjacking();
+                               if ( $wgEnableAPI && $wgEnableWriteAPI
+                                       && $user->isAllowed( 'writeapi' )
+                               ) {
+                                       $this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' );
                                }
-                               // Build the link
-                               if ( $rcid ) {
-                                       $this->getOutput()->preventClickjacking();
-                                       if ( $wgEnableAPI && $wgEnableWriteAPI
-                                               && $user->isAllowed( 'writeapi' )
-                                       ) {
-                                               $this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' );
-                                       }
 
-                                       $token = $user->getEditToken( $rcid );
-                                       $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown(
-                                               $this->mNewPage,
-                                               $this->msg( 'markaspatrolleddiff' )->escaped(),
-                                               array(),
-                                               array(
-                                                       'action' => 'markpatrolled',
-                                                       'rcid' => $rcid,
-                                                       'token' => $token,
-                                               )
-                                       ) . ']</span>';
-                               } else {
-                                       $this->mMarkPatrolledLink = '';
-                               }
-                       } else {
-                               $this->mMarkPatrolledLink = '';
+                               $token = $user->getEditToken( $rcid );
+                               return array(
+                                       'rcid' => $rcid,
+                                       'token' => $token,
+                               );
                        }
                }
 
-               return $this->mMarkPatrolledLink;
+               // No mark as patrolled link applicable
+               return false;
        }
 
        /**
@@ -681,40 +700,36 @@ class DifferenceEngine extends ContextSource {
         * @return mixed (string/false)
         */
        public function getDiffBody() {
-               global $wgMemc;
                $this->mCacheHit = true;
                // Check if the diff should be hidden from this user
                if ( !$this->loadRevisionData() ) {
-
                        return false;
                } elseif ( $this->mOldRev &&
                        !$this->mOldRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
                ) {
-
                        return false;
                } elseif ( $this->mNewRev &&
                        !$this->mNewRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
                ) {
-
                        return false;
                }
                // Short-circuit
                if ( $this->mOldRev === false || ( $this->mOldRev && $this->mNewRev
                        && $this->mOldRev->getID() == $this->mNewRev->getID() )
                ) {
-
                        return '';
                }
                // Cacheable?
                $key = false;
+               $cache = ObjectCache::getMainWANInstance();
                if ( $this->mOldid && $this->mNewid ) {
                        $key = $this->getDiffBodyCacheKey();
 
                        // Try cache
                        if ( !$this->mRefreshCache ) {
-                               $difftext = $wgMemc->get( $key );
+                               $difftext = $cache->get( $key );
                                if ( $difftext ) {
-                                       wfIncrStats( 'diff_cache_hit' );
+                                       wfIncrStats( 'diff_cache.hit' );
                                        $difftext = $this->localiseLineNumbers( $difftext );
                                        $difftext .= "\n<!-- diff cache key $key -->\n";
 
@@ -726,7 +741,6 @@ class DifferenceEngine extends ContextSource {
 
                // Loadtext is permission safe, this just clears out the diff
                if ( !$this->loadText() ) {
-
                        return false;
                }
 
@@ -734,12 +748,12 @@ class DifferenceEngine extends ContextSource {
 
                // Save to cache for 7 days
                if ( !Hooks::run( 'AbortDiffCache', array( &$this ) ) ) {
-                       wfIncrStats( 'diff_uncacheable' );
+                       wfIncrStats( 'diff_cache.uncacheable' );
                } elseif ( $key !== false && $difftext !== false ) {
-                       wfIncrStats( 'diff_cache_miss' );
-                       $wgMemc->set( $key, $difftext, 7 * 86400 );
+                       wfIncrStats( 'diff_cache.miss' );
+                       $cache->set( $key, $difftext, 7 * 86400 );
                } else {
-                       wfIncrStats( 'diff_uncacheable' );
+                       wfIncrStats( 'diff_cache.uncacheable' );
                }
                // Replace line numbers with the text in the user's language
                if ( $difftext !== false ) {
@@ -859,12 +873,10 @@ class DifferenceEngine extends ContextSource {
 
                        $tempFile1 = fopen( $tempName1, "w" );
                        if ( !$tempFile1 ) {
-
                                return false;
                        }
                        $tempFile2 = fopen( $tempName2, "w" );
                        if ( !$tempFile2 ) {
-
                                return false;
                        }
                        fwrite( $tempFile1, $otext );
@@ -1040,7 +1052,7 @@ class DifferenceEngine extends ContextSource {
                        $key = $title->quickUserCan( 'edit', $user ) ? 'editold' : 'viewsourceold';
                        $msg = $this->msg( $key )->escaped();
                        $editLink = $this->msg( 'parentheses' )->rawParams(
-                               Linker::linkKnown( $title, $msg, array( ), $editQuery ) )->escaped();
+                               Linker::linkKnown( $title, $msg, array(), $editQuery ) )->escaped();
                        $header .= ' ' . Html::rawElement(
                                'span',
                                array( 'class' => 'mw-diff-edit' ),
@@ -1075,8 +1087,10 @@ class DifferenceEngine extends ContextSource {
        public function addHeader( $diff, $otitle, $ntitle, $multi = '', $notice = '' ) {
                // shared.css sets diff in interface language/dir, but the actual content
                // is often in a different language, mostly the page content language/dir
-               $tableClass = 'diff diff-contentalign-' . htmlspecialchars( $this->getDiffLang()->alignStart() );
-               $header = "<table class='$tableClass'>";
+               $header = Html::openElement( 'table', array(
+                       'class' => array( 'diff', 'diff-contentalign-' . $this->getDiffLang()->alignStart() ),
+                       'data-mw' => 'interface',
+               ) );
                $userLang = htmlspecialchars( $this->getLanguage()->getHtmlCode() );
 
                if ( !$diff && !$otitle ) {