Cenarium has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/251795

Change subject: Allow patrol of uploads
......................................................................

Allow patrol of uploads

This allows to patrol file uploads, both new files and new file
versions, from the description page, provided $wgUseFilePatrol
is set to true. Special:NewFiles can be filtered to hide patrolled
files.

Bug: T11501
Change-Id: If71af58719a4461f12d125455b7bef07164525ca
---
M includes/DefaultSettings.php
M includes/User.php
M includes/changes/ChangesList.php
M includes/changes/RecentChange.php
M includes/filerepo/file/LocalFile.php
M includes/page/Article.php
M includes/specials/SpecialNewimages.php
M languages/i18n/en.json
M languages/i18n/qqq.json
9 files changed, 140 insertions(+), 17 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/95/251795/1

diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index bf6e245..b9d0921 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -6194,7 +6194,8 @@
 $wgRCWatchCategoryMembership = false;
 
 /**
- * Use RC Patrolling to check for vandalism
+ * Use RC Patrolling to check for vandalism (from recent changes and 
watchlists)
+ * New pages and new files are included.
  */
 $wgUseRCPatrol = true;
 
@@ -6204,6 +6205,11 @@
 $wgUseNPPatrol = true;
 
 /**
+ * Use file patrolling to check new files on Special:Newfiles
+ */
+$wgUseFilePatrol = true;
+
+/**
  * Log autopatrol actions to the log table
  */
 $wgLogAutopatrol = true;
diff --git a/includes/User.php b/includes/User.php
index b09e4e4..14de569 100644
--- a/includes/User.php
+++ b/includes/User.php
@@ -3311,6 +3311,18 @@
        }
 
        /**
+        * Check whether to enable new files patrol features for this user
+        * @return bool True or false
+        */
+       public function useFilePatrol() {
+               global $wgUseRCPatrol, $wgUseFilePatrol;
+               return (
+                       ( $wgUseRCPatrol || $wgUseFilePatrol )
+                               && ( $this->isAllowedAny( 'patrol', 
'patrolmarks' ) )
+               );
+       }
+
+       /**
         * Get the WebRequest object to use with this object
         *
         * @return WebRequest
diff --git a/includes/changes/ChangesList.php b/includes/changes/ChangesList.php
index 2494ef1..6081a17 100644
--- a/includes/changes/ChangesList.php
+++ b/includes/changes/ChangesList.php
@@ -638,9 +638,11 @@
                if ( $rc instanceof RecentChange ) {
                        $isPatrolled = $rc->mAttribs['rc_patrolled'];
                        $rcType = $rc->mAttribs['rc_type'];
+                       $rcLogType = $rc->mAttribs['rc_log_type'];
                } else {
                        $isPatrolled = $rc->rc_patrolled;
                        $rcType = $rc->rc_type;
+                       $rcLogType = $rc->rc_log_type;
                }
 
                if ( !$isPatrolled ) {
@@ -650,6 +652,9 @@
                        if ( $user->useNPPatrol() && $rcType == RC_NEW ) {
                                return true;
                        }
+                       if ( $user->useFilePatrol() && $rcLogType == 'upload' ) 
{
+                               return true;
+                       }
                }
 
                return false;
diff --git a/includes/changes/RecentChange.php 
b/includes/changes/RecentChange.php
index b0b88d3..df3b5bc 100644
--- a/includes/changes/RecentChange.php
+++ b/includes/changes/RecentChange.php
@@ -456,11 +456,13 @@
         * @return array Array of permissions errors, see 
Title::getUserPermissionsErrors()
         */
        public function doMarkPatrolled( User $user, $auto = false ) {
-               global $wgUseRCPatrol, $wgUseNPPatrol;
+               global $wgUseRCPatrol, $wgUseNPPatrol, $wgUseFilePatrol;
                $errors = array();
-               // If recentchanges patrol is disabled, only new pages
-               // can be patrolled
-               if ( !$wgUseRCPatrol && ( !$wgUseNPPatrol || 
$this->getAttribute( 'rc_type' ) != RC_NEW ) ) {
+               // If recentchanges patrol is disabled, only new pages or new 
file versions
+               // can be patrolled, provided the appropriate config variable 
is set
+               if ( !$wgUseRCPatrol && ( !$wgUseNPPatrol || 
$this->getAttribute( 'rc_type' ) != RC_NEW ) &&
+                       ( !$wgUseFilePatrol || !( $this->getAttribute( 
'rc_type' ) == RC_LOG &&
+                       $this->getAttribute( 'rc_log_type' ) == 'upload' ) ) ) {
                        $errors[] = array( 'rcpatroldisabled' );
                }
                // Automatic patrol needs "autopatrol", ordinary patrol needs 
"patrol"
diff --git a/includes/filerepo/file/LocalFile.php 
b/includes/filerepo/file/LocalFile.php
index cd64f0d..1f78a48 100644
--- a/includes/filerepo/file/LocalFile.php
+++ b/includes/filerepo/file/LocalFile.php
@@ -1340,6 +1340,7 @@
                }
 
                $descTitle = $this->getTitle();
+               $descId = $descTitle->getArticleID();
                $wikiPage = new WikiFilePage( $descTitle );
                $wikiPage->setFile( $this );
 
@@ -1365,8 +1366,6 @@
                $logId = $logEntry->insert();
 
                if ( $descTitle->exists() ) {
-                       // Page exists, do RC entry now (otherwise we wait for 
later)
-                       $logEntry->publish( $logId );
                        // Use own context to get the action text in content 
language
                        $formatter = LogFormatter::newFromEntry( $logEntry );
                        $formatter->setContext( 
RequestContext::newExtraneousContext( $descTitle ) );
@@ -1374,7 +1373,7 @@
 
                        $nullRevision = Revision::newNullRevision(
                                $dbw,
-                               $descTitle->getArticleID(),
+                               $descId,
                                $editSummary,
                                false,
                                $user
@@ -1386,7 +1385,11 @@
                                        array( $wikiPage, $nullRevision, 
$nullRevision->getParentId(), $user )
                                );
                                $wikiPage->updateRevisionOn( $dbw, 
$nullRevision );
+                               // Associate null revision id
+                               $logEntry->setAssociatedRevId( 
$nullRevision->getId() );
                        }
