Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiContentTranslationUnreviewedCheck
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 4
56
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
 validateRequest
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 execute
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
12
 isInternal
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types=1 );
3
4namespace ContentTranslation\ActionApi;
5
6use ContentTranslation\DTO\PublishedTranslationDTO;
7use ContentTranslation\Service\UserService;
8use ContentTranslation\Store\TranslationCorporaStore;
9use ContentTranslation\Store\TranslationStore;
10use MediaWiki\Api\ApiBase;
11use MediaWiki\Api\ApiMain;
12
13/**
14 * Action API module that is used to check if any "unreviewed" translation
15 * has just been published by the current user. A translation is considered
16 * "unreviewed" if the user has spent fewer minutes to complete it, than the
17 * number of the translated paragraphs, with a maximum limit to 10 minutes.
18 * That is, if the user has spent 10 or more minutes to complete a translation,
19 * the translation is considered "reviewed", even if it contains hundreds
20 * of paragraphs.
21 *
22 * @author Nik Gkountas
23 * @license GPL-2.0-or-later
24 * @since 2024.03
25 */
26class ApiContentTranslationUnreviewedCheck extends ApiBase {
27    public function __construct(
28        ApiMain $mainModule,
29        string $action,
30        private readonly TranslationStore $translationStore,
31        private readonly TranslationCorporaStore $corporaStore,
32        private readonly UserService $userService
33    ) {
34        parent::__construct( $mainModule, $action );
35    }
36
37    private function validateRequest(): void {
38        $user = $this->getUser();
39
40        if ( !$user->isNamed() ) {
41            $this->dieWithError( 'apierror-cxcheckunreviewed-anon-user' );
42        }
43    }
44
45    public function execute() {
46        $this->validateRequest();
47
48        // This method returns the last published translation, in the last 10 minutes.
49        // Checking the most recent translation is enough here. Previous translations
50        // have already been checked before the most recent translation was published.
51        $recentTranslation = $this->translationStore->findRecentTranslationByUser(
52            $this->userService->getGlobalUserId( $this->getUser() )
53        );
54        $result = [ 'result' => 'success' ];
55
56        if ( !$recentTranslation ) {
57            $this->getResult()->addValue( null, $this->getModuleName(), $result );
58            return;
59        }
60
61        $translatedSubSectionsCount = $this->corporaStore->countTranslatedSubSectionsByTranslationId(
62            $recentTranslation->getTranslationId()
63        );
64
65        $startUnixTimestamp = (int)wfTimestamp( TS_UNIX, $recentTranslation->translation['startTimestamp'] );
66        $minutesPassed = ( time() - $startUnixTimestamp ) / 60;
67        if ( $translatedSubSectionsCount > $minutesPassed ) {
68            $result['result'] = 'failure';
69            $translationDTO = new PublishedTranslationDTO(
70                $recentTranslation->getTranslationId(),
71                $recentTranslation->translation['sourceTitle'],
72                $recentTranslation->translation['sourceLanguage'],
73                $recentTranslation->translation['targetLanguage'],
74                $recentTranslation->translation['startTimestamp'],
75                $recentTranslation->translation['lastUpdateTimestamp'],
76                $recentTranslation->translation['sourceRevisionId'],
77                $recentTranslation->translation['targetTitle'],
78                $recentTranslation->translation['targetURL'],
79                []
80            );
81            $result['translation'] = $translationDTO->toArray();
82        }
83
84        $this->getResult()->addValue( null, $this->getModuleName(), $result );
85    }
86
87    /** @inheritDoc */
88    public function isInternal() {
89        return true;
90    }
91}