Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SearchTranslationsActionApi
0.00% covered (danger)
0.00%
0 / 92
0.00% covered (danger)
0.00%
0 / 6
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
20
 getSearchableTtmServers
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 getAllowedFilters
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
6
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TtmServer;
5
6use ApiBase;
7use ApiMain;
8use Config;
9use CrossLanguageTranslationSearchQuery;
10use MediaWiki\Config\ServiceOptions;
11use Wikimedia\ParamValidator\ParamValidator;
12use Wikimedia\ParamValidator\TypeDef\IntegerDef;
13
14/**
15 * API module for search translations
16 * @license GPL-2.0-or-later
17 */
18class SearchTranslationsActionApi extends ApiBase {
19    /** @var TtmServerFactory */
20    private $ttmServerFactory;
21    /** @var ServiceOptions */
22    private $options;
23
24    private const CONSTRUCTOR_OPTIONS = [
25        'LanguageCode',
26        'TranslateTranslationDefaultService',
27        'TranslateTranslationServices',
28    ];
29
30    public function __construct(
31        ApiMain $main,
32        string $moduleName,
33        Config $config,
34        TtmServerFactory $ttmServerFactory
35    ) {
36        parent::__construct( $main, $moduleName );
37        $this->options = new ServiceOptions( self::CONSTRUCTOR_OPTIONS, $config );
38        $this->ttmServerFactory = $ttmServerFactory;
39    }
40
41    public function execute(): void {
42        if ( !$this->getSearchableTtmServers() ) {
43            $this->dieWithError( 'apierror-translate-notranslationservices' );
44        }
45
46        $params = $this->extractRequestParams();
47
48        $server = $this->ttmServerFactory->create( $params[ 'service' ] );
49        if ( !$server instanceof SearchableTtmServer ) {
50            $this->dieWithError( 'apierror-translate-notranslationservices' );
51        }
52
53        $result = $this->getResult();
54
55        if ( $params['filter'] !== '' ) {
56            $translationSearch = new CrossLanguageTranslationSearchQuery( $params, $server );
57            $documents = $translationSearch->getDocuments();
58            $total = $translationSearch->getTotalHits();
59        } else {
60            $searchResults = $server->search(
61                $params['query'],
62                $params,
63                [ '', '' ]
64            );
65            $documents = $server->getDocuments( $searchResults );
66            $total = $server->getTotalHits( $searchResults );
67        }
68        $result->addValue( [ 'search', 'metadata' ], 'total', $total );
69        $result->addValue( 'search', 'translations', $documents );
70    }
71
72    /** @return string[] */
73    private function getSearchableTtmServers(): array {
74        $ttmServiceIds = $this->ttmServerFactory->getNames();
75
76        $good = [];
77        foreach ( $ttmServiceIds as $serviceId ) {
78            $ttmServer = $this->ttmServerFactory->create( $serviceId );
79            if ( $ttmServer instanceof SearchableTtmServer ) {
80                $good[] = $serviceId;
81            }
82        }
83
84        return $good;
85    }
86
87    protected function getAllowedFilters(): array {
88        return [
89            '',
90            'translated',
91            'fuzzy',
92            'untranslated'
93        ];
94    }
95
96    protected function getAllowedParams(): array {
97        $available = $this->getSearchableTtmServers();
98
99        $filters = $this->getAllowedFilters();
100
101        $ret = [
102            'service' => [
103                ParamValidator::PARAM_TYPE => $available,
104            ],
105            'query' => [
106                ParamValidator::PARAM_TYPE => 'string',
107                ParamValidator::PARAM_REQUIRED => true,
108            ],
109            'sourcelanguage' => [
110                ParamValidator::PARAM_TYPE => 'string',
111                ParamValidator::PARAM_DEFAULT => $this->options->get( 'LanguageCode' ),
112            ],
113            'language' => [
114                ParamValidator::PARAM_TYPE => 'string',
115                ParamValidator::PARAM_DEFAULT => '',
116            ],
117            'group' => [
118                ParamValidator::PARAM_TYPE => 'string',
119                ParamValidator::PARAM_DEFAULT => '',
120            ],
121            'filter' => [
122                ParamValidator::PARAM_TYPE => $filters,
123                ParamValidator::PARAM_DEFAULT => '',
124            ],
125            'match' => [
126                ParamValidator::PARAM_TYPE => 'string',
127                ParamValidator::PARAM_DEFAULT => '',
128            ],
129            'case' => [
130                ParamValidator::PARAM_TYPE => 'string',
131                ParamValidator::PARAM_DEFAULT => '0',
132            ],
133            'offset' => [
134                ParamValidator::PARAM_TYPE => 'integer',
135                ParamValidator::PARAM_DEFAULT => 0,
136            ],
137            'limit' => [
138                ParamValidator::PARAM_DEFAULT => 25,
139                ParamValidator::PARAM_TYPE => 'limit',
140                IntegerDef::PARAM_MIN => 1,
141                IntegerDef::PARAM_MAX => ApiBase::LIMIT_SML1,
142                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_SML2
143            ],
144        ];
145
146        if ( $available ) {
147            // Don't add this if no services are available, it makes
148            // ApiStructureTest unhappy
149            $ret['service'][ParamValidator::PARAM_DEFAULT] =
150                $this->options->get( 'TranslateTranslationDefaultService' );
151        }
152
153        return $ret;
154    }
155
156    protected function getExamplesMessages(): array {
157        return [
158            'action=searchtranslations&language=fr&query=aide'
159                => 'apihelp-searchtranslations-example-1',
160            'action=searchtranslations&language=fr&query=edit&filter=untranslated'
161                => 'apihelp-searchtranslations-example-2',
162        ];
163    }
164}