Index: trunk/extensions/Translate/SpecialLanguageStats.php |
— | — | @@ -116,16 +116,17 @@ |
117 | 117 | * Statistics table element (heading or regular cell) |
118 | 118 | * |
119 | 119 | * @todo document |
120 | | - * @param $in \string |
121 | | - * @param $bgcolor \string |
122 | | - * @return \string |
| 120 | + * @param $in \string Element contents. |
| 121 | + * @param $bgcolor \string Backround color in ABABAB format. |
| 122 | + * @param $sort \string Value used for sorting. |
| 123 | + * @return \string Html td element. |
123 | 124 | */ |
124 | | - function element( $in, $bgcolor = '' ) { |
125 | | - if ( $bgcolor ) { |
126 | | - $element = Xml::element( 'td', array( 'style' => "background-color: #" . $bgcolor ), $in ); |
127 | | - } else { |
128 | | - $element = Xml::element( 'td', null, $in ); |
129 | | - } |
| 125 | + function element( $in, $bgcolor = '', $sort = '' ) { |
| 126 | + $attributes = array(); |
| 127 | + if ( $sort ) $attributes['data-sort-value'] = $sort; |
| 128 | + if ( $bgcolor ) $attributes['style'] = "background-color: #" . $bgcolor; |
| 129 | + |
| 130 | + $element = Xml::element( 'td', $attributes, $in ); |
130 | 131 | return "\t\t" . $element . "\n"; |
131 | 132 | } |
132 | 133 | |
— | — | @@ -133,24 +134,18 @@ |
134 | 135 | $v = @round( 255 * $subset / $total ); |
135 | 136 | |
136 | 137 | if ( $fuzzy ) { |
137 | | - /** |
138 | | - * Weigh fuzzy with factor 20. |
139 | | - */ |
| 138 | + // Weigh fuzzy with factor 20. |
140 | 139 | $v = $v * 20; |
141 | 140 | if ( $v > 255 ) $v = 255; |
142 | 141 | $v = 255 - $v; |
143 | 142 | } |
144 | 143 | |
145 | 144 | if ( $v < 128 ) { |
146 | | - /** |
147 | | - * Red to Yellow |
148 | | - */ |
| 145 | + // Red to Yellow |
149 | 146 | $red = 'FF'; |
150 | 147 | $green = sprintf( '%02X', 2 * $v ); |
151 | 148 | } else { |
152 | | - /** |
153 | | - * Yellow to Green |
154 | | - */ |
| 149 | + // Yellow to Green |
155 | 150 | $red = sprintf( '%02X', 2 * ( 255 - $v ) ); |
156 | 151 | $green = 'FF'; |
157 | 152 | } |
— | — | @@ -205,23 +200,13 @@ |
206 | 201 | function getGroupStats( $code, $suppressComplete = false ) { |
207 | 202 | global $wgUser, $wgLang, $wgOut; |
208 | 203 | |
209 | | - $errorString = '<error>'; |
210 | 204 | $out = ''; |
211 | 205 | |
212 | 206 | $cache = new ArrayMemoryCache( 'groupstats' ); |
213 | | - |
214 | | - /** |
215 | | - * Fetch groups stats have to be displayed for. |
216 | | - */ |
217 | 207 | $groups = MessageGroups::singleton()->getGroups(); |
218 | 208 | |
219 | | - /** |
220 | | - * Get statistics for the message groups, |
221 | | - */ |
222 | 209 | foreach ( $groups as $groupName => $g ) { |
223 | | - /** |
224 | | - * Do not report if this group is blacklisted. |
225 | | - */ |
| 210 | + // Do not report if this group is blacklisted. |
226 | 211 | $groupId = $g->getId(); |
227 | 212 | $blacklisted = $this->isBlacklisted( $groupId, $code ); |
228 | 213 | |
— | — | @@ -229,10 +214,16 @@ |
230 | 215 | continue; |
231 | 216 | } |
232 | 217 | |
| 218 | + $fuzzy = $translated = $total = 0; |
| 219 | + |
233 | 220 | $incache = $cache->get( $groupName, $code ); |
234 | 221 | if ( $incache !== false ) { |
235 | 222 | list( $fuzzy, $translated, $total ) = $incache; |
236 | | - } else { |
| 223 | + } |
| 224 | + |
| 225 | + // Re-calculate if cache is empty or insane |
| 226 | + if ( !$total ) { |
| 227 | + echo $g->getId() . "<br />\n"; |
237 | 228 | // Initialise messages. |
238 | 229 | $collection = $g->initCollection( $code ); |
239 | 230 | $collection->setInFile( $g->load( $code ) ); |
— | — | @@ -250,53 +241,35 @@ |
251 | 242 | $translated = count( $collection ); |
252 | 243 | |
253 | 244 | $cache->set( $groupName, $code, array( $fuzzy, $translated, $total ) ); |
| 245 | + $cache->commit(); |
| 246 | + } |
254 | 247 | |
| 248 | + if ( $total === 0 ) { |
| 249 | + wfWarn( __METHOD__ . ": Group $groupName has zero message ($code)" ); |
| 250 | + continue; |
255 | 251 | } |
256 | 252 | |
257 | 253 | // Skip if $suppressComplete and complete |
258 | | - if ( $suppressComplete && !$fuzzy && $translated == $total ) { |
| 254 | + if ( $suppressComplete && !$fuzzy && $translated === $total ) { |
259 | 255 | continue; |
260 | 256 | } |
261 | 257 | |
262 | | - // Division by 0 should not be possible, but does occur. Caching issue? |
263 | | - $translatedPercentage = $total ? $wgLang->formatNum( number_format( round( 100 * $translated / $total, 2 ), 2 ) ) : $errorString; |
264 | | - $translatedPercentage = $translatedPercentage == $errorString ? $translatedPercentage : wfMsg( 'percent', $translatedPercentage ); |
265 | | - |
266 | | - $fuzzyPercentage = $total ? $wgLang->formatNum( number_format( round( 100 * $fuzzy / $total, 2 ), 2 ) ) : $errorString; |
267 | | - $fuzzyPercentage = $fuzzyPercentage == $errorString ? $fuzzyPercentage : wfMsg( 'percent', $fuzzyPercentage ); |
268 | | - |
269 | | - $translateTitle = SpecialPage::getTitleFor( 'Translate' ); |
270 | | - $queryParameters = array( |
271 | | - 'group' => $groupId, |
272 | | - 'language' => $code |
273 | | - ); |
274 | | - |
275 | | - if ( $translated == $total ) { |
276 | | - $queryParameters['task'] = 'reviewall'; |
| 258 | + if ( $translated === $total ) { |
| 259 | + $extra = array( 'task' => 'reviewall' ); |
| 260 | + } else { |
| 261 | + $extra = array(); |
277 | 262 | } |
278 | 263 | |
279 | | - $groupLabel = $g->getLabel(); |
280 | | - |
281 | | - // Bold for meta groups. |
282 | | - if ( $g->isMeta() ) { |
283 | | - $groupLabel = Xml::element( 'b', null, $groupLabel ); |
284 | | - } |
285 | | - |
286 | | - $translateGroupLink = $wgUser->getSkin()->link( |
287 | | - $translateTitle, |
288 | | - $groupLabel, |
289 | | - array( |
290 | | - 'title' => strip_tags( $wgOut->parse( $g->getDescription(), false ) ) |
291 | | - ), |
292 | | - $queryParameters |
293 | | - ); |
294 | | - |
295 | 264 | $out .= Xml::openElement( 'tr' ); |
296 | | - $out .= '<td>' . $translateGroupLink . '</td>'; |
297 | | - $out .= Xml::element( 'td', null, $total ); |
298 | | - $out .= Xml::element( 'td', null, $total - $translated ); |
299 | | - $out .= $this->element( $translatedPercentage, $translatedPercentage == $errorString ? '' : $this->getBackgroundColour( $translated, $total ) ); |
300 | | - $out .= $this->element( $fuzzyPercentage, $translatedPercentage == $errorString ? '' : $this->getBackgroundColour( $fuzzy, $total, true ) ); |
| 265 | + $out .= '<td>' . $this->makeGroupLink( $g, $code, $extra ) . '</td>'; |
| 266 | + $out .= Xml::element( 'td', null, $wgLang->formatNum( $total ) ); |
| 267 | + $out .= Xml::element( 'td', null, $wgLang->formatNum( $total - $translated ) ); |
| 268 | + $out .= $this->element( $this->formatPercentage( $translated / $total ), |
| 269 | + $this->getBackgroundColour( $translated, $total ), |
| 270 | + sprintf( '%1.5f', $translated / $total ) ); |
| 271 | + $out .= $this->element( $this->formatPercentage( $fuzzy / $total ), |
| 272 | + $this->getBackgroundColour( $fuzzy, $total, true ), |
| 273 | + sprintf( '%1.5f', $fuzzy / $total ) ); |
301 | 274 | $out .= Xml::closeElement( 'tr' ); |
302 | 275 | } |
303 | 276 | |
— | — | @@ -310,7 +283,47 @@ |
311 | 284 | return $out; |
312 | 285 | } |
313 | 286 | |
314 | | - private function isBlacklisted( $groupId, $code ) { |
| 287 | + protected function formatPercentage( $num ) { |
| 288 | + global $wgLang; |
| 289 | + $fmt = $wgLang->formatNum( number_format( round( 100 * $num, 2 ), 2 ) ); |
| 290 | + return wfMsg( 'percent', $fmt ); |
| 291 | + } |
| 292 | + |
| 293 | + protected function getGroupLabel( $group ) { |
| 294 | + $groupLabel = htmlspecialchars( $group->getLabel() ); |
| 295 | + |
| 296 | + // Bold for meta groups. |
| 297 | + if ( $group->isMeta() ) { |
| 298 | + $groupLabel = Xml::tags( 'b', null, $groupLabel ); |
| 299 | + } |
| 300 | + |
| 301 | + return $groupLabel; |
| 302 | + } |
| 303 | + |
| 304 | + protected function makeGroupLink( $group, $code, $params ) { |
| 305 | + global $wgOut, $wgUser; |
| 306 | + |
| 307 | + $specialTranslate = SpecialPage::getTitleFor( 'Translate' ); |
| 308 | + $skin = $wgUser->getSkin(); |
| 309 | + |
| 310 | + $queryParameters = $params + array( |
| 311 | + 'group' => $group->getId(), |
| 312 | + 'language' => $code |
| 313 | + ); |
| 314 | + |
| 315 | + $attributes = array( |
| 316 | + 'title' => strip_tags( $wgOut->parse( $group->getDescription(), false ) ) |
| 317 | + ); |
| 318 | + |
| 319 | + $translateGroupLink = $skin->link( |
| 320 | + $specialTranslate, $this->getGroupLabel( $group ), $attributes, $queryParameters |
| 321 | + ); |
| 322 | + |
| 323 | + return $translateGroupLink; |
| 324 | + |
| 325 | + } |
| 326 | + |
| 327 | + protected function isBlacklisted( $groupId, $code ) { |
315 | 328 | global $wgTranslateBlacklist; |
316 | 329 | |
317 | 330 | $blacklisted = null; |