Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MessageGroupReviewStore.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\MessageGroupProcessing;
5
6use InvalidArgumentException;
8use MediaWiki\Logging\ManualLogEntry;
9use MediaWiki\SpecialPage\SpecialPage;
10use MediaWiki\User\User;
11use MessageGroup;
12use Wikimedia\Rdbms\IConnectionProvider;
13use Wikimedia\Rdbms\IResultWrapper;
14
21
22 private const TABLE_NAME = 'translate_groupreviews';
24 private ?array $priorityCache = null;
25
26 public function __construct(
27 private readonly IConnectionProvider $dbProvider,
28 private readonly HookRunner $hookRunner,
29 ) {
30 }
31
33 public function getState( MessageGroup $group, string $code ) {
34 $dbw = $this->dbProvider->getPrimaryDatabase();
35 return $dbw->newSelectQueryBuilder()
36 ->select( 'tgr_state' )
37 ->from( self::TABLE_NAME )
38 ->where( [
39 'tgr_group' => MessageGroupSubscriptionStore::getGroupIdForDatabase( $group ),
40 'tgr_lang' => $code
41 ] )
42 ->caller( __METHOD__ )
43 ->fetchField();
44 }
45
47 public function changeState( MessageGroup $group, string $code, string $newState, User $user ): bool {
48 $currentState = $this->getState( $group, $code );
49 if ( $currentState === $newState ) {
50 return false;
51 }
52
53 $row = [
54 'tgr_group' => MessageGroupSubscriptionStore::getGroupIdForDatabase( $group ),
55 'tgr_lang' => $code,
56 'tgr_state' => $newState,
57 ];
58 $dbw = $this->dbProvider->getPrimaryDatabase();
59 $dbw->newReplaceQueryBuilder()
60 ->replaceInto( self::TABLE_NAME )
61 ->uniqueIndexFields( [ 'tgr_group', 'tgr_lang' ] )
62 ->row( $row )
63 ->caller( __METHOD__ )
64 ->execute();
65
66 $entry = new ManualLogEntry( 'translationreview', 'group' );
67 $entry->setPerformer( $user );
68 $entry->setTarget( SpecialPage::getTitleFor( 'Translate', $group->getId() ) );
69 $entry->setParameters( [
70 '4::language' => $code,
71 '5::group-label' => $group->getLabel(),
72 '6::old-state' => $currentState,
73 '7::new-state' => $newState,
74 ] );
75 // @todo
76 // $entry->setComment( $comment );
77
78 $logId = $entry->insert();
79 $entry->publish( $logId );
80
81 $this->hookRunner->onTranslateEventMessageGroupStateChange( $group, $code, $currentState, $newState );
82
83 return true;
84 }
85
86 public function getGroupPriority( string $group ): ?string {
87 $this->preloadGroupPriorities( __METHOD__ );
88 $dbGroupId = MessageGroupSubscriptionStore::getGroupIdForDatabase( $group );
89 return $this->priorityCache[$dbGroupId] ?? null;
90 }
91
93 public function setGroupPriority( string $groupId, ?string $priority ): void {
94 $dbGroupId = MessageGroupSubscriptionStore::getGroupIdForDatabase( $groupId );
95 if ( $this->priorityCache !== null ) {
96 $this->priorityCache[$dbGroupId] = $priority;
97 }
98
99 $dbw = $this->dbProvider->getPrimaryDatabase();
100 $row = [
101 'tgr_group' => $dbGroupId,
102 'tgr_lang' => '*priority',
103 'tgr_state' => $priority
104 ];
105
106 if ( $priority === null ) {
107 unset( $row['tgr_state'] );
108 $dbw->newDeleteQueryBuilder()
109 ->deleteFrom( self::TABLE_NAME )
110 ->where( $row )
111 ->caller( __METHOD__ )
112 ->execute();
113 } else {
114 $dbw->newReplaceQueryBuilder()
115 ->replaceInto( self::TABLE_NAME )
116 ->uniqueIndexFields( [ 'tgr_group', 'tgr_lang' ] )
117 ->row( $row )
118 ->caller( __METHOD__ )
119 ->execute();
120 }
121 }
122
123 private function preloadGroupPriorities( string $caller ): void {
124 if ( $this->priorityCache !== null ) {
125 return;
126 }
127
128 $dbr = $this->dbProvider->getReplicaDatabase();
129 $res = $dbr->newSelectQueryBuilder()
130 ->select( [ 'tgr_group', 'tgr_state' ] )
131 ->from( self::TABLE_NAME )
132 ->where( [ 'tgr_lang' => '*priority' ] )
133 ->caller( $caller )
134 ->fetchResultSet();
135
136 $this->priorityCache = $this->result2map( $res, 'tgr_group', 'tgr_state' );
137 }
138
145 public function getWorkflowState( MessageGroup $group, string $languageCode ): ?string {
146 $result = $this->getWorkflowStates( [ $group ], [ $languageCode ] );
147 return $result->fetchRow()['tgr_state'] ?? null;
148 }
149
154 public function getWorkflowStatesForLanguage( string $languageCode, array $groupIds ): array {
155 $result = $this->getWorkflowStates( $groupIds, [ $languageCode ] );
156 $states = $this->result2map( $result, 'tgr_group', 'tgr_state' );
157
158 $finalResult = [];
159 foreach ( $groupIds as $groupId ) {
160 $dbGroupId = MessageGroupSubscriptionStore::getGroupIdForDatabase( $groupId );
161 if ( isset( $states[ $dbGroupId ] ) ) {
162 $finalResult[ $groupId ] = $states[ $dbGroupId ];
163 }
164 }
165
166 return $finalResult;
167 }
168
169 public function getWorkflowStatesForGroup( string $groupId ): array {
170 $result = $this->getWorkflowStates( [ $groupId ], null );
171 return $this->result2map( $result, 'tgr_lang', 'tgr_state' );
172 }
173
178 private function getWorkflowStates( ?array $groups, ?array $languageCodes ): IResultWrapper {
179 if ( $groups === null && $languageCodes === null ) {
180 throw new InvalidArgumentException( 'Either the $groupId or the $languageCode should be provided' );
181 }
182
183 $conditions = [];
184 if ( $groups ) {
185 $conditions['tgr_group'] = array_map(
186 MessageGroupSubscriptionStore::getGroupIdForDatabase( ... ),
187 $groups
188 );
189 }
190 if ( $languageCodes ) {
191 $conditions['tgr_lang'] = $languageCodes;
192 }
193
194 return $this->dbProvider->getReplicaDatabase()->newSelectQueryBuilder()
195 ->select( [ 'tgr_state', 'tgr_group', 'tgr_lang' ] )
196 ->from( self::TABLE_NAME )
197 ->where( $conditions )
198 ->caller( __METHOD__ )
199 ->fetchResultSet();
200 }
201
202 private function result2map( IResultWrapper $result, string $keyValue, string $valueValue ): array {
203 $map = [];
204 foreach ( $result as $row ) {
205 $map[$row->$keyValue] = $row->$valueValue;
206 }
207
208 return $map;
209 }
210
211}
Hook runner for the Translate extension.
Provides methods to get and change the state of a message group.
changeState(MessageGroup $group, string $code, string $newState, User $user)
getWorkflowState(MessageGroup $group, string $languageCode)
Get the current workflow state for the given message group for the given language.
setGroupPriority(string $groupId, ?string $priority)
Store priority for message group.
Store service for looking up and storing user subscriptions to message group.
Interface for message groups.
getId()
Returns the unique identifier for this group.
getLabel(?IContextSource $context=null)
Returns the human readable label (as plain text).