Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MarkForTranslationActionApi.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\PageTranslation;
5
6use ApiBase;
7use ApiMain;
8use IDBAccessObject;
11use MediaWiki\Status\Status;
12use Wikimedia\ParamValidator\ParamValidator;
13
20class MarkForTranslationActionApi extends ApiBase {
21 private TranslatablePageMarker $translatablePageMarker;
22 private MessageGroupMetadata $messageGroupMetadata;
23
24 public function __construct(
25 ApiMain $mainModule,
26 $moduleName,
27 TranslatablePageMarker $translatablePageMarker,
28 MessageGroupMetadata $messageGroupMetadata
29 ) {
30 parent::__construct( $mainModule, $moduleName );
31 $this->translatablePageMarker = $translatablePageMarker;
32 $this->messageGroupMetadata = $messageGroupMetadata;
33 }
34
35 public function execute() {
36 $this->checkUserRightsAny( 'pagetranslation' );
37
38 $params = $this->extractRequestParams();
39 $title = $this->getTitleFromTitleOrPageId( $params );
40 $revision = $params['revid'] ?? null;
41
42 $translateTitle = $this->getTriState( $params, 'translatetitle' );
43
44 try {
45 $operation = $this->translatablePageMarker->getMarkOperation(
46 $title->toPageRecord( IDBAccessObject::READ_LATEST ),
47 $revision,
48 $translateTitle ?? true
49 );
50 } catch ( TranslatablePageMarkException $e ) {
51 $this->addError( $e->getMessageObject() );
52 return;
53 }
54
55 $unitNameValidationResult = $operation->getUnitValidationStatus();
56 if ( !$unitNameValidationResult->isOK() ) {
57 $this->addMessagesFromStatus( $unitNameValidationResult );
58 return;
59 }
60
61 if ( $translateTitle === null ) {
62 // Check whether page title was previously marked for translation.
63 // If the page is marked for translation the first time, default to
64 // allowing title translation, unless the page is a template. T305240
65 $translateTitle = (
66 $operation->isFirstMark() &&
67 !$title->inNamespace( NS_TEMPLATE )
68 ) || $operation->getPage()->hasPageDisplayTitle();
69 }
70
71 // By default, units are marked nofuzzy if only their tvars have changed
72 $noFuzzyUnits = [];
73 foreach ( $operation->getUnits() as $s ) {
74 if ( $s->type === 'changed' && $s->onlyTvarsChanged() ) {
75 $noFuzzyUnits[] = $s->id;
76 }
77 }
78
79 // Add and subtract nofuzzy flags as specified by the user
80 $noFuzzyUnits = array_unique( array_merge( $noFuzzyUnits, $params['nofuzzyunits'] ?? [] ) );
81 $noFuzzyUnits = array_diff( $noFuzzyUnits, $params['fuzzyunits'] ?? [] );
82
83 $groupId = $operation->getPage()->getMessageGroupId();
84 if ( isset( $params['prioritylanguages'] ) ) {
85 // Set priority languages
86 $priorityLanguages = $params['prioritylanguages'];
87 $priorityLanguageStatus = $this->validatePriorityLanguages( $priorityLanguages );
88 if ( !$priorityLanguageStatus->isOK() ) {
89 $this->addMessagesFromStatus( $priorityLanguageStatus );
90 return;
91 }
92 $forcePriority = $params['forcepriority'] ?? false;
93 $priorityReason = $params['priorityreason'] ?? '';
94 } else {
95 // markForTranslation() sets priority languages unconditionally.
96 // If no changes were requested, we need to load the current values
97 // just to avoid changing it.
98 $blob = (string)$this->messageGroupMetadata->get( $groupId, 'prioritylangs' );
99 $priorityLanguages = $blob !== '' ? explode( ',', $blob ) : [];
100 $forcePriority = $this->messageGroupMetadata->get( $groupId, 'priorityforce' ) === 'on';
101 // If no priority reason is set, set it to an empty string
102 $priorityReason = $this->messageGroupMetadata->get( $groupId, 'priorityreason' );
103 $priorityReason = $priorityReason !== false ? $priorityReason : '';
104 }
105
106 $transclusion = $this->getTriState( $params, 'transclusion' );
107 if ( $transclusion === null ) {
108 $transclusion = $operation->getPage()->supportsTransclusion() ?? $operation->isFirstMark();
109 }
110
111 $translatablePageSettings = new TranslatablePageSettings(
112 $priorityLanguages,
113 $forcePriority,
114 $priorityReason,
115 $noFuzzyUnits,
116 $translateTitle,
117 $params[ 'forcelatestsyntaxversion'] ?? false,
118 $transclusion
119 );
120
121 try {
122 $unitCount = $this->translatablePageMarker->markForTranslation(
123 $operation,
124 $translatablePageSettings,
125 $this->getUser()
126 );
127 } catch ( TranslatablePageMarkException $e ) {
128 $this->addError( $e->getMessageObject() );
129 return;
130 }
131 $res = [
132 'result' => 'Success',
133 'firstmark' => $operation->isFirstMark(),
134 'unitcount' => $unitCount,
135 ];
136 $this->getResult()->addValue( null, $this->getModuleName(), $res );
137 }
138
140 private function getTriState( array $params, string $name ): ?bool {
141 return isset( $params[$name] ) ? $params[$name] === 'yes' : null;
142 }
143
144 private function validatePriorityLanguages( array $priorityLanguageCodes ): Status {
145 $knownLanguageCodes = array_keys( Utilities::getLanguageNames( 'en' ) );
146 $invalidLanguageCodes = array_diff( $priorityLanguageCodes, $knownLanguageCodes );
147 $context = $this->getContext();
148
149 if ( $invalidLanguageCodes ) {
150 return Status::newFatal(
151 $context->msg( 'apierror-markfortranslation-invalid-prioritylangs' )
152 ->params(
153 count( $invalidLanguageCodes ),
154 $context->getLanguage()->commaList( $invalidLanguageCodes )
155 )
156 );
157 }
158
159 return Status::newGood();
160 }
161
162 public function isWriteMode() {
163 return true;
164 }
165
166 public function needsToken() {
167 return 'csrf';
168 }
169
170 protected function getAllowedParams() {
171 return [
172 'title' => [
173 ParamValidator::PARAM_TYPE => 'string',
174 ],
175 'pageid' => [
176 ParamValidator::PARAM_TYPE => 'integer',
177 ],
178 'revid' => [
179 ParamValidator::PARAM_TYPE => 'integer',
180 ],
181 'translatetitle' => [
182 ParamValidator::PARAM_TYPE => [ 'yes', 'no' ],
183 ],
184 'prioritylanguages' => [
185 ParamValidator::PARAM_TYPE => 'string',
186 ParamValidator::PARAM_ISMULTI => true,
187 ParamValidator::PARAM_ISMULTI_LIMIT1 => 1000,
188 ParamValidator::PARAM_ISMULTI_LIMIT2 => 1000,
189 ],
190 'forcepriority' => [
191 ParamValidator::PARAM_TYPE => 'boolean',
192 ],
193 'priorityreason' => [
194 ParamValidator::PARAM_TYPE => 'string',
195 ],
196 'nofuzzyunits' => [
197 ParamValidator::PARAM_TYPE => 'string',
198 ParamValidator::PARAM_ISMULTI => true,
199 ParamValidator::PARAM_ISMULTI_LIMIT1 => 1000,
200 ParamValidator::PARAM_ISMULTI_LIMIT2 => 1000,
201 ],
202 'fuzzyunits' => [
203 ParamValidator::PARAM_TYPE => 'string',
204 ParamValidator::PARAM_ISMULTI => true,
205 ParamValidator::PARAM_ISMULTI_LIMIT1 => 1000,
206 ParamValidator::PARAM_ISMULTI_LIMIT2 => 1000,
207 ],
208 'forcelatestsyntaxversion' => [
209 ParamValidator::PARAM_TYPE => 'boolean',
210 ],
211 'transclusion' => [
212 ParamValidator::PARAM_TYPE => [ 'yes', 'no' ],
213 ],
214 ];
215 }
216
217}
Offers functionality for reading and updating Translate group related metadata.
Exception thrown when TranslatablePageMarker is unable to unmark a page for translation.
Service to mark/unmark pages from translation and perform related validations.
Value object containing user configurable settings when marking a page for translation.
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:31