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