diff options
Diffstat (limited to 'www/wiki/extensions/Translate/tag/TranslatablePageMoveJob.php')
-rw-r--r-- | www/wiki/extensions/Translate/tag/TranslatablePageMoveJob.php | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/tag/TranslatablePageMoveJob.php b/www/wiki/extensions/Translate/tag/TranslatablePageMoveJob.php new file mode 100644 index 00000000..27f4b48d --- /dev/null +++ b/www/wiki/extensions/Translate/tag/TranslatablePageMoveJob.php @@ -0,0 +1,168 @@ +<?php +/** + * Contains class with job for moving translation pages. + * + * @file + * @author Niklas Laxström + * @license GPL-2.0-or-later + */ + +/** + * Contains class with job for moving translation pages. Used together with + * SpecialPageTranslationMovePage class. + * + * @ingroup PageTranslation JobQueue + */ +class TranslatablePageMoveJob extends Job { + + /** + * @param Title $source + * @param Title $target + * @param array $moves should include base-source and base-target + * @param string $summary + * @param User $performer + * @return TranslatablePageMoveJob + */ + public static function newJob( + Title $source, Title $target, array $moves, $summary, User $performer + ) { + $params = [ + 'source' => $source->getPrefixedText(), + 'target' => $target->getPrefixedText(), + 'moves' => $moves, + 'summary' => $summary, + 'performer' => $performer->getName(), + ]; + + $self = new self( $target, $params ); + $self->lock( array_keys( $moves ) ); + $self->lock( array_values( $moves ) ); + + return $self; + } + + public function __construct( $title, $params = [] ) { + parent::__construct( __CLASS__, $title, $params ); + } + + public function run() { + $sourceTitle = Title::newFromText( $this->params['source'] ); + $targetTitle = Title::newFromText( $this->params['target'] ); + $sourcePage = TranslatablePage::newFromTitle( $sourceTitle ); + $targetPage = TranslatablePage::newFromTitle( $targetTitle ); + + $this->doMoves(); + + $this->moveMetadata( + $sourcePage->getMessageGroupId(), + $targetPage->getMessageGroupId() + ); + + $entry = new ManualLogEntry( 'pagetranslation', 'moveok' ); + $entry->setPerformer( User::newFromName( $this->params['performer'] ) ); + $entry->setParameters( [ 'target' => $this->params['target'] ] ); + $entry->setTarget( $sourceTitle ); + $logid = $entry->insert(); + $entry->publish( $logid ); + + // Re-render the pages to get everything in sync + MessageGroups::singleton()->recache(); + // Update message index now so that, when after this job the MoveTranslationUnits hook + // runs in deferred updates, it will not run MessageIndexRebuildJob (T175834). + MessageIndex::singleton()->rebuild(); + + $job = TranslationsUpdateJob::newFromPage( $targetPage ); + JobQueueGroup::singleton()->push( $job ); + + return true; + } + + protected function doMoves() { + $fuzzybot = FuzzyBot::getUser(); + $performer = User::newFromName( $this->params['performer'] ); + + PageTranslationHooks::$allowTargetEdit = true; + + foreach ( $this->params['moves'] as $source => $target ) { + $sourceTitle = Title::newFromText( $source ); + $targetTitle = Title::newFromText( $target ); + + if ( $source === $this->params['source'] ) { + $user = $performer; + } else { + $user = $fuzzybot; + } + + $mover = new MovePage( $sourceTitle, $targetTitle ); + $status = $mover->move( $user, $this->params['summary'], false ); + if ( !$status->isOK() ) { + $entry = new ManualLogEntry( 'pagetranslation', 'movenok' ); + $entry->setPerformer( $performer ); + $entry->setTarget( $sourceTitle ); + $entry->setParameters( [ + 'target' => $target, + 'error' => $status->getErrorsArray(), + ] ); + $logid = $entry->insert(); + $entry->publish( $logid ); + } + + $this->unlock( [ $source, $target ] ); + } + + PageTranslationHooks::$allowTargetEdit = false; + } + + protected function moveMetadata( $oldGroupId, $newGroupId ) { + $types = [ 'prioritylangs', 'priorityforce', 'priorityreason' ]; + + TranslateMetadata::preloadGroups( [ $oldGroupId, $newGroupId ] ); + foreach ( $types as $type ) { + $value = TranslateMetadata::get( $oldGroupId, $type ); + if ( $value !== false ) { + TranslateMetadata::set( $oldGroupId, $type, false ); + TranslateMetadata::set( $newGroupId, $type, $value ); + } + } + + // Make the changes in aggregate groups metadata, if present in any of them. + $aggregateGroups = MessageGroups::getGroupsByType( AggregateMessageGroup::class ); + TranslateMetadata::preloadGroups( array_keys( $aggregateGroups ) ); + + foreach ( $aggregateGroups as $id => $group ) { + $subgroups = TranslateMetadata::get( $id, 'subgroups' ); + if ( $subgroups === false ) { + continue; + } + + $subgroups = explode( ',', $subgroups ); + $subgroups = array_flip( $subgroups ); + if ( isset( $subgroups[$oldGroupId] ) ) { + $subgroups[$newGroupId] = $subgroups[$oldGroupId]; + unset( $subgroups[$oldGroupId] ); + $subgroups = array_flip( $subgroups ); + TranslateMetadata::set( + $group->getId(), + 'subgroups', + implode( ',', $subgroups ) + ); + } + } + } + + private function lock( array $titles ) { + $cache = wfGetCache( CACHE_ANYTHING ); + $data = []; + foreach ( $titles as $title ) { + $data[wfMemcKey( 'pt-lock', sha1( $title ) )] = 'locked'; + } + $cache->setMulti( $data ); + } + + private function unlock( array $titles ) { + $cache = wfGetCache( CACHE_ANYTHING ); + foreach ( $titles as $title ) { + $cache->delete( wfMemcKey( 'pt-lock', sha1( $title ) ) ); + } + } +} |