summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/TranslateEditAddons.php
diff options
context:
space:
mode:
authorYaco <franco@reevo.org>2020-06-04 11:01:00 -0300
committerYaco <franco@reevo.org>2020-06-04 11:01:00 -0300
commitfc7369835258467bf97eb64f184b93691f9a9fd5 (patch)
treedaabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/extensions/Translate/TranslateEditAddons.php
first commit
Diffstat (limited to 'www/wiki/extensions/Translate/TranslateEditAddons.php')
-rw-r--r--www/wiki/extensions/Translate/TranslateEditAddons.php425
1 files changed, 425 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/TranslateEditAddons.php b/www/wiki/extensions/Translate/TranslateEditAddons.php
new file mode 100644
index 00000000..6a896546
--- /dev/null
+++ b/www/wiki/extensions/Translate/TranslateEditAddons.php
@@ -0,0 +1,425 @@
+<?php
+/**
+ * Tools for edit page view to aid translators. This implements the so called
+ * old style editing, which extends the normal edit page.
+ *
+ * @file
+ * @author Niklas Laxström
+ * @author Siebrand Mazeland
+ * @license GPL-2.0-or-later
+ */
+
+/**
+ * Various editing enhancements to the edit page interface.
+ * Partly succeeded by the new ajax-enhanced editor but kept for compatibility.
+ * Also has code that is still relevant, like the hooks on save.
+ */
+class TranslateEditAddons {
+ /**
+ * Do not show the usual introductory messages on edit page for messages.
+ * Hook: AlternateEdit
+ * @param EditPage $editPage
+ */
+ public static function suppressIntro( EditPage $editPage ) {
+ $handle = new MessageHandle( $editPage->getTitle() );
+ if ( $handle->isValid() ) {
+ $editPage->suppressIntro = true;
+ }
+ }
+
+ /**
+ * Prevent translations to non-translatable languages for the group
+ * Hook: getUserPermissionsErrorsExpensive
+ *
+ * @param Title $title
+ * @param User $user
+ * @param string $action
+ * @param mixed &$result
+ * @return bool
+ */
+ public static function disallowLangTranslations( Title $title, User $user,
+ $action, &$result
+ ) {
+ global $wgTranslateBlacklist;
+
+ if ( $action !== 'edit' ) {
+ return true;
+ }
+
+ $handle = new MessageHandle( $title );
+ if ( !$handle->isValid() ) {
+ return true;
+ }
+
+ if ( $user->isAllowed( 'translate-manage' ) ) {
+ return true;
+ }
+
+ $group = $handle->getGroup();
+ $languages = $group->getTranslatableLanguages();
+ $langCode = $handle->getCode();
+ if ( $languages !== null && $langCode && !isset( $languages[$langCode] ) ) {
+ $result = [ 'translate-language-disabled' ];
+ return false;
+ }
+
+ $groupId = $group->getId();
+ $checks = [
+ $groupId,
+ strtok( $groupId, '-' ),
+ '*'
+ ];
+
+ foreach ( $checks as $check ) {
+ if ( isset( $wgTranslateBlacklist[$check][$langCode] ) ) {
+ $reason = $wgTranslateBlacklist[$check][$langCode];
+ $result = [ 'translate-page-disabled', $reason ];
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Adds the translation aids and navigation to the normal edit page.
+ * Hook: EditPage::showEditForm:initial
+ * @param EditPage $object
+ * @return true
+ */
+ public static function addTools( EditPage $object ) {
+ $handle = new MessageHandle( $object->getTitle() );
+ if ( !$handle->isValid() ) {
+ return true;
+ }
+
+ $object->editFormTextTop .= self::editBoxes( $object );
+
+ return true;
+ }
+
+ /**
+ * Replace the normal save button with one that says if you are editing
+ * message documentation to try to avoid accidents.
+ * Hook: EditPageBeforeEditButtons
+ *
+ * @param EditPage $editpage
+ * @param array &$buttons
+ * @param int $tabindex
+ */
+ public static function buttonHack( EditPage $editpage, &$buttons, $tabindex ) {
+ $handle = new MessageHandle( $editpage->getTitle() );
+ if ( !$handle->isValid() ) {
+ return;
+ }
+
+ $context = $editpage->getArticle()->getContext();
+
+ if ( $handle->isDoc() ) {
+ $langCode = $context->getLanguage()->getCode();
+ $name = TranslateUtils::getLanguageName( $handle->getCode(), $langCode );
+ $attribs = [
+ 'id' => 'wpSave',
+ 'name' => 'wpSave',
+ 'tabindex' => ++$tabindex,
+ ] + Linker::tooltipAndAccesskeyAttribs( 'save' );
+
+ $saveConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
+ $buttons['save'] = new OOUI\ButtonInputWidget( [
+ // Support: IE 6 – Use <input>, otherwise it can't distinguish which button was clicked
+ 'useInputTag' => true,
+ 'flags' => [ 'progressive', 'primary' ],
+ 'label' => $context->msg( 'translate-save', $name )->text(),
+ 'type' => 'submit',
+ ] + $saveConfig );
+ }
+
+ try {
+ $supportUrl = SupportAid::getSupportUrl( $handle->getTitle() );
+ } catch ( TranslationHelperException $e ) {
+ return;
+ }
+
+ $attribs = [
+ 'id' => 'wpSupport',
+ 'name' => 'wpSupport',
+ 'type' => 'button',
+ 'tabindex' => ++$tabindex,
+ 'title' => $context->msg( 'translate-js-support-title' )->text(),
+ ];
+
+ $attribs += [
+ 'label' => $context->msg( 'translate-js-support' )->text(),
+ 'href' => $supportUrl,
+ 'target' => '_blank',
+ ];
+ $saveConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
+ $buttons['ask'] = new OOUI\ButtonWidget( $saveConfig );
+ }
+
+ /**
+ * @param EditPage $editpage
+ * @return string
+ */
+ private static function editBoxes( EditPage $editpage ) {
+ $context = $editpage->getArticle()->getContext();
+ $request = $context->getRequest();
+
+ $groupId = $request->getText( 'loadgroup', '' );
+ $th = new TranslationHelpers( $editpage->getTitle(), $groupId );
+
+ if ( $editpage->firsttime &&
+ !$request->getCheck( 'oldid' ) &&
+ !$request->getCheck( 'undo' )
+ ) {
+ $editpage->textbox1 = (string)$th->getTranslation();
+ } else {
+ $th->setTranslation( $editpage->textbox1 );
+ }
+
+ TranslationHelpers::addModules( $context->getOutput() );
+
+ return $th->getBoxes();
+ }
+
+ /**
+ * Runs message checks, adds tp:transver tags and updates statistics.
+ * Hook: PageContentSaveComplete
+ * @param WikiPage $wikiPage
+ * @param User $user
+ * @param Content $content
+ * @param string $summary
+ * @param bool $minor
+ * @param string $_1
+ * @param bool $_2
+ * @param int $flags
+ * @param Revision|null $revision
+ * @return true
+ */
+ public static function onSave( WikiPage $wikiPage, User $user, Content $content, $summary,
+ $minor, $_1, $_2, $flags, Revision $revision = null
+ ) {
+ global $wgEnablePageTranslation;
+
+ if ( !$content instanceof TextContent ) {
+ // Screw it, not interested
+ return true;
+ }
+
+ $text = $content->getNativeData();
+ $title = $wikiPage->getTitle();
+ $handle = new MessageHandle( $title );
+
+ if ( !$handle->isValid() ) {
+ return true;
+ }
+
+ // Update it.
+ if ( $revision === null ) {
+ $rev = $wikiPage->getTitle()->getLatestRevID();
+ } else {
+ $rev = $revision->getID();
+ }
+
+ $fuzzy = self::checkNeedsFuzzy( $handle, $text );
+ self::updateFuzzyTag( $title, $rev, $fuzzy );
+
+ $group = $handle->getGroup();
+ // Update translation stats - source language should always be up to date
+ if ( $handle->getCode() !== $group->getSourceLanguage() ) {
+ // This will update in-process cache immediately, but the value is saved
+ // to the database in a deferred update. See MessageGroupStats::queueUpdates.
+ // In case an error happens before that, the stats may be stale, but that
+ // would be fixed by the next update or purge.
+ MessageGroupStats::clear( $handle );
+ }
+
+ MessageGroupStatesUpdaterJob::onChange( $handle );
+
+ if ( $fuzzy === false ) {
+ Hooks::run( 'Translate:newTranslation', [ $handle, $rev, $text, $user ] );
+ }
+
+ TTMServer::onChange( $handle );
+
+ if ( $wgEnablePageTranslation && $handle->isPageTranslation() ) {
+ // Updates for translatable pages only
+ PageTranslationHooks::onSectionSave( $wikiPage, $user, $content,
+ $summary, $minor, $flags, $revision, $handle );
+ }
+
+ return true;
+ }
+
+ /**
+ * @param MessageHandle $handle
+ * @param string $text
+ * @return bool
+ */
+ protected static function checkNeedsFuzzy( MessageHandle $handle, $text ) {
+ // Check for explicit tag.
+ $fuzzy = MessageHandle::hasFuzzyString( $text );
+
+ // Docs are exempt for checks
+ if ( $handle->isDoc() ) {
+ return $fuzzy;
+ }
+
+ // Not all groups have checkers
+ $group = $handle->getGroup();
+ $checker = $group->getChecker();
+ if ( !$checker ) {
+ return $fuzzy;
+ }
+
+ $code = $handle->getCode();
+ $key = $handle->getKey();
+ $en = $group->getMessage( $key, $group->getSourceLanguage() );
+ $message = new FatMessage( $key, $en );
+ // Take the contents from edit field as a translation.
+ $message->setTranslation( $text );
+
+ $checks = $checker->checkMessage( $message, $code );
+ if ( count( $checks ) ) {
+ $fuzzy = true;
+ }
+
+ return $fuzzy;
+ }
+
+ /**
+ * @param Title $title
+ * @param int $revision
+ * @param bool $fuzzy Whether to fuzzy or not
+ * @return bool Whether status changed
+ */
+ protected static function updateFuzzyTag( Title $title, $revision, $fuzzy ) {
+ $dbw = wfGetDB( DB_MASTER );
+
+ $conds = [
+ 'rt_page' => $title->getArticleID(),
+ 'rt_type' => RevTag::getType( 'fuzzy' ),
+ 'rt_revision' => $revision
+ ];
+
+ // Replace the existing fuzzy tag, if any
+ if ( $fuzzy !== false ) {
+ $index = array_keys( $conds );
+ $dbw->replace( 'revtag', [ $index ], $conds, __METHOD__ );
+ } else {
+ $dbw->delete( 'revtag', $conds, __METHOD__ );
+ }
+
+ return (bool)$dbw->affectedRows();
+ }
+
+ /**
+ * Adds tag which identifies the revision of source message at that time.
+ * This is used to show diff against current version of source message
+ * when updating a translation.
+ * Hook: Translate:newTranslation
+ * @param MessageHandle $handle
+ * @param int $revision
+ * @param string $text
+ * @param User $user
+ * @return bool
+ */
+ public static function updateTransverTag( MessageHandle $handle, $revision,
+ $text, User $user
+ ) {
+ if ( $user->isAllowed( 'bot' ) ) {
+ return false;
+ }
+
+ $group = $handle->getGroup();
+
+ $title = $handle->getTitle();
+ $name = $handle->getKey() . '/' . $group->getSourceLanguage();
+ $definitionTitle = Title::makeTitleSafe( $title->getNamespace(), $name );
+ if ( !$definitionTitle || !$definitionTitle->exists() ) {
+ return true;
+ }
+
+ $definitionRevision = $definitionTitle->getLatestRevID();
+
+ $dbw = wfGetDB( DB_MASTER );
+
+ $conds = [
+ 'rt_page' => $title->getArticleID(),
+ 'rt_type' => RevTag::getType( 'tp:transver' ),
+ 'rt_revision' => $revision,
+ 'rt_value' => $definitionRevision,
+ ];
+ $index = [ 'rt_type', 'rt_page', 'rt_revision' ];
+ $dbw->replace( 'revtag', [ $index ], $conds, __METHOD__ );
+
+ return true;
+ }
+
+ /**
+ * Hook: ArticlePrepareTextForEdit
+ * @param WikiPage $wikiPage
+ * @param ParserOptions $popts
+ * @return bool
+ */
+ public static function disablePreSaveTransform( WikiPage $wikiPage, ParserOptions $popts ) {
+ global $wgTranslateUsePreSaveTransform;
+
+ if ( !$wgTranslateUsePreSaveTransform ) {
+ $handle = new MessageHandle( $wikiPage->getTitle() );
+ if ( $handle->isMessageNamespace() && !$handle->isDoc() ) {
+ $popts->setPreSaveTransform( false );
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Hook: ArticleContentOnDiff
+ * @param DifferenceEngine $de
+ * @param OutputPage $out
+ * @return true
+ */
+ public static function displayOnDiff( DifferenceEngine $de, OutputPage $out ) {
+ $title = $de->getTitle();
+ $handle = new MessageHandle( $title );
+
+ if ( !$handle->isValid() ) {
+ return true;
+ }
+
+ $th = new TranslationHelpers( $title, /*group*/false );
+ $th->setEditMode( false );
+
+ $de->loadNewText();
+ if ( method_exists( $de, 'getNewRevision' ) ) {
+ $newRevision = $de->getNewRevision();
+ $newContent = $newRevision ? $newRevision->getContent( 'main' ) : null;
+ } else {
+ $newContent = $de->mNewRev ? $de->mNewRev->getContent() : null;
+ }
+ if ( $newContent instanceof TextContent ) {
+ $th->setTranslation( $newContent->getNativeData() );
+ } else {
+ // Screw you, not interested.
+ return true;
+ }
+ TranslationHelpers::addModules( $out );
+
+ $boxes = [];
+ $boxes[] = $th->callBox( 'documentation', [ $th, 'getDocumentationBox' ] );
+ $boxes[] = $th->callBox( 'definition', [ $th, 'getDefinitionBox' ] );
+ $boxes[] = $th->callBox( 'translation', [ $th, 'getTranslationDisplayBox' ] );
+
+ $output = implode( "\n", $boxes );
+ $output = Html::rawElement(
+ 'div',
+ [ 'class' => 'mw-sp-translate-edit-fields' ],
+ $output
+ );
+ $out->addHTML( $output );
+
+ return true;
+ }
+}