diff options
Diffstat (limited to 'MLEB/Translate/specials/SpecialManageGroups.php')
-rw-r--r-- | MLEB/Translate/specials/SpecialManageGroups.php | 110 |
1 files changed, 80 insertions, 30 deletions
diff --git a/MLEB/Translate/specials/SpecialManageGroups.php b/MLEB/Translate/specials/SpecialManageGroups.php index 5db58fa2..cec2b8ce 100644 --- a/MLEB/Translate/specials/SpecialManageGroups.php +++ b/MLEB/Translate/specials/SpecialManageGroups.php @@ -5,6 +5,7 @@ use MediaWiki\Extension\Translate\MessageSync\MessageSourceChange; use MediaWiki\Extension\Translate\Synchronization\DisplayGroupSynchronizationInfo; use MediaWiki\Extension\Translate\Synchronization\GroupSynchronizationCache; use MediaWiki\Extension\Translate\Synchronization\MessageUpdateParameter; +use MediaWiki\Logger\LoggerFactory; use MediaWiki\MediaWikiServices; use MediaWiki\Revision\RevisionLookup; use MediaWiki\Revision\SlotRecord; @@ -170,7 +171,8 @@ class SpecialManageGroups extends SpecialPage { // The above count as three $limit -= 3; - if ( $this->getConfig()->get( 'TranslateGroupSynchronizationCache' ) ) { + $groupSyncCacheEnabled = $this->getConfig()->get( 'TranslateGroupSynchronizationCache' ); + if ( $groupSyncCacheEnabled ) { $out->addHTML( $this->displayGroupSyncInfo->getGroupsInSyncHtml( $this->synchronizationCache->getGroupsInSync(), @@ -195,6 +197,12 @@ class SpecialManageGroups extends SpecialPage { ); $out->addHTML( Html::element( 'h2', [], $group->getLabel() ) ); + if ( $groupSyncCacheEnabled && $this->synchronizationCache->groupHasErrors( $id ) ) { + $out->addHTML( + Html::warningBox( $this->msg( 'translate-smg-group-sync-error-warn' )->escaped(), 'center' ) + ); + } + // Reduce page existance queries to one per group $lb = new LinkBatch(); $ns = $group->getNamespace(); @@ -267,6 +275,7 @@ class SpecialManageGroups extends SpecialPage { $title = Title::makeTitleSafe( $group->getNamespace(), "$key/$language" ); $id = self::changeId( $group->getId(), $language, $type, $key ); $noticeHtml = ''; + $isReusedKey = false; if ( $title && $type === 'addition' && $title->exists() ) { // The message has for some reason dropped out from cache @@ -278,6 +287,7 @@ class SpecialManageGroups extends SpecialPage { // leads to many other annoying problems. $type = 'change'; $noticeHtml .= Html::warningBox( $this->msg( 'translate-manage-key-reused' )->text() ); + $isReusedKey = true; } elseif ( $title && ( $type === 'deletion' || $type === 'change' ) && !$title->exists() ) { // This happens if a message key has been renamed // The change can be ignored. @@ -288,11 +298,10 @@ class SpecialManageGroups extends SpecialPage { $titleLink = $this->getLinkRenderer()->makeLink( $title ); if ( $type === 'deletion' ) { - $wiki = ContentHandler::getContentText( - $this->revLookup - ->getRevisionByTitle( $title ) - ->getContent( SlotRecord::MAIN ) - ); + $content = $this->revLookup + ->getRevisionByTitle( $title ) + ->getContent( SlotRecord::MAIN ); + $wiki = ( $content instanceof TextContent ) ? $content->getText() : ''; if ( $wiki === '' ) { $noticeHtml .= Html::warningBox( @@ -348,18 +357,35 @@ class SpecialManageGroups extends SpecialPage { $actions = ''; $importSelected = true; - if ( $group->getSourceLanguage() === $language ) { + $sourceLanguage = $group->getSourceLanguage(); + + if ( $sourceLanguage === $language ) { $importSelected = false; $label = $this->msg( 'translate-manage-action-fuzzy' )->text(); $actions .= Xml::radioLabel( $label, "msg/$id", "fuzzy", "f/$id", true ); } - $label = $this->msg( 'translate-manage-action-import' )->text(); - $actions .= Xml::radioLabel( $label, "msg/$id", "import", "imp/$id", $importSelected ); + if ( + $sourceLanguage !== $language && + $isReusedKey && + !self::isMessageDefinitionPresent( $group, $changes, $key ) + ) { + $noticeHtml .= Html::warningBox( + $this->msg( 'translate-manage-source-message-not-found' )->text(), + 'mw-translate-smg-notice-important' + ); - $label = $this->msg( 'translate-manage-action-ignore' )->text(); - $actions .= Xml::radioLabel( $label, "msg/$id", "ignore", "i/$id" ); - $limit--; + // Automatically ignore messages that don't have a definitions + $actions .= Html::hidden( "msg/$id", 'ignore', [ 'id' => "i/$id" ] ); + $limit--; + } else { + $label = $this->msg( 'translate-manage-action-import' )->text(); + $actions .= Xml::radioLabel( $label, "msg/$id", "import", "imp/$id", $importSelected ); + + $label = $this->msg( 'translate-manage-action-ignore' )->text(); + $actions .= Xml::radioLabel( $label, "msg/$id", "ignore", "i/$id" ); + $limit--; + } $oldContent = ContentHandler::makeContent( $wiki, $title ); $newContent = ContentHandler::makeContent( $params['content'], $title ); @@ -396,13 +422,18 @@ class SpecialManageGroups extends SpecialPage { $reader = \Cdb\Reader::open( $this->cdb ); $groups = $this->getGroupsFromCdb( $reader ); + $groupSyncCacheEnabled = $this->getConfig()->get( 'TranslateGroupSynchronizationCache' ); $postponed = []; foreach ( $groups as $groupId => $group ) { try { - $sourceChanges = MessageSourceChange::loadModifications( - TranslateUtils::deserialize( $reader->get( $groupId ) ) - ); + $changes = TranslateUtils::deserialize( $reader->get( $groupId ) ); + if ( $groupSyncCacheEnabled && $this->synchronizationCache->groupHasErrors( $groupId ) ) { + $postponed[$groupId] = $changes; + continue; + } + + $sourceChanges = MessageSourceChange::loadModifications( $changes ); $groupModificationJobs = []; $groupRenameJobData = []; $languages = $sourceChanges->getLanguages(); @@ -433,6 +464,10 @@ class SpecialManageGroups extends SpecialPage { } } + if ( $groupSyncCacheEnabled && !isset( $postponed[ $groupId ] ) ) { + $this->synchronizationCache->markGroupAsReviewed( $groupId ); + } + $modificationJobs[$groupId] = $groupModificationJobs; $renameJobData[$groupId] = $groupRenameJobData; } catch ( Exception $e ) { @@ -504,13 +539,10 @@ class SpecialManageGroups extends SpecialPage { return; } - $skin->getOutput()->addModuleStyles( 'ext.translate.tabgroup' ); - $tabs['namespaces'] = []; foreach ( $pagesInGroup as $spName => $section ) { $spClass = $specialPageFactory->getPage( $spName ); - // DisabledSpecialPage was added in MW 1.33 if ( $spClass === null || $spClass instanceof DisabledSpecialPage ) { continue; // Page explicitly disabled } @@ -558,7 +590,9 @@ class SpecialManageGroups extends SpecialPage { ): void { $changes = $sourceChanges->getRenames( $language ); foreach ( $changes as $key => $params ) { - if ( !isset( $changes[$key] ) ) { + // Since we're removing items from the array within the loop add + // a check here to ensure that the current key is still set. + if ( !isset( $changes[ $key ] ) ) { continue; } @@ -753,7 +787,9 @@ class SpecialManageGroups extends SpecialPage { $groupNamespace = $group->getNamespace(); foreach ( $renames as $key => $params ) { - if ( !isset( $renames[ $key] ) ) { + // Since we're removing items from the array within the loop add + // a check here to ensure that the current key is still set. + if ( !isset( $renames[$key] ) ) { continue; } @@ -943,13 +979,12 @@ class SpecialManageGroups extends SpecialPage { return [ false, $isCurrentKeyPresent ]; } - if ( $isSourceLang === false && $sourceChanges->isEqual( $language, $matchedKey ) ) { - // For non source language, if strings are equal, they are not shown on the UI - // and hence not submitted. - return [ false, $isCurrentKeyPresent ]; - } - - return [ true, $isCurrentKeyPresent ]; + // For non source language, if strings are equal, they are not shown on the UI + // and hence not submitted. + return [ + $isSourceLang || !$sourceChanges->isEqual( $language, $matchedKey ), + $isCurrentKeyPresent + ]; } private function getProcessingErrorMessage( array $errorGroups, int $totalGroupCount ): string { @@ -1037,11 +1072,26 @@ class SpecialManageGroups extends SpecialPage { if ( $this->getConfig()->get( 'TranslateGroupSynchronizationCache' ) ) { $this->synchronizationCache->addMessages( $groupId, ...$messages ); $this->synchronizationCache->markGroupForSync( $groupId ); + + LoggerFactory::getInstance( 'Translate.GroupSynchronization' )->info( + '[' . __CLASS__ . '] Synchronization started for {groupId} by {user}', + [ + 'groupId' => $groupId, + 'user' => $this->getUser()->getName() + ] + ); } - $jobQueueInstance->push( $groupJobs ); - } + // There is posibility for a race condition here: the translate_cache table / group sync + // cache is not yet populated with the messages to be processed, but the jobs start + // running and try to remove the message from the cache. This results in a "Key not found" + // error. Avoid this condition by using a DeferredUpdate. + DeferredUpdates::addCallableUpdate( + static function () use ( $jobQueueInstance, $groupJobs ) { + $jobQueueInstance->push( $groupJobs ); + } + ); - $jobQueueInstance->push( MessageIndexRebuildJob::newJob() ); + } } } |