Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
processMessageChanges.php
Go to the documentation of this file.
1<?php
12// Standard boilerplate to define $IP
13if ( getenv( 'MW_INSTALL_PATH' ) !== false ) {
14 $IP = getenv( 'MW_INSTALL_PATH' );
15} else {
16 $dir = __DIR__;
17 $IP = "$dir/../../..";
18}
19require_once "$IP/maintenance/Maintenance.php";
20
24use MediaWiki\MediaWikiServices;
25
35class ProcessMessageChanges extends Maintenance {
36 public function __construct() {
37 parent::__construct();
38 $this->addDescription( 'Script for processing message changes in file based message groups' );
39 $this->addOption(
40 'group',
41 '(optional) Comma separated list of group IDs to process (can use * as wildcard). ' .
42 'Default: "*"',
43 false, /*required*/
44 true /*has arg*/
45 );
46 $this->addOption(
47 'skipgroup',
48 '(optional) Comma separated list of group IDs to not process (can use * ' .
49 'as wildcard). Overrides --group parameter.',
50 false, /*required*/
51 true /*has arg*/
52 );
53 $this->addOption(
54 'name',
55 '(optional) Unique name to avoid conflicts with multiple invocations of this script.',
56 false, /*required*/
57 true /*has arg*/
58 );
59 $this->addOption(
60 'safe-import',
61 '(optional) Import "safe" changes: message additions when no other kind of changes.'
62 );
63 $this->addOption(
64 'skip-group-sync-check',
65 '(optional) Skip importing group if synchronization is still in progress or if there ' .
66 'was an error during synchronization. See: ' .
67 'https://www.mediawiki.org/wiki/Help:Extension:Translate/Group_management#Strong_synchronization'
68 );
69 $this->requireExtension( 'Translate' );
70 }
71
72 public function execute() {
73 $name = $this->getOption( 'name', MessageChangeStorage::DEFAULT_NAME );
74 if ( !MessageChangeStorage::isValidCdbName( $name ) ) {
75 $this->fatalError( 'Invalid name' );
76 }
77
78 $groups = $this->getGroups();
79 $changes = [];
81
82 $scripted = $this->hasOption( 'safe-import' );
83 $skipGroupSyncCache = $this->hasOption( 'skip-group-sync-check' );
84
85 $services = Services::getInstance();
86 $groupSyncCache = $services->getGroupSynchronizationCache();
87 $groupSyncCacheEnabled = MediaWikiServices::getInstance()->getMainConfig()
88 ->get( 'TranslateGroupSynchronizationCache' );
89
91 foreach ( $groups as $id => $group ) {
92 if ( $groupSyncCacheEnabled && !$skipGroupSyncCache ) {
93 if ( $groupSyncCache->isGroupBeingProcessed( $id ) ) {
94 $this->error( "Group $id is currently being synchronized; skipping processing of changes\n" );
95 continue;
96 }
97
98 if ( $groupSyncCache->groupHasErrors( $id ) ) {
99 $this->error( "Skipping $id due to an error during synchronization\n" );
100 continue;
101 }
102 }
103
104 if ( !$scripted ) {
105 $this->output( "Processing $id\n" );
106 }
107 try {
108 $changes[$id] = $comparator->processGroup( $group, $comparator::ALL_LANGUAGES );
109 } catch ( Exception $e ) {
110 $errorMsg = "Exception occurred while processing group: $id.\nException: $e";
111 $this->error( $errorMsg );
112 error_log( $errorMsg );
113 }
114 }
115
116 // Remove all groups without changes
117 $changes = array_filter( $changes, static function ( MessageSourceChange $change ) {
118 return $change->getAllModifications() !== [];
119 } );
120
121 if ( $changes === [] ) {
122 if ( !$scripted ) {
123 $this->output( "No changes found\n" );
124 }
125
126 return;
127 }
128
129 if ( $scripted ) {
130 $importer = $services->getExternalMessageSourceStateImporter();
131 $info = $importer->importSafe( $changes, $name );
132 $this->printChangeInfo( $info );
133
134 return;
135 }
136
137 $file = MessageChangeStorage::getCdbPath( $name );
138
139 MessageChangeStorage::writeChanges( $changes, $file );
140 $url = SpecialPage::getTitleFor( 'ManageMessageGroups', $name )->getFullURL();
141 $this->output( "Process changes at $url\n" );
142 }
143
148 protected function getGroups() {
149 $groups = MessageGroups::getGroupsByType( FileBasedMessageGroup::class );
150
151 // Include all if option not given
152 $include = $this->getOption( 'group', '*' );
153 $include = explode( ',', $include );
154 $include = array_map( 'trim', $include );
155 $include = MessageGroups::expandWildcards( $include );
156
157 // Exclude nothing if option not given
158 $exclude = $this->getOption( 'skipgroup', '' );
159 $exclude = explode( ',', $exclude );
160 $exclude = array_map( 'trim', $exclude );
161 $exclude = MessageGroups::expandWildcards( $exclude );
162
163 // Flip to allow isset
164 $include = array_flip( $include );
165 $exclude = array_flip( $exclude );
166
167 $groups = array_filter( $groups,
168 static function ( MessageGroup $group ) use ( $include, $exclude ) {
169 $id = $group->getId();
170
171 return isset( $include[$id] ) && !isset( $exclude[$id] );
172 }
173 );
174
175 return $groups;
176 }
177
178 protected function printChangeInfo( array $info ) {
179 foreach ( $info['processed'] as $group => $languages ) {
180 $newMessageCount = array_sum( $languages );
181 if ( $newMessageCount ) {
182 $this->output( "Imported $newMessageCount new messages or translations for $group.\n" );
183 }
184 }
185
186 if ( $info['skipped'] !== [] ) {
187 $skipped = implode( ', ', array_keys( $info['skipped'] ) );
188 $this->output( "There are changes to check for groups $skipped.\n" );
189 $url = SpecialPage::getTitleFor( 'ManageMessageGroups', $info['name'] )->getFullURL();
190 $this->output( "You can process them at $url\n" );
191 }
192 }
193}
194
195$maintClass = ProcessMessageChanges::class;
196require_once RUN_MAINTENANCE_IF_MAIN;
Class is use to track the changes made when importing messages from the remote sources using processM...
Minimal service container.
Definition Services.php:38
A simple string comparator, that compares two strings and determines if they are an exact match.
Script for processing message changes in file based message groups.
getGroups()
Gets list of message groups filtered by user input.
Interface for message groups.
getId()
Returns the unique identifier for this group.