Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
Translator
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 9
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getGlobalUserId
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getUser
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addTranslation
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 getLanguages
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
12
 getTranslationsCount
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 getStats
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getTranslatorsCount
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
6
 getTotalTranslatorsCount
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace ContentTranslation;
4
5use ContentTranslation\Service\UserService;
6use MediaWiki\MediaWikiServices;
7use MediaWiki\User\User;
8
9class Translator {
10
11    private User $user;
12
13    public function __construct( User $user ) {
14        $this->user = $user;
15    }
16
17    private function getGlobalUserId(): int {
18        /** @var UserService $userService */
19        $userService = MediaWikiServices::getInstance()->getService( 'ContentTranslation.UserService' );
20
21        return $userService->getGlobalUserId( $this->user );
22    }
23
24    public function getUser(): User {
25        return $this->user;
26    }
27
28    /**
29     * @param int $translationId
30     */
31    public function addTranslation( $translationId ) {
32        /** @var LoadBalancer $lb */
33        $lb = MediaWikiServices::getInstance()->getService( 'ContentTranslation.LoadBalancer' );
34        $dbw = $lb->getConnection( DB_PRIMARY );
35        $dbw->newReplaceQueryBuilder()
36            ->replaceInto( 'cx_translators' )
37            ->uniqueIndexFields( [ 'translator_user_id', 'translator_translation_id' ] )
38            ->row( [
39                'translator_user_id' => $this->getGlobalUserId(),
40                'translator_translation_id' => $translationId,
41            ] )
42            ->caller( __METHOD__ )
43            ->execute();
44    }
45
46    /**
47     * @param string|null $type
48     * @return string[]
49     */
50    public function getLanguages( $type ) {
51        // Note: there is no index on translation_last_updated_timestamp
52        /** @var LoadBalancer $lb */
53        $lb = MediaWikiServices::getInstance()->getService( 'ContentTranslation.LoadBalancer' );
54        $dbr = $lb->getConnection( DB_REPLICA );
55
56        $baseQuery = $dbr->newSelectQueryBuilder()
57            // ->select() below
58            ->from( 'cx_translations' )
59            ->join( 'cx_translators', null, 'translator_translation_id = translation_id' )
60            ->where( [ 'translator_user_id' => $this->getGlobalUserId() ] );
61        if ( $type !== null ) {
62            $baseQuery->andWhere( [ 'translation_status' => $type ] );
63        }
64        $unionQueryBuilder = $dbr->newUnionQueryBuilder();
65
66        $sourceQuery = clone $baseQuery;
67        $sourceQuery->select( [ 'code' => 'translation_source_language' ] );
68        $unionQueryBuilder->add( $sourceQuery );
69        $targetQuery = clone $baseQuery;
70        $targetQuery->select( [ 'code' => 'translation_target_language' ] );
71        $unionQueryBuilder->add( $targetQuery );
72
73        $res = $unionQueryBuilder->caller( __METHOD__ )->fetchResultSet();
74
75        $result = [];
76        foreach ( $res as $row ) {
77            $result[] = $row->code;
78        }
79
80        return $result;
81    }
82
83    /**
84     * Get the number of published translation by current translator.
85     * @return int
86     */
87    public function getTranslationsCount() {
88        /** @var LoadBalancer $lb */
89        $lb = MediaWikiServices::getInstance()->getService( 'ContentTranslation.LoadBalancer' );
90        $dbr = $lb->getConnection( DB_REPLICA );
91
92        $count = $dbr->newSelectQueryBuilder()
93            ->select( 'COUNT(*)' )
94            ->from( 'cx_translators' )
95            ->join( 'cx_translations', null, 'translator_translation_id = translation_id' )
96            ->where( [
97                'translator_user_id' => $this->getGlobalUserId(),
98                // And it is published
99                Translation::getPublishedCondition( $dbr )
100            ] )
101            ->caller( __METHOD__ )
102            ->fetchField();
103
104        return intval( $count );
105    }
106
107    /**
108     * Get the stats for all translator counts.
109     * @return array
110     */
111    public static function getStats() {
112        return [
113            'from' => self::getTranslatorsCount( 'source' ),
114            'to' => self::getTranslatorsCount( 'target' ),
115            'total' => self::getTotalTranslatorsCount(),
116        ];
117    }
118
119    /**
120     * Get the stats for translator count to or from a language.
121     * @param string $direction source or target
122     * @return int[] Number of translators indexed by language code
123     */
124    public static function getTranslatorsCount( $direction ) {
125        $directionField = [
126            'source' => 'translation_source_language',
127            'target' => 'translation_target_language',
128        ];
129
130        /** @var LoadBalancer $lb */
131        $lb = MediaWikiServices::getInstance()->getService( 'ContentTranslation.LoadBalancer' );
132        $dbr = $lb->getConnection( DB_REPLICA );
133
134        $rows = $dbr->newSelectQueryBuilder()
135            ->select( [
136                'language' => $directionField[$direction],
137                'translators' => 'COUNT(DISTINCT translation_started_by)',
138            ] )
139            ->from( 'cx_translations' )
140            ->where( Translation::getPublishedCondition( $dbr ) )
141            ->groupBy( $directionField[$direction] )
142            ->caller( __METHOD__ )
143            ->fetchResultSet();
144
145        $result = [];
146
147        foreach ( $rows as $row ) {
148            $result[$row->language] = (int)$row->translators;
149        }
150
151        return $result;
152    }
153
154    /**
155     * Get the total count of users who published a translation.
156     * @return int Number of translators
157     */
158    public static function getTotalTranslatorsCount() {
159        /** @var LoadBalancer $lb */
160        $lb = MediaWikiServices::getInstance()->getService( 'ContentTranslation.LoadBalancer' );
161        $dbr = $lb->getConnection( DB_REPLICA );
162
163        return $dbr->newSelectQueryBuilder()
164            ->select( 'COUNT(DISTINCT translation_started_by)' )
165            ->from( 'cx_translations' )
166            ->where( Translation::getPublishedCondition( $dbr ) )
167            ->caller( __METHOD__ )
168            ->fetchField();
169    }
170}