Merge "Patrol overhaul phase 1: Remove rcid parameters"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Sat, 25 May 2013 10:08:50 +0000 (10:08 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Sat, 25 May 2013 10:08:50 +0000 (10:08 +0000)
1  2 
includes/Article.php

diff --combined includes/Article.php
@@@ -855,11 -855,11 +855,11 @@@ class Article implements Page 
        /**
         * Get the robot policy to be used for the current view
         * @param string $action the action= GET parameter
 -       * @param $pOutput ParserOutput
 +       * @param $pOutput ParserOutput|null
         * @return Array the policy that should be set
         * TODO: actions other than 'view'
         */
 -      public function getRobotPolicy( $action, $pOutput ) {
 +      public function getRobotPolicy( $action, $pOutput = null ) {
                global $wgArticleRobotPolicies, $wgNamespaceRobotPolicies, $wgDefaultRobotPolicy;
  
                $ns = $this->getTitle()->getNamespace();
                        $this->getContext()->getOutput()->addWikiMsg( 'anontalkpagetext' );
                }
  
-               # If we have been passed an &rcid= parameter, we want to give the user a
-               # chance to mark this new article as patrolled.
+               // Show a footer allowing the user to patrol the shown revision or page if possible
                $this->showPatrolFooter();
  
                wfRunHooks( 'ArticleViewFooter', array( $this ) );
         * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
         */
        public function showPatrolFooter() {
+               global $wgUseRCPatrol, $wgUseNPPatrol, $wgRCMaxAge;
                $request = $this->getContext()->getRequest();
                $outputPage = $this->getContext()->getOutput();
                $user = $this->getContext()->getUser();
-               $rcid = $request->getVal( 'rcid' );
+               $cache = wfGetMainCache();
+               // Conditions to potentially patrol the current revision
+               // patrolPage is set in case we want to patrol the first
+               // revision and not the current one (set in Special:NewPages)
+               $useRCPatrol = $wgUseRCPatrol && !$request->getBool( 'patrolpage' );
+               if ( !$this->getTitle()->quickUserCan( 'patrol', $user ) || ( !$wgUseNPPatrol && !$wgUseRCPatrol ) ) {
+                       // Patrolling is fully disabled or the user isn't allowed to
+                       return;
+               }
+               wfProfileIn( __METHOD__ );
+               if ( $useRCPatrol ) {
+                       // Check for cached results
+                       if ( $cache->get( wfMemcKey( 'NotPatrollableRevId', $this->getRevIdFetched() ) ) ) {
+                               wfProfileOut( __METHOD__ );
+                               return;
+                       }
+                       // We make use of a little index trick over here:
+                       // First we get the timestamp of the last revision and then
+                       // we look up the RC row by that as the timestamp is indexed
+                       // and usually very few rows exist for one timestamp
+                       // (While several thousand can exists for a single page)
+                       if ( !$this->mRevision ) {
+                               $this->mRevision = Revision::newFromId( $this->getRevIdFetched() );
+                       }
+                       if ( !$this->mRevision || !RecentChange::isInRCLifespan( $this->mRevision->getTimestamp(), 21600 )  ) {
+                               // The revision is more than 6 hours older than the Max RC age
+                               // no need to torture the DB any further (6h because the RC might not be cleaned out regularly)
+                               wfProfileOut( __METHOD__ );
+                               return;
+                       }
+                       $rc = RecentChange::newFromConds(
+                               array(
+                                       'rc_this_oldid' => $this->getRevIdFetched(),
+                                       'rc_timestamp' => $this->mRevision->getTimestamp(),
+                                       'rc_cur_id' => $this->getTitle()->getArticleID(),
+                                       'rc_patrolled' => 0
+                               ),
+                               __METHOD__,
+                               array( 'USE INDEX' => 'rc_timestamp' )
+                       );
+               } else {
+                       // RC patrol is disabled so we have to patrol the first
+                       // revision (new page patrol) in case it's in the RC table.
+                       // To achieve this we get the timestamp of the oldest revison
+                       // the revision table holds for the given page. Then we look
+                       // whether it's within the RC lifespan and if it is, we try
+                       // to get the recentchanges row belonging to that entry
+                       // (with rc_new = 1).
+                       // Check for cached results
+                       if ( $cache->get( wfMemcKey( 'NotPatrollablePage', $this->getTitle()->getArticleID() ) ) ) {
+                               wfProfileOut( __METHOD__ );
+                               return;
+                       }
+                       $dbr = wfGetDB( DB_SLAVE );
+                       $oldestRevisionTimestamp = $dbr->selectField(
+                               'revision',
+                               'MIN( rev_timestamp )',
+                               array( 'rev_page' => $this->getTitle()->getArticleID() ),
+                               __METHOD__
+                       );
+                       if ( !$oldestRevisionTimestamp || !RecentChange::isInRCLifespan( $oldestRevisionTimestamp, 21600 ) ) {
+                               // We either didn't find the oldest revision for the given page
+                               // or it's to old for the RC table (with 6h tolerance)
+                               wfProfileOut( __METHOD__ );
+                               return;
+                       }
+                       $rc = RecentChange::newFromConds(
+                               array(
+                                       'rc_new' => 1,
+                                       'rc_timestamp' => $oldestRevisionTimestamp,
+                                       'rc_namespace' => $this->getTitle()->getNamespace(),
+                                       'rc_cur_id' => $this->getTitle()->getArticleID(),
+                                       'rc_patrolled' => 0
+                               ),
+                               __METHOD__,
+                               array( 'USE INDEX' => 'new_name_timestamp' )
+                       );
+               }
+               wfProfileOut( __METHOD__ );
+               if ( !$rc ) {
+                       // No RC entry around
+                       // Cache the information we gathered above in case we can't patrol
+                       // Don't cache in case we can patrol as this could change
+                       if( $useRCPatrol ) {
+                               $cache->set( wfMemcKey( 'NotPatrollableRevId', $this->getRevIdFetched() ), '1', $wgRCMaxAge );
+                       } else {
+                               $cache->set( wfMemcKey( 'NotPatrollablePage', $this->getTitle()->getArticleID() ), '1', $wgRCMaxAge );
+                       }
  
-               if ( !$rcid || !$this->getTitle()->quickUserCan( 'patrol', $user ) ) {
                        return;
                }
  
+               $rcid = $rc->getAttribute( 'rc_id' );
                $token = $user->getEditToken( $rcid );
  
                $outputPage->preventClickjacking();
                        $this->getContext()->getRequest()->response()->header( "HTTP/1.1 404 Not Found" );
                }
  
 +              if ( $validUserPage ) {
 +                      // Also apply the robot policy for nonexisting user pages (as those aren't served as 404)
 +                      $policy = $this->getRobotPolicy( 'view' );
 +                      $outputPage->setIndexPolicy( $policy['index'] );
 +                      $outputPage->setFollowPolicy( $policy['follow'] );
 +              }
 +
                $hookResult = wfRunHooks( 'BeforeDisplayNoArticleText', array( $this ) );
  
                if ( ! $hookResult ) {