Add rc.unpatrolled to the recentchanges API
authorTimo Tijhof <krinklemail@gmail.com>
Fri, 25 Oct 2013 08:25:48 +0000 (10:25 +0200)
committerTimo Tijhof <krinklemail@gmail.com>
Fri, 25 Oct 2013 15:26:43 +0000 (17:26 +0200)
On SpecialRecentChanges, the unpatrolled "bang" icon is only
rendered when:
- the user has the patrol right.
- the rc type is EDIT and rcpatrol is permitted, or
  the tc type is NEW and nppatrol is permitted.
- the rc event is in fact still unpatrolled.

In other words, when an edit is patrollable and unpatrolled.

However, consumers of the API are unable to render this because
the API only has a boolean "patrolled" attribute. Apps using
the absence of "patrolled" and presence of "patrol" right as
meaning "unpatrolled" get into trouble on wikis with RCpatrol
disabled and NPpatrol enabled. In those cases the app would
render a change as unpatrolled, but when the user clicks it
find out it can't be patrolled.

This adds an "unpatrolled" flag that does just that.

Change-Id: Ic947c6c75eb7936fcebdccbcd27ff62e07f1feda

includes/api/ApiQueryRecentChanges.php
includes/changes/ChangesList.php

index 6b10bdc..8d969fc 100644 (file)
@@ -456,6 +456,10 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $vals['patrolled'] = '';
                }
 
+               if ( $this->fld_patrolled && ChangesList::isUnpatrolled( $row, $this->getUser() ) ) {
+                       $vals['unpatrolled'] = '';
+               }
+
                if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
                        $vals['logid'] = intval( $row->rc_logid );
                        $vals['logtype'] = $row->rc_log_type;
@@ -655,7 +659,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                ' ids            - Adds the page ID, recent changes ID and the new and old revision ID',
                                ' sizes          - Adds the new and old page length in bytes',
                                ' redirect       - Tags edit if page is a redirect',
-                               ' patrolled      - Tags edits that have been patrolled',
+                               ' patrolled      - Tags patrollable edits as being patrolled or unpatrolled',
                                ' loginfo        - Adds log information (logid, logtype, etc) to log entries',
                                ' tags           - Lists tags for the entry',
                                ' sha1           - Adds the content checksum for entries associated with a revision',
@@ -741,7 +745,8 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                                'redirect' => 'boolean'
                        ),
                        'patrolled' => array(
-                               'patrolled' => 'boolean'
+                               'patrolled' => 'boolean',
+                               'unpatrolled' => 'boolean'
                        ),
                        'loginfo' => array(
                                'logid' => array(
index bf800c4..1b14b97 100644 (file)
@@ -539,14 +539,32 @@ class ChangesList extends ContextSource {
        }
 
        protected function showAsUnpatrolled( RecentChange $rc ) {
-               $unpatrolled = false;
-               if ( !$rc->mAttribs['rc_patrolled'] ) {
-                       if ( $this->getUser()->useRCPatrol() ) {
-                               $unpatrolled = true;
-                       } elseif ( $this->getUser()->useNPPatrol() && $rc->mAttribs['rc_type'] == RC_NEW ) {
-                               $unpatrolled = true;
+               return self::isUnpatrolled( $rc, $this->getUser() );
+       }
+
+       /**
+        * @param object|RecentChange $rc Database row from recentchanges or a RecentChange object
+        * @param User $user
+        * @return bool
+        */
+       public static function isUnpatrolled( $rc, User $user ) {
+               if ( $rc instanceof RecentChange ) {
+                       $isPatrolled = $rc->mAttribs['rc_patrolled'];
+                       $rcType = $rc->mAttribs['rc_type'];
+               } else {
+                       $isPatrolled = $rc->rc_patrolled;
+                       $rcType = $rc->rc_type;
+               }
+
+               if ( !$isPatrolled ) {
+                       if ( $user->useRCPatrol() ) {
+                               return true;
+                       }
+                       if ( $user->useNPPatrol() && $rcType == RC_NEW ) {
+                               return true;
                        }
                }
-               return $unpatrolled;
+
+               return false;
        }
 }