Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslateEditAddons.php
Go to the documentation of this file.
1<?php
15use MediaWiki\Logger\LoggerFactory;
16use MediaWiki\Revision\RevisionRecord;
17use MediaWiki\Storage\EditResult;
18use MediaWiki\User\UserIdentity;
19
36 public static function disallowLangTranslations( Title $title, User $user,
37 $action, &$result
38 ) {
39 if ( $action !== 'edit' ) {
40 return true;
41 }
42
43 $handle = new MessageHandle( $title );
44 if ( !$handle->isValid() ) {
45 return true;
46 }
47
48 if ( $user->isAllowed( 'translate-manage' ) ) {
49 return true;
50 }
51
52 $group = $handle->getGroup();
53 $languages = $group->getTranslatableLanguages();
54 $langCode = $handle->getCode();
55 if ( $languages !== null && $langCode && !isset( $languages[$langCode] ) ) {
56 $result = [ 'translate-language-disabled' ];
57 return false;
58 }
59
60 $groupId = $group->getId();
61 $checks = [
62 $groupId,
63 strtok( $groupId, '-' ),
64 '*'
65 ];
66
67 $disabledLanguages = Services::getInstance()->getConfigHelper()->getDisabledTargetLanguages();
68 foreach ( $checks as $check ) {
69 if ( isset( $disabledLanguages[$check][$langCode] ) ) {
70 $reason = $disabledLanguages[$check][$langCode];
71 $result = [ 'translate-page-disabled', $reason ];
72 return false;
73 }
74 }
75
76 return true;
77 }
78
91 public static function onSaveComplete(
92 WikiPage $wikiPage,
93 UserIdentity $userIdentity,
94 string $summary,
95 int $flags,
96 RevisionRecord $revisionRecord,
97 EditResult $editResult
98 ) {
99 global $wgEnablePageTranslation;
100
101 $content = $wikiPage->getContent();
102
103 if ( !$content instanceof TextContent ) {
104 // Screw it, not interested
105 return true;
106 }
107
108 $text = $content->getText();
109 $title = $wikiPage->getTitle();
110 $handle = new MessageHandle( $title );
111
112 if ( !$handle->isValid() ) {
113 return true;
114 }
115
116 // Update it.
117 $revId = $revisionRecord->getId();
118
119 $fuzzy = self::checkNeedsFuzzy( $handle, $text );
120 self::updateFuzzyTag( $title, $revId, $fuzzy );
121
122 $group = $handle->getGroup();
123 // Update translation stats - source language should always be up to date
124 if ( $handle->getCode() !== $group->getSourceLanguage() ) {
125 // This will update in-process cache immediately, but the value is saved
126 // to the database in a deferred update. See MessageGroupStats::queueUpdates.
127 // In case an error happens before that, the stats may be stale, but that
128 // would be fixed by the next update or purge.
129 MessageGroupStats::clear( $handle );
130 }
131
132 // This job asks for stats, however the updated stats are written in a deferred update.
133 // To make it less likely that the job would be executed before the updated stats are
134 // written, create the job inside a deferred update too.
135 DeferredUpdates::addCallableUpdate(
136 static function () use ( $handle ) {
138 }
139 );
140
141 $user = User::newFromIdentity( $userIdentity );
142
143 if ( $fuzzy === false ) {
144 Hooks::run( 'Translate:newTranslation', [ $handle, $revId, $text, $user ] );
145 }
146
147 TTMServer::onChange( $handle );
148
149 if ( $wgEnablePageTranslation && $handle->isPageTranslation() ) {
150 // Updates for translatable pages only
151 $minor = $flags & EDIT_MINOR;
152 PageTranslationHooks::onSectionSave( $wikiPage, $user, $content,
153 $summary, $minor, $flags, $handle );
154 }
155
156 return true;
157 }
158
165 protected static function checkNeedsFuzzy( MessageHandle $handle, $text ) {
166 // Docs are exempt for checks
167 if ( $handle->isDoc() ) {
168 return false;
169 }
170
171 // Check for explicit tag.
172 if ( MessageHandle::hasFuzzyString( $text ) ) {
173 return true;
174 }
175
176 // Not all groups have validators
177 $group = $handle->getGroup();
178 $validator = $group->getValidator();
179
180 // no validator set
181 if ( !$validator ) {
182 return false;
183 }
184
185 $code = $handle->getCode();
186 $key = $handle->getKey();
187 $en = $group->getMessage( $key, $group->getSourceLanguage() );
188 $message = new FatMessage( $key, $en );
189 // Take the contents from edit field as a translation.
190 $message->setTranslation( $text );
191 if ( $message->definition() === null ) {
192 // This should NOT happen, but add a check since it seems to be happening
193 // See: https://phabricator.wikimedia.org/T255669
194 LoggerFactory::getInstance( 'Translate' )->warning(
195 'Message definition is empty! Title: {title}, group: {group}, key: {key}',
196 [
197 'title' => $handle->getTitle()->getPrefixedText(),
198 'group' => $group->getId(),
199 'key' => $key
200 ]
201 );
202 return false;
203 }
204
205 $validationResult = $validator->quickValidate( $message, $code );
206 return $validationResult->hasIssues();
207 }
208
215 protected static function updateFuzzyTag( Title $title, $revision, $fuzzy ) {
216 $dbw = wfGetDB( DB_PRIMARY );
217
218 $conds = [
219 'rt_page' => $title->getArticleID(),
220 'rt_type' => RevTagStore::FUZZY_TAG,
221 'rt_revision' => $revision
222 ];
223
224 // Replace the existing fuzzy tag, if any
225 if ( $fuzzy !== false ) {
226 $index = array_keys( $conds );
227 $dbw->replace( 'revtag', [ $index ], $conds, __METHOD__ );
228 } else {
229 $dbw->delete( 'revtag', $conds, __METHOD__ );
230 }
231
232 return (bool)$dbw->affectedRows();
233 }
234
246 public static function updateTransverTag( MessageHandle $handle, $revision,
247 $text, User $user
248 ) {
249 if ( $user->isAllowed( 'bot' ) ) {
250 return false;
251 }
252
253 $group = $handle->getGroup();
254
255 $title = $handle->getTitle();
256 $name = $handle->getKey() . '/' . $group->getSourceLanguage();
257 $definitionTitle = Title::makeTitleSafe( $title->getNamespace(), $name );
258 if ( !$definitionTitle || !$definitionTitle->exists() ) {
259 return true;
260 }
261
262 $definitionRevision = $definitionTitle->getLatestRevID();
263
264 $dbw = wfGetDB( DB_PRIMARY );
265
266 $conds = [
267 'rt_page' => $title->getArticleID(),
268 'rt_type' => RevTagStore::TRANSVER_PROP,
269 'rt_revision' => $revision,
270 'rt_value' => $definitionRevision,
271 ];
272 $index = [ 'rt_type', 'rt_page', 'rt_revision' ];
273 $dbw->replace( 'revtag', [ $index ], $conds, __METHOD__ );
274
275 return true;
276 }
277
284 public static function disablePreSaveTransform( WikiPage $wikiPage, ParserOptions $popts ) {
285 global $wgTranslateUsePreSaveTransform;
286
287 if ( !$wgTranslateUsePreSaveTransform ) {
288 $handle = new MessageHandle( $wikiPage->getTitle() );
289 if ( $handle->isMessageNamespace() && !$handle->isDoc() ) {
290 $popts->setPreSaveTransform( false );
291 }
292 }
293
294 return true;
295 }
296}
Message object where you can directly set the translation.
Definition Message.php:189
Class to manage revision tags for translatable bundles.
static onSectionSave(WikiPage $wikiPage, User $user, TextContent $content, $summary, $minor, $flags, MessageHandle $handle)
This is triggered after an edit to translation unit page.
Definition Hooks.php:379
Minimal service container.
Definition Services.php:38
static onChange(MessageHandle $handle)
Hook: TranslateEventTranslationReview and also on translation changes.
Class for pointing to messages, like Title class is for titles.
isDoc()
Determine whether the current handle is for message documentation.
getGroup()
Get the primary MessageGroup this message belongs to.
getTitle()
Get the original title.
getCode()
Returns the language code.
getKey()
Returns the identified or guessed message key.
Various editing enhancements to the edit page interface.
static updateTransverTag(MessageHandle $handle, $revision, $text, User $user)
Adds tag which identifies the revision of source message at that time.
static updateFuzzyTag(Title $title, $revision, $fuzzy)
static disallowLangTranslations(Title $title, User $user, $action, &$result)
Prevent translations to non-translatable languages for the group Hook: getUserPermissionsErrorsExpens...
static checkNeedsFuzzy(MessageHandle $handle, $text)
Returns true if message is fuzzy, OR fails checks OR fails validations (error OR warning).
static onSaveComplete(WikiPage $wikiPage, UserIdentity $userIdentity, string $summary, int $flags, RevisionRecord $revisionRecord, EditResult $editResult)
Runs message checks, adds tp:transver tags and updates statistics.
static disablePreSaveTransform(WikiPage $wikiPage, ParserOptions $popts)
Hook: ArticlePrepareTextForEdit.