X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/maintenance/deleteEqualMessages.php diff --git a/maintenance/deleteEqualMessages.php b/maintenance/deleteEqualMessages.php new file mode 100644 index 00000000..5fc7d184 --- /dev/null +++ b/maintenance/deleteEqualMessages.php @@ -0,0 +1,206 @@ +addDescription( 'Deletes all pages in the MediaWiki namespace that are equal to ' + . 'the default message' ); + $this->addOption( 'delete', 'Actually delete the pages (default: dry run)' ); + $this->addOption( 'delete-talk', 'Don\'t leave orphaned talk pages behind during deletion' ); + $this->addOption( 'lang-code', 'Check for subpages of this language code (default: root ' + . 'page against content language). Use value "*" to run for all mwfile language code ' + . 'subpages (including the base pages that override content language).', false, true ); + } + + /** + * @param string|bool $langCode See --lang-code option. + * @param array &$messageInfo + */ + protected function fetchMessageInfo( $langCode, array &$messageInfo ) { + global $wgContLang; + + if ( $langCode ) { + $this->output( "\n... fetching message info for language: $langCode" ); + $nonContLang = true; + } else { + $this->output( "\n... fetching message info for content language" ); + $langCode = $wgContLang->getCode(); + $nonContLang = false; + } + + /* Based on SpecialAllmessages::reallyDoQuery #filter=modified */ + + $l10nCache = Language::getLocalisationCache(); + $messageNames = $l10nCache->getSubitemList( 'en', 'messages' ); + // Normalise message names for NS_MEDIAWIKI page_title + $messageNames = array_map( [ $wgContLang, 'ucfirst' ], $messageNames ); + + $statuses = AllMessagesTablePager::getCustomisedStatuses( + $messageNames, $langCode, $nonContLang ); + // getCustomisedStatuses is stripping the sub page from the page titles, add it back + $titleSuffix = $nonContLang ? "/$langCode" : ''; + + foreach ( $messageNames as $key ) { + $customised = isset( $statuses['pages'][$key] ); + if ( $customised ) { + $actual = wfMessage( $key )->inLanguage( $langCode )->plain(); + $default = wfMessage( $key )->inLanguage( $langCode )->useDatabase( false )->plain(); + + $messageInfo['relevantPages']++; + + if ( + // Exclude messages that are empty by default, such as sitenotice, specialpage + // summaries and accesskeys. + $default !== '' && $default !== '-' && + $actual === $default + ) { + $hasTalk = isset( $statuses['talks'][$key] ); + $messageInfo['results'][] = [ + 'title' => $key . $titleSuffix, + 'hasTalk' => $hasTalk, + ]; + $messageInfo['equalPages']++; + if ( $hasTalk ) { + $messageInfo['equalPagesTalks']++; + } + } + } + } + } + + public function execute() { + $doDelete = $this->hasOption( 'delete' ); + $doDeleteTalk = $this->hasOption( 'delete-talk' ); + $langCode = $this->getOption( 'lang-code' ); + + $messageInfo = [ + 'relevantPages' => 0, + 'equalPages' => 0, + 'equalPagesTalks' => 0, + 'results' => [], + ]; + + $this->output( 'Checking for pages with default message...' ); + + // Load message information + if ( $langCode ) { + $langCodes = Language::fetchLanguageNames( null, 'mwfile' ); + if ( $langCode === '*' ) { + // All valid lang-code subpages in NS_MEDIAWIKI that + // override the messsages in that language + foreach ( $langCodes as $key => $value ) { + $this->fetchMessageInfo( $key, $messageInfo ); + } + // Lastly, the base pages in NS_MEDIAWIKI that override + // messages in content language + $this->fetchMessageInfo( false, $messageInfo ); + } else { + if ( !isset( $langCodes[$langCode] ) ) { + $this->error( 'Invalid language code: ' . $langCode, 1 ); + } + $this->fetchMessageInfo( $langCode, $messageInfo ); + } + } else { + $this->fetchMessageInfo( false, $messageInfo ); + } + + if ( $messageInfo['equalPages'] === 0 ) { + // No more equal messages left + $this->output( "\ndone.\n" ); + + return; + } + + $this->output( "\n{$messageInfo['relevantPages']} pages in the MediaWiki namespace " + . "override messages." ); + $this->output( "\n{$messageInfo['equalPages']} pages are equal to the default message " + . "(+ {$messageInfo['equalPagesTalks']} talk pages).\n" ); + + if ( !$doDelete ) { + $list = ''; + foreach ( $messageInfo['results'] as $result ) { + $title = Title::makeTitle( NS_MEDIAWIKI, $result['title'] ); + $list .= "* [[$title]]\n"; + if ( $result['hasTalk'] ) { + $title = Title::makeTitle( NS_MEDIAWIKI_TALK, $result['title'] ); + $list .= "* [[$title]]\n"; + } + } + $this->output( "\nList:\n$list\nRun the script again with --delete to delete these pages" ); + if ( $messageInfo['equalPagesTalks'] !== 0 ) { + $this->output( " (include --delete-talk to also delete the talk pages)" ); + } + $this->output( "\n" ); + + return; + } + + $user = User::newSystemUser( 'MediaWiki default', [ 'steal' => true ] ); + if ( !$user ) { + $this->error( "Invalid username", true ); + } + global $wgUser; + $wgUser = $user; + + // Hide deletions from RecentChanges + $user->addGroup( 'bot' ); + + // Handle deletion + $this->output( "\n...deleting equal messages (this may take a long time!)..." ); + $dbw = $this->getDB( DB_MASTER ); + foreach ( $messageInfo['results'] as $result ) { + wfWaitForSlaves(); + $dbw->ping(); + $title = Title::makeTitle( NS_MEDIAWIKI, $result['title'] ); + $this->output( "\n* [[$title]]" ); + $page = WikiPage::factory( $title ); + $error = ''; // Passed by ref + $success = $page->doDeleteArticle( 'No longer required', false, 0, true, $error, $user ); + if ( !$success ) { + $this->output( " (Failed!)" ); + } + if ( $result['hasTalk'] && $doDeleteTalk ) { + $title = Title::makeTitle( NS_MEDIAWIKI_TALK, $result['title'] ); + $this->output( "\n* [[$title]]" ); + $page = WikiPage::factory( $title ); + $error = ''; // Passed by ref + $success = $page->doDeleteArticle( 'Orphaned talk page of no longer required message', + false, 0, true, $error, $user ); + if ( !$success ) { + $this->output( " (Failed!)" ); + } + } + } + $this->output( "\n\ndone!\n" ); + } +} + +$maintClass = "DeleteEqualMessages"; +require_once RUN_MAINTENANCE_IF_MAIN;