Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslatePerLanguageStats.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Statistics;
5
6use MediaWiki\MediaWikiServices;
8
17 protected $seenUsers;
18 protected $groups;
19
20 public function __construct( TranslationStatsGraphOptions $opts ) {
21 parent::__construct( $opts );
22 // This query is slow. Set a lower limit, but allow seeing one year at once.
23 $opts->boundValue( 'days', 1, 400 );
24 }
25
26 public function preQuery( &$tables, &$fields, &$conds, &$type, &$options, &$joins, $start, $end ) {
27 global $wgTranslateMessageNamespaces;
28
29 $db = wfGetDB( DB_REPLICA );
30
31 $tables = [ 'recentchanges' ];
32 $fields = [ 'rc_timestamp' ];
33 $joins = [];
34
35 $conds = [
36 'rc_namespace' => $wgTranslateMessageNamespaces,
37 'rc_bot' => 0,
38 'rc_type != ' . RC_LOG,
39 ];
40
41 $timeConds = self::makeTimeCondition( 'rc_timestamp', $start, $end );
42 $conds = array_merge( $conds, $timeConds );
43
44 $options = [ 'ORDER BY' => 'rc_timestamp' ];
45
46 $this->groups = array_map( 'MessageGroups::normalizeId', $this->opts->getGroups() );
47
48 $namespaces = self::namespacesFromGroups( $this->groups );
49 if ( count( $namespaces ) ) {
50 $conds['rc_namespace'] = $namespaces;
51 }
52
53 $languages = [];
54 foreach ( $this->opts->getLanguages() as $code ) {
55 $languages[] = 'rc_title ' . $db->buildLike( $db->anyString(), "/$code" );
56 }
57 if ( count( $languages ) ) {
58 $conds[] = $db->makeList( $languages, LIST_OR );
59 }
60
61 $fields[] = 'rc_title';
62
63 if ( $this->groups ) {
64 $fields[] = 'rc_namespace';
65 }
66
67 if ( $this->opts->getValue( 'count' ) === 'users' ) {
68 $fields[] = 'rc_actor';
69 }
70
71 $type .= '-perlang';
72 }
73
74 public function indexOf( $row ) {
75 if ( $this->opts->getValue( 'count' ) === 'users' ) {
76 $date = $this->formatTimestamp( $row->rc_timestamp );
77
78 if ( isset( $this->seenUsers[$date][$row->rc_actor] ) ) {
79 return false;
80 }
81
82 $this->seenUsers[$date][$row->rc_actor] = true;
83 }
84
85 // Do not consider language-less pages.
86 if ( strpos( $row->rc_title, '/' ) === false ) {
87 return false;
88 }
89
90 // No filters, just one key to track.
91 if ( !$this->groups && !$this->opts->getLanguages() ) {
92 return [ 'all' ];
93 }
94
95 // The key-building needs to be in sync with ::labels().
96 [ $key, $code ] = TranslateUtils::figureMessage( $row->rc_title );
97
98 $groups = [];
99 $codes = [];
100
101 if ( $this->groups ) {
102 /*
103 * Get list of keys that the message belongs to, and filter
104 * out those which are not requested.
105 */
106 $groups = TranslateUtils::messageKeyToGroups( $row->rc_namespace, $key );
107 $groups = array_intersect( $this->groups, $groups );
108 }
109
110 if ( $this->opts->getLanguages() ) {
111 $codes = [ $code ];
112 }
113
114 return $this->combineTwoArrays( $groups, $codes );
115 }
116
117 public function labels() {
118 return $this->combineTwoArrays( $this->groups, $this->opts->getLanguages() );
119 }
120
121 public function getTimestamp( $row ) {
122 return $row->rc_timestamp;
123 }
124
132 protected function makeLabel( $group, $code ) {
133 if ( $group || $code ) {
134 return "$group@$code";
135 } else {
136 return 'all';
137 }
138 }
139
147 protected function combineTwoArrays( $groups, $codes ) {
148 if ( !count( $groups ) ) {
149 $groups[] = false;
150 }
151
152 if ( !count( $codes ) ) {
153 $codes[] = false;
154 }
155
156 $items = [];
157 foreach ( $groups as $group ) {
158 foreach ( $codes as $code ) {
159 $items[] = $this->makeLabel( $group, $code );
160 }
161 }
162
163 return $items;
164 }
165
172 protected function formatTimestamp( $timestamp ) {
173 switch ( $this->opts->getValue( 'scale' ) ) {
174 case 'hours':
175 $cut = 4;
176 break;
177 case 'days':
178 $cut = 6;
179 break;
180 case 'months':
181 $cut = 8;
182 break;
183 case 'years':
184 $cut = 10;
185 break;
186 default:
187 return MediaWikiServices::getInstance()->getContentLanguage()
188 ->sprintfDate( $this->getDateFormat(), $timestamp );
189 }
190
191 return substr( $timestamp, 0, -$cut );
192 }
193}
Graph which provides statistics on active users and number of translations.
combineTwoArrays( $groups, $codes)
Cross-product of two lists with string results, where either list can be empty.
formatTimestamp( $timestamp)
Returns unique index for given item in the scale being used.
preQuery(&$tables, &$fields, &$conds, &$type, &$options, &$joins, $start, $end)
Query details that the graph must fill.
getTimestamp( $row)
Return the timestamp associated with this result row.
indexOf( $row)
Return the indexes which this result contributes to.
Provides some hand default implementations for TranslationStatsInterface.
Essentially random collection of helper functions, similar to GlobalFunctions.php.