23 public function __construct() {
24 parent::__construct();
25 $this->addDescription(
'Delete translations that are equal to the definition' );
29 'Which group to scan',
35 'Which language to scan',
41 'Delete the listed pages instead of just listing them'
45 'Comment for the deletions'
48 $this->requireExtension(
'Translate' );
53 $groupId = $this->getOption(
'group' );
54 $language = $this->getOption(
'language' );
55 $group = MessageGroups::getGroup( $groupId );
57 $this->fatalError(
"Message group '$groupId' does not exist" );
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" );
68 $stats = $this->getUserStats( $equalMessages );
69 $this->printUserStats( $stats, $equalMessageCount );
70 $this->output(
"\n" );
71 $this->printMessages( $equalMessages );
73 if ( $this->hasOption(
'really' ) ) {
74 $comment = $this->getOption(
'comment' ) ??
'';
75 $this->deleteMessages( $equalMessages, $comment );
77 $this->output(
"This is a dry-run. Run again with --really to delete these messages\n" );
81 private function getEqualMessages(
MessageCollection $collection ): SplObjectStorage {
82 $collection->filter(
'translated', false );
85 $messages =
new SplObjectStorage();
86 foreach ( $collection->
keys() as $key => $titleValue ) {
88 $message = $collection[$key];
90 if ( $message->definition() === $message->translation() ) {
91 $messages->attach( $titleValue, $message );
98 private function getUserStats( SplObjectStorage $messages ): array {
100 foreach ( $messages as $key ) {
102 $message = $messages[$key];
103 $index = $message->getProperty(
'last-translator-text' );
104 $stats[$index] = ( $stats[$index] ?? 0 ) + 1;
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 ) );
118 private function printMessages( SplObjectStorage $messages ): void {
120 foreach ( $messages as $key ) {
122 $message = $messages[$key];
123 $title = Title::newFromLinkTarget( $key );
125 sprintf(
"== %s ==\n%s\n\n", $title->getPrefixedText(), $message->translation() )
130 private function deleteMessages( SplObjectStorage $messages,
string $reason ): void {
131 $user = FuzzyBot::getUser();
132 $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
135 foreach ( $messages as $key ) {
136 $title = Title::newFromLinkTarget( $key );
137 $page = $wikiPageFactory->newFromTitle( $title );
138 $status = $page->doDeleteArticleReal(
142 if ( $status->isOK() ) {
143 $this->output(
".",
'deletions' );
145 $pageName = $title->getPrefixedText();
146 $this->output(
"FAILED to delete page $pageName\n" );