jenkins-bot has submitted this change and it was merged.
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/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 includes/user/User.php
M languages/i18n/en.json
M languages/i18n/qqq.json
9 files changed, 145 insertions(+), 12 deletions(-)
Approvals:
Legoktm: Looks good to me, approved
Bartosz Dziewoński: Looks good to me, but someone else must approve
jenkins-bot: Verified
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 54216fd..7415528 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -6164,7 +6164,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;
@@ -6174,6 +6175,13 @@
$wgUseNPPatrol = true;
/**
+ * Use file patrolling to check new files on Special:Newfiles
+ *
+ * @since 1.27
+ */
+$wgUseFilePatrol = true;
+
+/**
* Log autopatrol actions to the log table
*/
$wgLogAutopatrol = true;
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 0da1ae8..5a6a8b2 100644
--- a/includes/filerepo/file/LocalFile.php
+++ b/includes/filerepo/file/LocalFile.php
@@ -1330,6 +1330,7 @@
}
$descTitle = $this->getTitle();
+ $descId = $descTitle->getArticleID();
$wikiPage = new WikiFilePage( $descTitle );
$wikiPage->setFile( $this );
@@ -1362,7 +1363,7 @@
$nullRevision = Revision::newNullRevision(
$dbw,
- $descTitle->getArticleID(),
+ $descId,
$editSummary,
false,
$user
@@ -1374,6 +1375,8 @@
array( $wikiPage, $nullRevision,
$nullRevision->getParentId(), $user )
);
$wikiPage->updateRevisionOn( $dbw,
$nullRevision );
+ // Associate null revision id
+ $logEntry->setAssociatedRevId(
$nullRevision->getId() );
}
$newPageContent = null;
@@ -1391,7 +1394,7 @@
# 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();
@@ -1408,6 +1411,10 @@
$user
);
+ if ( isset( $status->value['revision'] ) ) {
+ // Associate new page revision id
+ $logEntry->setAssociatedRevId(
$status->value['revision']->getId() );
+ }
// This relies on the resetArticleID() call in
WikiPage::insertOn(),
// which is triggered on $descTitle by
doEditContent() above.
if ( isset( $status->value['revision'] ) ) {
@@ -1424,6 +1431,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 );
}
# Now that the page exists, make an RC entry.
diff --git a/includes/page/Article.php b/includes/page/Article.php
index af1f00b..22e24ae 100644
--- a/includes/page/Article.php
+++ b/includes/page/Article.php
@@ -1061,14 +1061,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;
@@ -1103,6 +1103,9 @@
__METHOD__
);
+ $cantPatrolNewPage = false;
+ $cantPatrolFile = false;
+
if ( $oldestRevisionTimestamp
&& RecentChange::isInRCLifespan(
$oldestRevisionTimestamp, 21600 )
) {
@@ -1116,7 +1119,51 @@
),
__METHOD__
);
+ if ( $rc ) {
+ // Use generic patrol message for new pages
+ $markPatrolledMsg = wfMessage(
'markaspatrolledtext' );
+ }
} else {
+ $cantPatrolNewPage = true;
+ }
+
+ // 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' );
+ }
+ } else {
+ $cantPatrolFile = true;
+ }
+ } else {
+ $cantPatrolFile = true;
+ }
+
+ if ( $cantPatrolFile && $cantPatrolNewPage ) {
// 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' );
@@ -1156,7 +1203,7 @@
$link = Linker::linkKnown(
$this->getTitle(),
- wfMessage( 'markaspatrolledtext' )->escaped(),
+ $markPatrolledMsg->escaped(),
array(),
array(
'action' => 'markpatrolled',
@@ -1175,6 +1222,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 6b7c038..53fb45e 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/includes/user/User.php b/includes/user/User.php
index fed9664..10365b0 100644
--- a/includes/user/User.php
+++ b/includes/user/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/languages/i18n/en.json b/languages/i18n/en.json
index 000b4ae..ce3eb6c 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -2711,6 +2711,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",
@@ -2764,6 +2765,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 d21718e..0ef31e3 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -2886,6 +2886,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}}",
@@ -2939,6 +2940,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: merged
Gerrit-Change-Id: If71af58719a4461f12d125455b7bef07164525ca
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Cenarium <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Bartosz Dziewoński <[email protected]>
Gerrit-Reviewer: Florianschmidtwelzow <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits