Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiContentTranslationSplit
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 7
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 validateRequest
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
30
 execute
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
6
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 needsToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isWriteMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 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\LoadBalancer;
7use ContentTranslation\Service\TranslationSplitter;
8use ContentTranslation\Store\SectionTranslationStore;
9use ContentTranslation\Store\TranslationStore;
10use MediaWiki\Api\ApiBase;
11use MediaWiki\Api\ApiMain;
12use MediaWiki\Api\ApiUsageException;
13use Wikimedia\ParamValidator\ParamValidator;
14
15/**
16 * Action API module that is used to split a content translation
17 * into section translations.
18 *
19 * @author Nik Gkountas
20 * @license GPL-2.0-or-later
21 * @since 2024.01
22 */
23class ApiContentTranslationSplit extends ApiBase {
24    private TranslationSplitter $translationSplitter;
25    private TranslationStore $translationStore;
26    private SectionTranslationStore $sectionTranslationStore;
27    private LoadBalancer $loadBalancer;
28
29    public function __construct(
30        ApiMain $mainModule,
31        string $action,
32        LoadBalancer $loadBalancer,
33        TranslationSplitter $translationSplitter,
34        TranslationStore $translationStore,
35        SectionTranslationStore $sectionTranslationStore
36    ) {
37        parent::__construct( $mainModule, $action );
38        $this->loadBalancer = $loadBalancer;
39        $this->translationSplitter = $translationSplitter;
40        $this->translationStore = $translationStore;
41        $this->sectionTranslationStore = $sectionTranslationStore;
42    }
43
44    /**
45     * @return void
46     * @throws ApiUsageException
47     */
48    private function validateRequest(): void {
49        if ( $this->loadBalancer->getConnection( DB_PRIMARY )->isReadOnly() ) {
50            $this->dieReadOnly();
51        }
52
53        $user = $this->getUser();
54
55        if ( !$user->isNamed() ) {
56            $this->dieWithError( 'apierror-cxsplit-anon-user' );
57        }
58
59        $block = $user->getBlock();
60        if ( $block && $block->isSitewide() ) {
61            $this->dieBlocked( $block );
62        }
63    }
64
65    /**
66     * @throws ApiUsageException
67     */
68    public function execute() {
69        $this->validateRequest();
70
71        $params = $this->extractRequestParams();
72        $translationId = $params['translationid'];
73        $user = $this->getUser();
74
75        $translation = $this->translationStore->findByUserAndId( $user, $translationId );
76
77        if ( !$translation ) {
78            $this->dieWithError( 'apierror-cxsplit-no-translation-found' );
79        }
80        $newSectionTranslations = $this->translationSplitter->splitIntoSectionTranslations(
81            $translation
82        );
83        $this->sectionTranslationStore->insertMultipleTranslations( $newSectionTranslations );
84
85        $result = [ 'result' => 'success' ];
86        $this->getResult()->addValue( null, $this->getModuleName(), $result );
87    }
88
89    public function getAllowedParams() {
90        return [
91            'translationid' => [
92                ParamValidator::PARAM_TYPE => 'integer',
93                ParamValidator::PARAM_REQUIRED => true,
94            ]
95        ];
96    }
97
98    public function needsToken() {
99        return 'csrf';
100    }
101
102    public function isWriteMode() {
103        return true;
104    }
105
106    public function isInternal() {
107        return true;
108    }
109}