2declare( strict_types = 1 );
4namespace MediaWiki\Extension\Translate\Statistics;
9use MediaWiki\MediaWikiServices;
10use Wikimedia\Rdbms\IDatabase;
20 protected array $seenUsers = [];
21 protected array $groups = [];
22 private Language $dateFormatter;
23 private array $formatCache = [];
26 parent::__construct( $opts );
28 $opts->boundValue(
'days', 1, 400 );
30 $this->dateFormatter = MediaWikiServices::getInstance()->getContentLanguage();
44 global $wgTranslateMessageNamespaces;
46 $tables = [
'recentchanges' ];
47 $fields = [
'rc_timestamp' ];
51 'rc_namespace' => $wgTranslateMessageNamespaces,
53 'rc_type != ' . RC_LOG,
56 $timeConds = self::makeTimeCondition( $database,
'rc_timestamp', $start, $end );
57 $conds = array_merge( $conds, $timeConds );
59 $options = [
'ORDER BY' =>
'rc_timestamp' ];
61 $this->groups = array_map( [ MessageGroups::class,
'normalizeId' ], $this->opts->getGroups() );
64 if ( count( $namespaces ) ) {
65 $conds[
'rc_namespace'] = $namespaces;
69 foreach ( $this->opts->getLanguages() as $code ) {
70 $languages[] =
'rc_title ' . $database->buildLike( $database->anyString(),
"/$code" );
72 if ( count( $languages ) ) {
73 $conds[] = $database->makeList( $languages, LIST_OR );
76 $fields[] =
'rc_title';
78 if ( $this->groups ) {
79 $fields[] =
'rc_namespace';
82 if ( $this->opts->getValue(
'count' ) ===
'users' ) {
83 $fields[] =
'rc_actor';
90 if ( $this->opts->getValue(
'count' ) ===
'users' ) {
93 if ( isset( $this->seenUsers[$date][$row->rc_actor] ) ) {
97 $this->seenUsers[$date][$row->rc_actor] =
true;
101 if ( !str_contains( $row->rc_title,
'/' ) ) {
106 if ( !$this->groups && !$this->opts->getLanguages() ) {
111 [ $key, $code ] = Utilities::figureMessage( $row->rc_title );
116 if ( $this->groups ) {
119 $groups = Utilities::messageKeyToGroups( (
int)$row->rc_namespace, $key );
120 $groups = array_intersect( $this->groups, $groups );
123 if ( $this->opts->getLanguages() ) {
131 return $this->
combineTwoArrays( $this->groups, $this->opts->getLanguages() );
135 return $row->rc_timestamp;
146 if ( $group || $code ) {
147 return "$group@$code";
161 if ( !count( $groups ) ) {
165 if ( !count( $codes ) ) {
170 foreach ( $groups as $group ) {
171 foreach ( $codes as $code ) {
172 $items[] = $this->
makeLabel( $group, $code );
186 switch ( $this->opts->getValue(
'scale' ) ) {
201 $index = substr( $timestamp, 0, -6 );
204 $this->formatCache[$index] ??= $this->dateFormatter->sprintfDate( $this->
getDateFormat(), $timestamp );
205 return $this->formatCache[$index];
208 return substr( $timestamp, 0, -$cut );