Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslatablePageStore.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
7use InvalidArgumentException;
8use JobQueueGroup;
11use MediaWiki\Revision\RevisionRecord;
13use MessageIndex;
14use Title;
16use Wikimedia\Rdbms\ILoadBalancer;
17
26 private $messageIndex;
28 private $jobQueue;
30 private $revTagStore;
32 private $loadBalancer;
33
34 public function __construct(
35 MessageIndex $messageIndex,
36 JobQueueGroup $jobQueue,
37 RevTagStore $revTagStore,
38 ILoadBalancer $loadBalancer
39 ) {
40 $this->messageIndex = $messageIndex;
41 $this->jobQueue = $jobQueue;
42 $this->revTagStore = $revTagStore;
43 $this->loadBalancer = $loadBalancer;
44 }
45
46 public function move( Title $oldName, Title $newName ): void {
47 $oldTranslatablePage = TranslatablePage::newFromTitle( $oldName );
48 $newTranslatablePage = TranslatablePage::newFromTitle( $newName );
49 $oldGroupId = $oldTranslatablePage->getMessageGroupId();
50 $newGroupId = $newTranslatablePage->getMessageGroupId();
51
52 TranslateMetadata::moveMetadata( $oldGroupId, $newGroupId, TranslatablePage::METADATA_KEYS );
53
54 $this->moveMetadata( $oldGroupId, $newGroupId );
55
56 TranslatablePage::clearSourcePageCache();
57
58 // Re-render the pages to get everything in sync
59 MessageGroups::singleton()->recache();
60 // Update message index now so that, when after this job the MoveTranslationUnits hook
61 // runs in deferred updates, it will not run MessageIndexRebuildJob (T175834).
62 $this->messageIndex->rebuild();
63
64 $job = UpdateTranslatablePageJob::newFromPage( TranslatablePage::newFromTitle( $newName ) );
65 $this->jobQueue->push( $job );
66 }
67
68 public function handleNullRevisionInsert( TranslatableBundle $bundle, RevisionRecord $revision ): void {
69 if ( !$bundle instanceof TranslatablePage ) {
70 throw new InvalidArgumentException(
71 'Expected $bundle to be of type TranslatablePage, got ' . get_class( $bundle )
72 );
73 }
74
75 $this->revTagStore->replaceTag( $bundle->getTitle(), RevTagStore::TP_READY_TAG, $revision->getId() );
76 TranslatablePage::clearSourcePageCache();
77 }
78
79 public function delete( Title $title ): void {
80 $dbw = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
81
82 $this->revTagStore->removeTags( $title, RevTagStore::TP_MARK_TAG, RevTagStore::TP_READY_TAG );
83 $dbw->delete( 'translate_sections', [ 'trs_page' => $title->getArticleID() ], __METHOD__ );
84
85 $translatablePage = TranslatablePage::newFromTitle( $title );
86 $translatablePage->getTranslationPercentages();
87 foreach ( $translatablePage->getTranslationPages() as $page ) {
88 $page->invalidateCache();
89 }
90
91 $groupId = $translatablePage->getMessageGroupId();
92 TranslateMetadata::clearMetadata( $groupId, TranslatablePage::METADATA_KEYS );
93 $this->removeFromAggregateGroups( $groupId );
94 TranslatablePage::clearSourcePageCache();
95
96 MessageGroups::singleton()->recache();
97 $this->messageIndex->rebuild();
98 }
99
100 private function moveMetadata( string $oldGroupId, string $newGroupId ): void {
101 // Make the changes in aggregate groups metadata, if present in any of them.
102 $aggregateGroups = MessageGroups::getGroupsByType( AggregateMessageGroup::class );
103 TranslateMetadata::preloadGroups( array_keys( $aggregateGroups ), __METHOD__ );
104
105 foreach ( $aggregateGroups as $id => $group ) {
106 $subgroups = TranslateMetadata::get( $id, 'subgroups' );
107 if ( $subgroups === false ) {
108 continue;
109 }
110
111 $subgroups = explode( ',', $subgroups );
112 $subgroups = array_flip( $subgroups );
113 if ( isset( $subgroups[$oldGroupId] ) ) {
114 $subgroups[$newGroupId] = $subgroups[$oldGroupId];
115 unset( $subgroups[$oldGroupId] );
116 $subgroups = array_flip( $subgroups );
117 TranslateMetadata::set(
118 $group->getId(),
119 'subgroups',
120 implode( ',', $subgroups )
121 );
122 }
123 }
124
125 // Move discouraged status
126 $priority = MessageGroups::getPriority( $oldGroupId );
127 if ( $priority !== '' ) {
128 MessageGroups::setPriority( $newGroupId, $priority );
129 MessageGroups::setPriority( $oldGroupId, '' );
130 }
131 }
132
133 private function removeFromAggregateGroups( string $groupId ): void {
134 // remove the page from aggregate groups, if present in any of them.
135 $aggregateGroups = MessageGroups::getGroupsByType( AggregateMessageGroup::class );
136 TranslateMetadata::preloadGroups( array_keys( $aggregateGroups ), __METHOD__ );
137 foreach ( $aggregateGroups as $group ) {
138 $subgroups = TranslateMetadata::get( $group->getId(), 'subgroups' );
139 if ( $subgroups !== false ) {
140 $subgroups = explode( ',', $subgroups );
141 $subgroups = array_flip( $subgroups );
142 if ( isset( $subgroups[$groupId] ) ) {
143 unset( $subgroups[$groupId] );
144 $subgroups = array_flip( $subgroups );
145 TranslateMetadata::set(
146 $group->getId(),
147 'subgroups',
148 implode( ',', $subgroups )
149 );
150 }
151 }
152 }
153 }
154}
Groups multiple message groups together as one group.
Class to manage revision tags for translatable bundles.
const TP_READY_TAG
Indicates a revision of a translatable page that is marked for translation.
const TP_MARK_TAG
Indicates a revision of a page that can be marked for translation.
Translatable bundle represents a message group where its translatable content is defined on a wiki pa...
getTitle()
Return the title of the page where the translatable bundle is defined.
Mixed bag of methods related to translatable pages.
Job for updating translation units and translation pages when a translatable page is marked for trans...
Factory class for accessing message groups individually by id or all of them as an list.
Creates a database of keys in all groups, so that namespace and key can be used to get the groups the...