+                       // Page exists, do RC entry now (otherwise we wait for 
later)
+                       $logEntry->publish( $logId );
 
                        $newPageContent = null;
                } else {
@@ -1403,7 +1406,8 @@
                # b) They won't cause rollback of the log publish/update above
                $that = $this;
                $dbw->onTransactionIdle( function () use (
-                       $that, $reupload, $wikiPage, $newPageContent, $comment, 
$user, $logEntry, $logId
+                       $that, $reupload, $wikiPage, $newPageContent, $comment, 
$user, $logEntry, $logId,
+                       $descId
                ) {
                        # Update memcache after the commit
                        $that->invalidateCache();
@@ -1420,6 +1424,10 @@
                                        $user
                                );
 
+                               if ( isset( $status->value['revision'] ) ) {
+                                       // Associate new page revision id
+                                       $logEntry->setAssociatedRevId( 
$status->value['revision']->getId() );
+                               }
                                // Now that the page exists, make an RC entry.
                                // This relies on the resetArticleID() call in 
WikiPage::insertOn(),
                                // which is triggered on $descTitle by 
doEditContent() above.
@@ -1438,6 +1446,8 @@
                                # Existing file page: invalidate description 
page cache
                                $wikiPage->getTitle()->invalidateCache();
                                $wikiPage->getTitle()->purgeSquid();
+                               # Allow the new file version to be patrolled 
from the page footer
+                               Article::purgePatrolFooterCache( $descId );
                        }
 
                        # Run hook for other updates (typically more cache 
purging)
diff --git a/includes/page/Article.php b/includes/page/Article.php
index 5d6435e..6865543 100644
--- a/includes/page/Article.php
+++ b/includes/page/Article.php
@@ -1071,14 +1071,14 @@
         * @return bool
         */
        public function showPatrolFooter() {
-               global $wgUseNPPatrol, $wgUseRCPatrol, $wgEnableAPI, 
$wgEnableWriteAPI;
+               global $wgUseNPPatrol, $wgUseRCPatrol, $wgUseFilePatrol, 
$wgEnableAPI, $wgEnableWriteAPI;
 
                $outputPage = $this->getContext()->getOutput();
                $user = $this->getContext()->getUser();
                $rc = false;
 
                if ( !$this->getTitle()->quickUserCan( 'patrol', $user )
-                       || !( $wgUseRCPatrol || $wgUseNPPatrol )
+                       || !( $wgUseRCPatrol || $wgUseNPPatrol || 
$wgUseFilePatrol )
                ) {
                        // Patrolling is disabled or the user isn't allowed to
                        return false;
@@ -1127,9 +1127,46 @@
                                __METHOD__
                        );
                } else {
-                       // Cache the information we gathered above in case we 
can't patrol
-                       // Don't cache in case we can patrol as this could 
change
-                       $cache->set( $key, '1' );
+                       if ( $rc ) {
+                               // Use generic patrol message for new pages
+                               $markPatrolledMsg = wfMessage( 
'markaspatrolledtext' );
+                               // Suggest returning to new pages special page
+                               $returnToSpecialPage = 'NewPages';
+                       }
+               }
+
+               // Allow patrolling of latest file upload
+               if ( !$rc && $wgUseFilePatrol && 
$this->getTitle()->getNamespace() === NS_FILE ) {
+                       // Retrieve timestamp of most recent upload
+                       $newestUploadTimestamp = $dbr->selectField(
+                               'image',
+                               'MAX( img_timestamp )',
+                               array( 'img_name' => 
$this->getTitle()->getDBkey() ),
+                               __METHOD__
+                       );
+                       if ( $newestUploadTimestamp
+                               && RecentChange::isInRCLifespan( 
$newestUploadTimestamp, 21600 )
+                       ) {
+                               // 6h tolerance because the RC might not be 
cleaned out regularly
+                               $rc = RecentChange::newFromConds(
+                                       array(
+                                               'rc_type' => RC_LOG,
+                                               'rc_log_type' => 'upload',
+                                               'rc_timestamp' => 
$newestUploadTimestamp,
+                                               'rc_namespace' => NS_FILE,
+                                               'rc_cur_id' => 
$this->getTitle()->getArticleID(),
+                                               'rc_patrolled' => 0
+                                       ),
+                                       __METHOD__,
+                                       array( 'USE INDEX' => 'rc_timestamp' )
+                               );
+                       }
+                       if ( $rc ) {
+                               // Use patrol message specific to files
+                               $markPatrolledMsg = wfMessage( 
'markaspatrolledtext-file' );
+                               // Suggest returning to new files special page
+                               $returnToSpecialPage = 'NewFiles';
+                       }
                }
 
                if ( !$rc ) {
@@ -1166,12 +1203,13 @@
 
                $link = Linker::linkKnown(
                        $this->getTitle(),
-                       wfMessage( 'markaspatrolledtext' )->escaped(),
+                       $markPatrolledMsg->escaped(),
                        array(),
                        array(
                                'action' => 'markpatrolled',
                                'rcid' => $rcid,
                                'token' => $token,
+                               'wpReturnToSpecial' => $returnToSpecialPage
                        )
                );
 
@@ -1185,6 +1223,17 @@
        }
 
        /**
+        * Purge the cache used to check if it is worth showing the patrol 
footer
+        * For example, it is done during re-uploads when file patrol is used.
+        * @param int $articleID ID of the article to purge
+        * @since 1.27
+        */
+       public static function purgePatrolFooterCache( $articleID ) {
+               $cache = ObjectCache::getMainWANInstance();
+               $cache->touchCheckKey( wfMemcKey( 'unpatrollable-page', 
$articleID ) );
+       }
+
+       /**
         * Show the error text for a missing article. For articles in the 
MediaWiki
         * namespace, show the default message text. To be called from 
Article::view().
         */
