31 private $groupSynchronizationCache;
33 private $jobQueueGroup;
37 private $messageIndex;
39 public function __construct(
42 JobQueueGroup $jobQueueGroup,
43 LoggerInterface $logger,
46 $this->config = $config;
47 $this->groupSynchronizationCache = $groupSynchronizationCache;
48 $this->jobQueueGroup = $jobQueueGroup;
49 $this->logger = $logger;
50 $this->messageIndex = $messageIndex;
58 public function importSafe( array $changeData,
string $name ): array {
63 $groupSyncCacheEnabled = $this->config->get(
'TranslateGroupSynchronizationCache' );
65 foreach ( $changeData as $groupId => $changesForGroup ) {
66 $group = MessageGroups::getGroup( $groupId );
68 unset( $changeData[$groupId] );
73 $this->logger->warning(
74 '[ExternalMessageSourceStateImporter] Expected FileBasedMessageGroup, ' .
75 'but got {class} for group {groupId}',
77 'class' => get_class( $group ),
81 unset( $changeData[$groupId] );
85 $processed[$groupId] = [];
86 $languages = $changesForGroup->getLanguages();
89 $groupSafeLanguages = self::identifySafeLanguages( $group, $changesForGroup );
91 foreach ( $languages as $language ) {
92 if ( !$groupSafeLanguages[ $language ] ) {
93 $skipped[$groupId] =
true;
97 $additions = $changesForGroup->getAdditions( $language );
98 if ( $additions === [] ) {
102 [ $groupLanguageJobs, $groupProcessed ] = $this->createMessageUpdateJobs(
103 $group, $additions, $language
106 $groupJobs = array_merge( $groupJobs, $groupLanguageJobs );
107 $processed[$groupId][$language] = $groupProcessed;
109 $changesForGroup->removeChangesForLanguage( $language );
110 $group->getMessageGroupCache( $language )->create();
114 if ( $groupSyncCacheEnabled && isset( $skipped[$groupId] ) ) {
115 $this->groupSynchronizationCache->markGroupAsInReview( $groupId );
118 if ( $groupJobs !== [] ) {
119 if ( $groupSyncCacheEnabled ) {
120 $this->updateGroupSyncInfo( $groupId, $groupJobs );
122 $jobs = array_merge( $jobs, $groupJobs );
132 $processed = array_filter( $processed );
134 $file = MessageChangeStorage::getCdbPath( $name );
135 MessageChangeStorage::writeChanges( $changeData, $file );
136 $this->jobQueueGroup->push( $jobs );
139 'processed' => $processed,
140 'skipped' => $skipped,
146 private function createMessageUpdateJobs(
151 $groupId = $group->getId();
154 foreach ( $additions as $addition ) {
156 $name =
"{$addition['key']}/$language";
158 $title = Title::makeTitleSafe( $namespace, $name );
160 wfWarn(
"Invalid title for group $groupId key {$addition['key']}" );
164 $jobs[] = MessageUpdateJob::newJob( $title, $addition[
'content'] );
168 return [ $jobs, $processed ];
175 private function updateGroupSyncInfo(
string $groupId, array $groupJobs ): void {
177 $groupMessageKeys = [];
178 foreach ( $groupJobs as $job ) {
179 $messageParams[] = MessageUpdateParameter::createFromJob( $job );
182 $groupMessageKeys[(
new MessageHandle( $job->getTitle() ) )->getKey()] =
true;
186 if ( $group ===
null ) {
188 throw new RuntimeException(
"Did not find group $groupId" );
191 $this->messageIndex->storeInterim( $group, array_keys( $groupMessageKeys ) );
193 $this->groupSynchronizationCache->addMessages( $groupId, ...$messageParams );
194 $this->groupSynchronizationCache->markGroupForSync( $groupId );
197 '[ExternalMessageSourceStateImporter] Synchronization started for {groupId}',
198 [
'groupId' => $groupId ]
206 private static function identifySafeLanguages(
208 MessageSourceChange $changesForGroup
210 $sourceLanguage = $group->getSourceLanguage();
211 $safeLanguagesMap = [];
212 $modifiedLanguages = $changesForGroup->getLanguages();
215 $safeLanguagesMap[ $sourceLanguage ] =
false;
216 foreach ( $modifiedLanguages as $language ) {
217 $safeLanguagesMap[ $language ] =
false;
220 if ( !$changesForGroup->hasOnly( $sourceLanguage, MessageSourceChange::ADDITION ) ) {
221 return $safeLanguagesMap;
224 $sourceLanguageKeyCache = [];
225 foreach ( $changesForGroup->getAdditions( $sourceLanguage ) as $change ) {
226 if ( $change[
'content'] ===
'' ) {
227 return $safeLanguagesMap;
230 $sourceLanguageKeyCache[ $change[
'key'] ] =
true;
233 $safeLanguagesMap[ $sourceLanguage ] =
true;
239 if ( $sourceLanguageKeyCache ) {
240 array_splice( $modifiedLanguages, array_search( $sourceLanguage, $modifiedLanguages ), 1 );
243 foreach ( $modifiedLanguages as $language ) {
244 if ( !$changesForGroup->hasOnly( $language, MessageSourceChange::ADDITION ) ) {
248 foreach ( $changesForGroup->getAdditions( $language ) as $change ) {
249 if ( $change[
'content'] ===
'' ) {
253 $msgKey = $change[
'key'];
255 if ( !isset( $sourceLanguageKeyCache[ $msgKey ] ) ) {
259 $sourceHandle =
new MessageHandle( Title::makeTitle( $groupNamespace, $msgKey ) );
260 $sourceLanguageKeyCache[ $msgKey ] = $sourceHandle->isValid();
263 if ( !$sourceLanguageKeyCache[ $msgKey ] ) {
268 $safeLanguagesMap[ $language ] =
true;
271 return $safeLanguagesMap;