17 public function __construct() {
18 parent::__construct();
19 $this->addDescription(
'Script for processing message changes in file based message groups' );
22 '(optional) Comma separated list of group IDs to process (can use * as wildcard). ' .
29 '(optional) Comma separated list of group IDs to not process (can use * ' .
30 'as wildcard). Overrides --group parameter.',
36 '(optional) Unique name to avoid conflicts with multiple invocations of this script.',
42 '(optional) Import "safe" changes: message additions when no other kind of changes.'
45 'skip-group-sync-check',
46 '(optional) Skip importing group if synchronization is still in progress or if there ' .
47 'was an error during synchronization. See: ' .
48 'https://www.mediawiki.org/wiki/Help:Extension:Translate/Group_management#Strong_synchronization'
52 '(optional) Import non renames: if a language in a group has only additions and changes to existing ' .
53 ' strings, then the additions are imported'
55 $this->requireExtension(
'Translate' );
58 public function execute() {
59 $name = $this->getOption(
'name', MessageChangeStorage::DEFAULT_NAME );
61 $this->fatalError(
'Invalid name' );
64 $groups = $this->getGroups();
66 $comparator = Services::getInstance()->getExternalMessageSourceStateComparator();
68 $importStrategy = $this->getImportStrategy();
69 $skipGroupSyncCache = $this->hasOption(
'skip-group-sync-check' );
71 $services = Services::getInstance();
72 $importer = $services->getExternalMessageSourceStateImporter();
74 foreach ( $groups as $id => $group ) {
75 $status = $importer->canImportGroup( $group, $skipGroupSyncCache );
76 if ( !$status->isOK() ) {
77 $this->error( $status->getMessage()->plain() );
82 $changes[$id] = $comparator->processGroup( $group );
83 }
catch ( Exception $e ) {
84 $errorMsg =
"Exception occurred while processing group: $id.\nException: $e";
85 $this->error( $errorMsg );
86 error_log( $errorMsg );
95 if ( $changes === [] ) {
96 if ( $importStrategy === ExternalMessageSourceStateImporter::IMPORT_NONE ) {
97 $this->output(
"No changes found\n" );
103 $info = $importer->import( $changes, $name, $importStrategy );
104 $this->printChangeInfo( $info );
111 private function getGroups(): array {
112 $groups = MessageGroups::getGroupsByType( FileBasedMessageGroup::class );
115 $include = $this->getOption(
'group',
'*' );
116 $include = explode(
',', $include );
117 $include = array_map(
'trim', $include );
118 $include = MessageGroups::expandWildcards( $include );
121 $exclude = $this->getOption(
'skipgroup',
'' );
122 $exclude = explode(
',', $exclude );
123 $exclude = array_map(
'trim', $exclude );
124 $exclude = MessageGroups::expandWildcards( $exclude );
127 $include = array_flip( $include );
128 $exclude = array_flip( $exclude );
130 return array_filter( $groups,
131 static function (
MessageGroup $group ) use ( $include, $exclude ) {
132 $id = $group->
getId();
134 return isset( $include[$id] ) && !isset( $exclude[$id] );
139 private function printChangeInfo( array $info ):
void {
140 foreach ( $info[
'processed'] as $group => $languages ) {
141 $newMessageCount = array_sum( $languages );
142 if ( $newMessageCount ) {
143 $this->output(
"Imported $newMessageCount new messages or translations for $group.\n" );
147 if ( $info[
'skipped'] !== [] ) {
148 $skipped = implode(
', ', array_keys( $info[
'skipped'] ) );
149 $this->output(
"There are changes to check for groups $skipped.\n" );
150 $url = SpecialPage::getTitleFor(
'ManageMessageGroups', $info[
'name'] )->getFullURL();
151 $this->output(
"You can process them at $url\n" );
155 private function getImportStrategy():
int {
156 $importStrategy = ExternalMessageSourceStateImporter::IMPORT_NONE;
157 if ( $this->hasOption(
'safe-import' ) ) {
158 $importStrategy = ExternalMessageSourceStateImporter::IMPORT_SAFE;
161 if ( $this->hasOption(
'import-non-renames' ) ) {
162 $importStrategy = ExternalMessageSourceStateImporter::IMPORT_NON_RENAMES;
165 return $importStrategy;