Add a maintenance script to delete a change tag
Based on Ib8b96b8460db3832e9297a07922ee1d9d1af5ccb by Legoktm. Bug: T75181 Change-Id: I0e61dfbc72fe27efa9c1deabc928e7c9af66e1bc
This commit is contained in:
parent
5a811a1ea2
commit
38a9f0a42a
3 changed files with 86 additions and 2 deletions
|
|
@ -388,6 +388,7 @@ $wgAutoloadLocalClasses = [
|
|||
'DeleteOrphanedRevisions' => __DIR__ . '/maintenance/deleteOrphanedRevisions.php',
|
||||
'DeletePageJob' => __DIR__ . '/includes/jobqueue/jobs/DeletePageJob.php',
|
||||
'DeleteSelfExternals' => __DIR__ . '/maintenance/deleteSelfExternals.php',
|
||||
'DeleteTag' => __DIR__ . '/maintenance/deleteTag.php',
|
||||
'DeletedContribsPager' => __DIR__ . '/includes/specials/pagers/DeletedContribsPager.php',
|
||||
'DependencyWrapper' => __DIR__ . '/includes/cache/dependency/DependencyWrapper.php',
|
||||
'DeprecatedGlobal' => __DIR__ . '/includes/DeprecatedGlobal.php',
|
||||
|
|
|
|||
|
|
@ -1301,10 +1301,11 @@ class ChangeTags {
|
|||
* @param string $tag Tag that you are interested in deleting
|
||||
* @param User|null $user User whose permission you wish to check, or null if
|
||||
* you don't care (e.g. maintenance scripts)
|
||||
* @param bool $ignoreCounts If true, no check for tag usage will be preformed
|
||||
* @return Status
|
||||
* @since 1.25
|
||||
*/
|
||||
public static function canDeleteTag( $tag, User $user = null ) {
|
||||
public static function canDeleteTag( $tag, User $user = null, bool $ignoreCounts = false ) {
|
||||
$tagUsage = self::tagUsageStatistics();
|
||||
|
||||
if ( !is_null( $user ) ) {
|
||||
|
|
@ -1321,7 +1322,7 @@ class ChangeTags {
|
|||
return Status::newFatal( 'tags-delete-not-found', $tag );
|
||||
}
|
||||
|
||||
if ( isset( $tagUsage[$tag] ) && $tagUsage[$tag] > self::MAX_DELETE_USES ) {
|
||||
if ( !$ignoreCounts && isset( $tagUsage[$tag] ) && $tagUsage[$tag] > self::MAX_DELETE_USES ) {
|
||||
return Status::newFatal( 'tags-delete-too-many-uses', $tag, self::MAX_DELETE_USES );
|
||||
}
|
||||
|
||||
|
|
|
|||
82
maintenance/deleteTag.php
Normal file
82
maintenance/deleteTag.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Remove a revision tag from edits and log entries it was applied to.
|
||||
* @see bug T75181
|
||||
*/
|
||||
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Storage\NameTableAccessException;
|
||||
|
||||
require_once __DIR__ . '/Maintenance.php';
|
||||
|
||||
class DeleteTag extends Maintenance {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->addDescription( 'Deletes a change tag' );
|
||||
$this->addArg( 'tag name', 'Name of the tag to delete' );
|
||||
$this->setBatchSize( 500 );
|
||||
}
|
||||
|
||||
public function execute() {
|
||||
$dbw = $this->getDB( DB_MASTER );
|
||||
$services = MediaWikiServices::getInstance();
|
||||
$defStore = $services->getChangeTagDefStore();
|
||||
$lbFactory = $services->getDBLoadBalancerFactory();
|
||||
$options = [ 'domain' => $lbFactory->getLocalDomainID() ];
|
||||
|
||||
$tag = $this->getArg( 0 );
|
||||
try {
|
||||
$tagId = $defStore->getId( $tag );
|
||||
} catch ( NameTableAccessException $ex ) {
|
||||
$this->fatalError( "Tag '$tag' not found" );
|
||||
// To make analyzers happy
|
||||
return;
|
||||
}
|
||||
|
||||
$status = ChangeTags::canDeleteTag( $tag, null, true );
|
||||
if ( !$status->isOK() ) {
|
||||
$message = $status->getHTML( false, false, 'en' );
|
||||
$this->fatalError( Sanitizer::stripAllTags( $message ) );
|
||||
}
|
||||
|
||||
$this->output( "Deleting tag '$tag'...\n" );
|
||||
|
||||
// Make the tag imposssible to add by users while we're deleting it and drop the
|
||||
// usage counter to zero
|
||||
$dbw->update(
|
||||
'change_tag_def',
|
||||
[
|
||||
'ctd_user_defined' => 0,
|
||||
'ctd_count' => 0,
|
||||
],
|
||||
[ 'ctd_id' => $tagId ],
|
||||
__METHOD__
|
||||
);
|
||||
ChangeTags::purgeTagCacheAll();
|
||||
|
||||
// Iterate over change_tag, deleting rows in batches
|
||||
$count = 0;
|
||||
do {
|
||||
$ids = $dbw->selectFieldValues(
|
||||
'change_tag',
|
||||
'ct_id',
|
||||
[ 'ct_tag_id' => $tagId ],
|
||||
__METHOD__,
|
||||
[ 'LIMIT' => $this->getBatchSize() ]
|
||||
);
|
||||
|
||||
$dbw->delete( 'change_tag', [ 'ct_id' => $ids ], __METHOD__ );
|
||||
$count += $dbw->affectedRows();
|
||||
$this->output( "$count\n" );
|
||||
$lbFactory->waitForReplication( $options );
|
||||
} while ( $dbw->affectedRows() === $this->getBatchSize() );
|
||||
$this->output( "The tag has been removed from $count revisions, deleting the tag itself...\n" );
|
||||
|
||||
ChangeTags::deleteTagEverywhere( $tag );
|
||||
$this->output( "Done.\n" );
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = DeleteTag::class;
|
||||
require_once RUN_MAINTENANCE_IF_MAIN;
|
||||
Loading…
Reference in a new issue