Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
DeleteEqualTranslationsMaintenanceScript.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Diagnostics;
5
11use MediaWiki\MediaWikiServices;
12use MediaWiki\Title\Title;
13use SplObjectStorage;
14use TitleValue;
15use const SORT_NUMERIC;
16
23 public function __construct() {
24 parent::__construct();
25 $this->addDescription( 'Delete translations that are equal to the definition' );
26
27 $this->addOption(
28 'group',
29 'Which group to scan',
30 self::REQUIRED,
31 self::HAS_ARG
32 );
33 $this->addOption(
34 'language',
35 'Which language to scan',
36 self::REQUIRED,
37 self::HAS_ARG
38 );
39 $this->addOption(
40 'really',
41 'Delete the listed pages instead of just listing them'
42 );
43 $this->addOption(
44 'comment',
45 'Comment for the deletions'
46 );
47
48 $this->requireExtension( 'Translate' );
49 }
50
52 public function execute() {
53 $groupId = $this->getOption( 'group' );
54 $language = $this->getOption( 'language' );
55 $group = MessageGroups::getGroup( $groupId );
56 if ( !$group ) {
57 $this->fatalError( "Message group '$groupId' does not exist" );
58 }
59
60 $collection = $group->initCollection( $language );
61 $equalMessages = $this->getEqualMessages( $collection );
62 $equalMessageCount = count( $equalMessages );
63 if ( $equalMessageCount === 0 ) {
64 $this->output( "No translations equal to definition found\n" );
65 return;
66 }
67
68 $stats = $this->getUserStats( $equalMessages );
69 $this->printUserStats( $stats, $equalMessageCount );
70 $this->output( "\n" );
71 $this->printMessages( $equalMessages );
72
73 if ( $this->hasOption( 'really' ) ) {
74 $comment = $this->getOption( 'comment' ) ?? '';
75 $this->deleteMessages( $equalMessages, $comment );
76 } else {
77 $this->output( "This is a dry-run. Run again with --really to delete these messages\n" );
78 }
79 }
80
81 private function getEqualMessages( MessageCollection $collection ): SplObjectStorage {
82 $collection->filter( 'translated', false );
83 $collection->loadTranslations();
84
85 $messages = new SplObjectStorage();
86 foreach ( $collection->keys() as $key => $titleValue ) {
88 $message = $collection[$key];
89
90 if ( $message->definition() === $message->translation() ) {
91 $messages->attach( $titleValue, $message );
92 }
93 }
94
95 return $messages;
96 }
97
98 private function getUserStats( SplObjectStorage $messages ): array {
99 $stats = [];
100 foreach ( $messages as $key ) {
102 $message = $messages[$key];
103 $index = $message->getProperty( 'last-translator-text' );
104 $stats[$index] = ( $stats[$index] ?? 0 ) + 1;
105 }
106
107 return $stats;
108 }
109
110 private function printUserStats( array $stats, int $equalMessageCount ): void {
111 $this->output( "Found $equalMessageCount message(s) created by these user(s):\n" );
112 arsort( $stats, SORT_NUMERIC );
113 foreach ( $stats as $userName => $count ) {
114 $this->output( sprintf( "%6d | %s\n", $count, $userName ) );
115 }
116 }
117
118 private function printMessages( SplObjectStorage $messages ): void {
120 foreach ( $messages as $key ) {
122 $message = $messages[$key];
123 $title = Title::newFromLinkTarget( $key );
124 $this->output(
125 sprintf( "== %s ==\n%s\n\n", $title->getPrefixedText(), $message->translation() )
126 );
127 }
128 }
129
130 private function deleteMessages( SplObjectStorage $messages, string $reason ): void {
131 $services = MediaWikiServices::getInstance();
132 $wikiPageFactory = $services->getWikiPageFactory();
133 $deletePageFactory = $services->getDeletePageFactory();
134
135 $user = FuzzyBot::getUser();
136
138 foreach ( $messages as $key ) {
139 $title = Title::newFromLinkTarget( $key );
140 $page = $wikiPageFactory->newFromTitle( $title );
141 $status = $deletePageFactory->newDeletePage( $page, $user )
142 ->deleteUnsafe( $reason );
143
144 if ( $status->isOK() ) {
145 $this->output( '.', 'deletions' );
146 } else {
147 $pageName = $title->getPrefixedText();
148 $this->output( "FAILED to delete page $pageName\n" );
149 }
150 }
151 }
152}
Factory class for accessing message groups individually by id or all of them as a list.
This file contains the class for core message collections implementation.
Interface for message objects used by MessageCollection.
Definition Message.php:13
FuzzyBot - the misunderstood workhorse.
Definition FuzzyBot.php:15
Base maintenance script containing constants and methods used in multiple scripts Hopefully the const...