Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MessageGroupStatsTable.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Statistics;
5
6use Html;
7use Language;
10use MediaWiki\Linker\LinkRenderer;
11use MessageGroup;
13use MessageLocalizer;
14use SpecialPage;
15use Title;
17use Wikimedia\Rdbms\ILoadBalancer;
18
26 private ILoadBalancer $loadBalancer;
27 private LinkRenderer $linkRenderer;
28 private MessageLocalizer $localizer;
29 private Language $interfaceLanguage;
30 private StatsTable $table;
31 private MessageGroupReviewStore $groupReviewStore;
33 private bool $incompleteStats;
34 private array $languageNames;
35 private Title $translateTitle;
37 private array $states;
38 private bool $haveTranslateWorkflowStates;
39
40 public function __construct(
41 StatsTable $table,
42 ILoadBalancer $loadBalancer,
43 LinkRenderer $linkRenderer,
44 MessageLocalizer $localizer,
45 Language $interfaceLanguage,
46 MessageGroupReviewStore $groupReviewStore,
47 bool $haveTranslateWorkflowStates
48 ) {
49 $this->table = $table;
50 $this->loadBalancer = $loadBalancer;
51 $this->linkRenderer = $linkRenderer;
52 $this->incompleteStats = false;
53 $this->localizer = $localizer;
54 $this->interfaceLanguage = $interfaceLanguage;
55 $this->groupReviewStore = $groupReviewStore;
56 $this->haveTranslateWorkflowStates = $haveTranslateWorkflowStates;
57 $this->languageNames = Utilities::getLanguageNames( $this->interfaceLanguage->getCode() );
58 $this->translateTitle = SpecialPage::getTitleFor( 'Translate' );
59 }
60
61 public function get(
62 array $stats,
63 MessageGroup $group,
64 bool $noComplete,
65 bool $noEmpty
66 ): ?string {
67 $out = '';
68 $rowCount = 0;
69 $totals = MessageGroupStats::getEmptyStats();
70 $groupId = $group->getId();
71
72 $languages = array_keys(
73 Utilities::getLanguageNames( $this->interfaceLanguage->getCode() )
74 );
75 sort( $languages );
76 $this->filterPriorityLangs( $languages, $groupId, $stats );
77
78 // If workflow states are configured, adds a workflow states column
79 if ( $this->haveTranslateWorkflowStates ) {
80 $this->table->addExtraColumn( $this->localizer->msg( 'translate-stats-workflow' ) );
81 }
82
83 foreach ( $languages as $code ) {
84 if ( $this->table->isExcluded( $group, $code ) ) {
85 continue;
86 }
87
88 $languageStats = $stats[$code];
89 $row = $this->makeRow(
90 $this->table,
91 $code,
92 $languageStats,
93 $group,
94 $rowCount,
95 $noComplete,
96 $noEmpty
97 );
98 if ( $row ) {
99 $rowCount += 1;
100 $out .= $row;
101 $totals = MessageGroupStats::multiAdd( $totals, $languageStats );
102 }
103 }
104
105 if ( $out ) {
106 $this->table->setMainColumnHeader( $this->localizer->msg( 'translate-mgs-column-language' ) );
107 $out = $this->table->createHeader() . "\n" . $out;
108 $out .= Html::closeElement( 'tbody' );
109
110 $out .= Html::openElement( 'tfoot' );
111 $out .= $this->table->makeTotalRow(
112 $this->localizer->msg( 'translate-mgs-totals' )->numParams( $rowCount ),
113 $totals
114 );
115 $out .= Html::closeElement( 'tfoot' );
116
117 $out .= Html::closeElement( 'table' );
118
119 return $out;
120 } else {
121 return null;
122 }
123 }
124
125 public function areStatsIncomplete(): bool {
126 return $this->incompleteStats;
127 }
128
129 private function makeRow(
130 StatsTable $table,
131 string $languageCode,
132 array $stats,
133 MessageGroup $group,
134 int $rowCount,
135 bool $noComplete,
136 bool $noEmpty
137 ): ?string {
138 $total = $stats[MessageGroupStats::TOTAL];
139 $translated = $stats[MessageGroupStats::TRANSLATED];
140 $fuzzy = $stats[MessageGroupStats::FUZZY];
141 $extra = [];
142
143 if ( $total === null ) {
144 $this->incompleteStats = true;
145 } else {
146 if ( $noComplete && $fuzzy === 0 && $translated === $total ) {
147 return null;
148 }
149
150 if ( $noEmpty && $translated === 0 && $fuzzy === 0 ) {
151 return null;
152 }
153
154 // Skip below 2% if "don't show without translations" is checked.
155 if ( $noEmpty && ( $translated / $total ) < 0.02 ) {
156 return null;
157 }
158
159 if ( $translated === $total ) {
160 $extra = [ 'action' => 'proofread' ];
161 }
162 }
163
164 $rowParams = [];
165 if ( $rowCount % 2 === 0 ) {
166 $rowParams[ 'class' ] = 'tux-statstable-even';
167 }
168
169 $out = "\t" . Html::openElement( 'tr', $rowParams );
170 $out .= "\n\t\t" . $this->getMainColumnCell( $languageCode, $extra, $group->getId() );
171 $out .= $table->makeNumberColumns( $stats );
172 $out .= $this->getWorkflowStateCell( $table, $languageCode, $group );
173
174 $out .= "\n\t" . Html::closeElement( 'tr' ) . "\n";
175
176 return $out;
177 }
178
179 private function getMainColumnCell( string $code, array $params, string $groupId ): string {
180 if ( isset( $this->languageNames[$code] ) ) {
181 $text = "$code: {$this->languageNames[$code]}";
182 } else {
183 $text = $code;
184 }
185
186 // Do not render links when generating table for MessagePrefixMessageGroup
187 // as this is a dynamic group whose contents are based on user input
188 if ( $groupId === '!prefix' ) {
189 return Html::rawElement( 'td', [], $text );
190 }
191
192 $queryParameters = $params + [
193 'group' => $groupId,
194 'language' => $code
195 ];
196
197 $link = $this->linkRenderer->makeKnownLink(
198 $this->translateTitle,
199 $text,
200 [],
201 $queryParameters
202 );
203
204 return Html::rawElement( 'td', [], $link );
205 }
206
208 private function getWorkflowStateCell( StatsTable $table, string $language, MessageGroup $group ): string {
209 if ( !$this->haveTranslateWorkflowStates ) {
210 return '';
211 }
212
213 $this->states ??= $this->groupReviewStore->getWorkflowStatesForGroup( $group->getId() );
214 return $table->makeWorkflowStateCell( $this->states[$language] ?? null, $group, $language );
215 }
216
222 private function filterPriorityLangs( array &$languages, string $group, array $cache ): void {
223 $filterLangs = TranslateMetadata::get( $group, 'prioritylangs' );
224 if ( $filterLangs === false || strlen( $filterLangs ) === 0 ) {
225 // No restrictions, keep everything
226 return;
227 }
228 $filter = array_flip( explode( ',', $filterLangs ) );
229 foreach ( $languages as $id => $code ) {
230 if ( isset( $filter[$code] ) ) {
231 continue;
232 }
233 $translated = $cache[$code][1];
234 if ( $translated === 0 ) {
235 unset( $languages[$id] );
236 }
237 }
238 }
239}
Provides methods to get and change the state of a message group.
Used to build the table displayed on Special:MessageGroupStats.
Implements generation of HTML stats table.
makeNumberColumns(array $stats)
Makes partial row from completion numbers.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:31
This class abstract MessageGroup statistics calculation and storing.
Interface for message groups.