diff --git a/includes/specials/SpecialNewimages.php 
b/includes/specials/SpecialNewimages.php
index 00c8e05..8aba05b 100644
--- a/includes/specials/SpecialNewimages.php
+++ b/includes/specials/SpecialNewimages.php
@@ -81,9 +81,20 @@
         */
        protected $gallery;
 
+       /**
+        * @var bool
+        */
+       protected $showBots;
+
+       /**
+        * @var bool
+        */
+       protected $hidePatrolled;
+
        function __construct( IContextSource $context, $par = null ) {
                $this->like = $context->getRequest()->getText( 'like' );
-               $this->showbots = $context->getRequest()->getBool( 'showbots', 
0 );
+               $this->showBots = $context->getRequest()->getBool( 'showbots', 
0 );
+               $this->hidePatrolled = $context->getRequest()->getBool( 
'hidepatrolled', 0 );
                if ( is_numeric( $par ) ) {
                        $this->setLimit( $par );
                }
@@ -95,7 +106,7 @@
                $conds = $jconds = array();
                $tables = array( 'image' );
 
-               if ( !$this->showbots ) {
+               if ( !$this->showBots ) {
                        $groupsWithBotPermission = 
User::getGroupsWithPermission( 'bot' );
 
                        if ( count( $groupsWithBotPermission ) ) {
@@ -109,6 +120,21 @@
                                        )
                                );
                        }
+               }
+
+               if ( $this->hidePatrolled ) {
+                       $tables[] = 'recentchanges';
+                       $conds['rc_type'] = RC_LOG;
+                       $conds['rc_log_type'] = 'upload';
+                       $conds['rc_patrolled'] = 0;
+                       $jconds['recentchanges'] = array(
+                               'INNER JOIN',
+                               array(
+                                       'rc_title = img_name',
+                                       'rc_user = img_user',
+                                       'rc_timestamp = img_timestamp'
+                               )
+                       );
                }
 
                if ( !$this->getConfig()->get( 'MiserMode' ) && $this->like !== 
null ) {
@@ -185,6 +211,11 @@
                                'label-message' => 'newimages-showbots',
                                'name' => 'showbots',
                        ),
