Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryTranslatorStats
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 5
132
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
 execute
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
20
 addMissingMonths
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Api module for querying translation statistics for a translator.
4 *
5 * @copyright See AUTHORS.txt
6 * @license GPL-2.0-or-later
7 */
8
9namespace ContentTranslation\ActionApi;
10
11use ContentTranslation\DateManipulator;
12use ContentTranslation\Service\UserService;
13use ContentTranslation\Store\TranslationStore;
14use Exception;
15use MediaWiki\Api\ApiQuery;
16use MediaWiki\Api\ApiQueryBase;
17use MediaWiki\User\User;
18use Wikimedia\ParamValidator\ParamValidator;
19
20class ApiQueryTranslatorStats extends ApiQueryBase {
21    public function __construct(
22        ApiQuery $query,
23        string $moduleName,
24        private readonly UserService $userService,
25        private readonly TranslationStore $translationStore,
26    ) {
27        parent::__construct( $query, $moduleName );
28    }
29
30    public function execute() {
31        $params = $this->extractRequestParams();
32        $user = $this->getUser();
33
34        if ( isset( $params['translator'] ) ) {
35            $user = User::newFromName( $params['translator'] );
36        }
37
38        if ( !$user ) {
39            $this->dieWithError( 'apierror-cx-invalidtranslator', 'invalidtranslator' );
40        }
41
42        try {
43            $translatorId = $this->userService->getGlobalUserId( $user );
44        } catch ( Exception ) {
45            $this->dieWithError( 'apierror-cx-invalidtranslator', 'invalidtranslator' );
46        }
47
48        $publishedStats = $this->translationStore->getTrendByStatus(
49            null,
50            null,
51            'published',
52            'month',
53            $translatorId
54        );
55
56        $trend = $this->addMissingMonths( $publishedStats );
57
58        $result = [
59            'translator' => $user->getName(),
60            'translatorId' => $translatorId,
61            'publishTrend' => $trend,
62        ];
63        $this->getResult()->addValue( null, $this->getModuleName(), $result );
64    }
65
66    private function addMissingMonths( array $data ): array {
67        $dates = array_keys( $data );
68
69        $dm = new DateManipulator( 'month' );
70        // If there is no data, just use zero (represents now)
71        // to avoid passing empty array into min method
72        $min = $dm->getIntervalIdentifier( !$dates ? 0 : min( $dates ) );
73        $max = $dm->getIntervalIdentifier( 0 ); // Now
74
75        $steps = $dm->getSteps( $min, $max );
76
77        $out = [];
78        $count = 0;
79
80        foreach ( $steps as $datetime ) {
81            $id = $datetime->format( 'U' );
82            $date = $datetime->format( 'Y-m-d' );
83
84            if ( isset( $data[ $id ] ) ) {
85                $out[ $date ] = $data[ $id ];
86                $count = $data[ $id ][ 'count' ];
87            } else {
88                $out[ $date ] = [
89                    'count' => $count,
90                    'delta' => 0
91                ];
92            }
93        }
94
95        return $out;
96    }
97
98    /** @inheritDoc */
99    public function getAllowedParams() {
100        return [
101            'translator' => [
102                ParamValidator::PARAM_TYPE => 'string',
103            ]
104        ];
105    }
106
107    /** @inheritDoc */
108    protected function getExamplesMessages() {
109        return [
110            'action=query&list=cxtranslatorstats&translator=TranslatorName' =>
111                'apihelp-query+cxtranslatorstats-example-1',
112        ];
113    }
114}