+                       'hidepatrolled' => array(
+                               'type' => 'check',
+                               'label-message' => 'newimages-hidepatrolled',
+                               'name' => 'hidepatrolled',
+                       ),
                        'limit' => array(
                                'type' => 'hidden',
                                'default' => $this->mLimit,
@@ -201,6 +232,10 @@
                        unset( $fields['like'] );
                }
 
+               if ( !$this->getUser()->useFilePatrol() ) {
+                       unset( $fields['hidepatrolled'] );
+               }
+
                $context = new DerivativeContext( $this->getContext() );
                $context->setTitle( $this->getTitle() ); // Remove subpage
                $form = new HTMLForm( $fields, $context );
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index c4e7d92..74aa889 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -2672,6 +2672,7 @@
        "markaspatrolleddiff": "Mark as patrolled",
        "markaspatrolledlink": "[$1]",
        "markaspatrolledtext": "Mark this page as patrolled",
+       "markaspatrolledtext-file": "Mark this file version as patrolled",
        "markedaspatrolled": "Marked as patrolled",
        "markedaspatrolledtext": "The selected revision of [[:$1]] has been 
marked as patrolled.",
        "rcpatroldisabled": "Recent changes patrol disabled",
@@ -2725,6 +2726,7 @@
        "newimages-legend": "Filter",
        "newimages-label": "Filename (or a part of it):",
        "newimages-showbots": "Show uploads by bots",
+       "newimages-hidepatrolled": "Hide patrolled uploads",
        "noimages": "Nothing to see.",
        "ilsubmit": "Search",
        "bydate": "by date",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index 34240d4..aac4582 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -2845,6 +2845,7 @@
        "markaspatrolleddiff": "{{doc-actionlink}}\nSee also:\n* 
{{msg-mw|Markaspatrolledtext}}\n{{Identical|Mark as patrolled}}",
        "markaspatrolledlink": "{{notranslate}}\nParameters:\n* $1 - link which 
has text {{msg-mw|Markaspatrolledtext}}",
        "markaspatrolledtext": "{{doc-actionlink}}\nSee also:\n* 
{{msg-mw|Markaspatrolleddiff}}",
+       "markaspatrolledtext-file": "Same as markaspatrolledtext, but for files 
(new versions included) instead of pages.",
        "markedaspatrolled": "Used as title of the message 
{{msg-mw|Markedaspatrolledtext}}, when marking a change as 
patrolled.\n{{Related|Markedaspatrolled}}",
        "markedaspatrolledtext": "Used when marking a change as 
patrolled.\n\nThe title for this message is 
{{msg-mw|Markedaspatrolled}}.\n\nParameters:\n* $1 - page 
title\n{{Related|Markedaspatrolled}}",
        "rcpatroldisabled": "Used as title of the error message 
{{msg-mw|Rcpatroldisabledtext}}, when marking a change as 
patrolled.\n{{Related|Markedaspatrolled}}",
@@ -2898,6 +2899,7 @@
        "newimages-legend": "Caption of the fieldset for the filter on 
[[Special:NewImages]]\n\n{{Identical|Filter}}",
        "newimages-label": "Caption of the filter editbox on 
[[Special:NewImages]]",
        "newimages-showbots": "Used as label for a checkbox. When checked, 
[[Special:NewImages]] will also display uploads by users in the bots group.",
+       "newimages-hidepatrolled": "Used as label for a checkbox. When checked, 
[[Special:NewImages]] will not display patrolled uploads.",
        "noimages": "This is shown on the special page [[Special:NewImages]], 
when there aren't any recently uploaded files.",
        "ilsubmit": "Used as label for input box in the MIMESearch form on 
[[Special:MIMESearch]].\n\nSee also:\n* {{msg-mw|Mimesearch|page title}}\n* 
{{msg-mw|Mimetype|label for input box}}\n{{Identical|Search}}",
        "bydate": "{{Identical|Date}}",

-- 
To view, visit https://gerrit.wikimedia.org/r/251795
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: If71af58719a4461f12d125455b7bef07164525ca
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Cenarium <cenarium.sy...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to