summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'MLEB/Translate/TranslateHooks.php')
-rw-r--r--MLEB/Translate/TranslateHooks.php375
1 files changed, 81 insertions, 294 deletions
diff --git a/MLEB/Translate/TranslateHooks.php b/MLEB/Translate/TranslateHooks.php
index 3d092870..7c26d147 100644
--- a/MLEB/Translate/TranslateHooks.php
+++ b/MLEB/Translate/TranslateHooks.php
@@ -8,19 +8,26 @@
*/
use MediaWiki\Config\ServiceOptions;
+use MediaWiki\Extension\Translate\PageTranslation\PageTranslationSpecialPage;
use MediaWiki\Extension\Translate\SystemUsers\FuzzyBot;
use MediaWiki\Extension\Translate\SystemUsers\TranslateUserManager;
use MediaWiki\Extension\Translate\TranslatorSandbox\ManageTranslatorSandboxSpecialPage;
use MediaWiki\Extension\Translate\TranslatorSandbox\TranslationStashSpecialPage;
use MediaWiki\Hook\BeforeParserFetchTemplateRevisionRecordHook;
-use MediaWiki\Hook\PageMoveCompleteHook;
-use MediaWiki\Hook\SidebarBeforeOutputHook;
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\Hook\RevisionRecordInsertedHook;
+use MediaWiki\Revision\RevisionLookup;
+use Wikimedia\Rdbms\ILoadBalancer;
/**
- * Some hooks for Translate extension.
+ * Hooks for Translate extension.
+ *
+ * Main subsystems, like page translation, should have their own hook handler.
+ *
+ * Most of the hooks on this class are still old style static functions, but new new hooks should
+ * use the new style hook handlers with interfaces.
*/
-class TranslateHooks {
+class TranslateHooks implements RevisionRecordInsertedHook {
/**
* Any user of this list should make sure that the tables
* actually exist, since they may be optional
@@ -31,6 +38,15 @@ class TranslateHooks {
'translate_stash' => 'ts_user',
'translate_reviews' => 'trr_user',
];
+ /** @var RevisionLookup */
+ private $revisionLookup;
+ /** @var ILoadBalancer */
+ private $loadBalancer;
+
+ public function __construct( RevisionLookup $revisionLookup, ILoadBalancer $loadBalancer ) {
+ $this->revisionLookup = $revisionLookup;
+ $this->loadBalancer = $loadBalancer;
+ }
/**
* Do late setup that depends on configuration.
@@ -50,19 +66,23 @@ class TranslateHooks {
$wgTranslateYamlLibrary = function_exists( 'yaml_parse' ) ? 'phpyaml' : 'spyc';
}
- $usePageSaveComplete = version_compare( TranslateUtils::getMWVersion(), '1.35', '>=' );
- if ( $usePageSaveComplete ) {
- $wgHooks['PageSaveComplete'][] = 'TranslateEditAddons::onSaveComplete';
- } else {
- $wgHooks['PageContentSaveComplete'][] = 'TranslateEditAddons::onSave';
- }
+ $wgHooks['PageSaveComplete'][] = 'TranslateEditAddons::onSaveComplete';
// Page translation setup check and init if enabled.
global $wgEnablePageTranslation;
if ( $wgEnablePageTranslation ) {
// Special page and the right to use it
global $wgSpecialPages, $wgAvailableRights;
- $wgSpecialPages['PageTranslation'] = 'SpecialPageTranslation';
+ $wgSpecialPages['PageTranslation'] = [
+ 'class' => PageTranslationSpecialPage::class,
+ 'services' => [
+ 'LanguageNameUtils',
+ 'LanguageFactory',
+ 'Translate:TranslationUnitStoreFactory',
+ 'Translate:TranslatablePageParser',
+ 'LinkBatchFactory'
+ ]
+ ];
$wgSpecialPages['PageTranslationDeletePage'] = 'SpecialPageTranslationDeletePage';
// right-pagetranslation action-pagetranslation
@@ -131,16 +151,13 @@ class TranslateHooks {
$wgHooks['BeforePageDisplay'][] = 'PageTranslationHooks::onBeforePageDisplay';
// Check syntax for \<translate>
- $wgHooks['PageContentSave'][] = 'PageTranslationHooks::tpSyntaxCheck';
+ $wgHooks['MultiContentSave'][] = 'PageTranslationHooks::tpSyntaxCheck';
$wgHooks['EditFilterMergedContent'][] =
'PageTranslationHooks::tpSyntaxCheckForEditContent';
// Add transtag to page props for discovery
- if ( $usePageSaveComplete ) {
- $wgHooks['PageSaveComplete'][] = 'PageTranslationHooks::addTranstagAfterSave';
- } else {
- $wgHooks['PageContentSaveComplete'][] = 'PageTranslationHooks::addTranstag';
- }
+ $wgHooks['PageSaveComplete'][] = 'PageTranslationHooks::addTranstagAfterSave';
+
$wgHooks['RevisionRecordInserted'][] =
'PageTranslationHooks::updateTranstagOnNullRevisions';
@@ -190,11 +207,7 @@ class TranslateHooks {
$wgHooks['SkinTemplateNavigation'][] = 'PageTranslationHooks::translateTab';
// Update translated page when translation unit is moved
- if ( interface_exists( PageMoveCompleteHook::class ) ) {
- $wgHooks['PageMoveComplete'][] = 'PageTranslationHooks::onMovePageTranslationUnits';
- } else {
- $wgHooks['TitleMoveComplete'][] = 'PageTranslationHooks::onMoveTranslationUnits';
- }
+ $wgHooks['PageMoveComplete'][] = 'PageTranslationHooks::onMovePageTranslationUnits';
// Update translated page when translation unit is deleted
$wgHooks['ArticleDeleteComplete'][] = 'PageTranslationHooks::onDeleteTranslationUnit';
@@ -210,7 +223,7 @@ class TranslateHooks {
'Translate:TranslationStashReader',
],
'args' => [
- function () {
+ static function () {
return new ServiceOptions(
ManageTranslatorSandboxSpecialPage::CONSTRUCTOR_OPTIONS,
MediaWikiServices::getInstance()->getMainConfig()
@@ -225,7 +238,7 @@ class TranslateHooks {
'Translate:TranslationStashReader'
],
'args' => [
- function () {
+ static function () {
return new ServiceOptions(
TranslationStashSpecialPage::CONSTRUCTOR_OPTIONS,
MediaWikiServices::getInstance()->getMainConfig()
@@ -278,12 +291,7 @@ class TranslateHooks {
}
}
- // Add the BaseTemplateToolbox handler only when the new hook hasn't been defined yet.
- if ( interface_exists( SidebarBeforeOutputHook::class ) ) {
- $wgHooks['SidebarBeforeOutput'][] = 'TranslateToolbox::toolboxAllTranslations';
- } else {
- $wgHooks['BaseTemplateToolbox'][] = 'TranslateToolbox::toolboxAllTranslationsOld';
- }
+ $wgHooks['SidebarBeforeOutput'][] = 'TranslateToolbox::toolboxAllTranslations';
}
/**
@@ -660,37 +668,6 @@ class TranslateHooks {
}
/**
- * Hook: Translate:MessageGroupStats:isIncluded
- * @param int $id
- * @param string $code
- * @return bool
- */
- public static function hideDiscouragedFromStats( $id, $code ) {
- // Return true to keep, false to exclude
- return MessageGroups::getPriority( $id ) !== 'discouraged';
- }
-
- /**
- * Hook: Translate:MessageGroupStats:isIncluded
- * @param int $id
- * @param string $code
- * @return false
- */
- public static function hideRestrictedFromStats( $id, $code ) {
- $filterLangs = TranslateMetadata::get( $id, 'prioritylangs' );
- $hasPriorityForce = TranslateMetadata::get( $id, 'priorityforce' ) === 'on';
- if ( strlen( $filterLangs ) === 0 || !$hasPriorityForce ) {
- // No restrictions, keep everything
- return true;
- }
-
- $filter = array_flip( explode( ',', $filterLangs ) );
-
- // If the language is in the list, return true to not hide it
- return isset( $filter[$code] );
- }
-
- /**
* Hook: LinksUpdate
* @param LinksUpdate $updater
*/
@@ -754,7 +731,7 @@ class TranslateHooks {
* @param User $newUser
*/
public static function onMergeAccountFromTo( User $oldUser, User $newUser ) {
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = wfGetDB( DB_PRIMARY );
// Update the non-duplicate rows, we'll just delete
// the duplicate ones later
@@ -778,7 +755,7 @@ class TranslateHooks {
* @param User $oldUser
*/
public static function onDeleteAccount( User $oldUser ) {
- $dbw = wfGetDB( DB_MASTER );
+ $dbw = wfGetDB( DB_PRIMARY );
// Delete any remaining rows that didn't get merged
foreach ( self::$userMergeTables as $table => $field ) {
@@ -868,234 +845,6 @@ class TranslateHooks {
return '';
}
- /** @param ResourceLoader $resourceLoader */
- public static function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ) {
- // Support: MediaWiki <= 1.34
- $hasOldTokens = $hasOldNotify = version_compare(
- TranslateUtils::getMWVersion(), '1.35', '<'
- );
-
- $tpl = [
- 'localBasePath' => __DIR__,
- 'remoteExtPath' => 'Translate',
- 'targets' => [ 'desktop', 'mobile' ],
- ];
-
- $modules = [
- 'ext.translate.recentgroups' => $tpl + [
- 'scripts' => 'resources/js/ext.translate.recentgroups.js',
- 'dependencies' => [
- 'mediawiki.storage'
- ],
- ],
- 'ext.translate.groupselector' => $tpl + [
- 'styles' => 'resources/css/ext.translate.groupselector.less',
- 'scripts' => 'resources/js/ext.translate.groupselector.js',
- 'dependencies' => [
- 'ext.translate.base',
- 'ext.translate.loader',
- 'ext.translate.statsbar',
- 'jquery.ui',
- 'mediawiki.jqueryMsg'
- ],
- 'messages' => [
- 'translate-msggroupselector-search-all',
- 'translate-msggroupselector-search-placeholder',
- 'translate-msggroupselector-search-recent',
- 'translate-msggroupselector-view-subprojects'
- ]
- ],
- 'ext.translate.special.aggregategroups' => $tpl + [
- 'scripts' => 'resources/js/ext.translate.special.aggregategroups.js',
- 'dependencies' => [
- 'jquery.ui',
- 'mediawiki.api',
- 'mediawiki.util'
- ],
- 'messages' => [
- 'tpt-aggregategroup-add',
- 'tpt-aggregategroup-edit-description',
- 'tpt-aggregategroup-edit-name',
- 'tpt-aggregategroup-remove-confirm',
- 'tpt-aggregategroup-update',
- 'tpt-aggregategroup-update-cancel',
- 'tpt-invalid-group'
- ]
- ],
- 'ext.translate.special.importtranslations' => $tpl + [
- 'scripts' => 'resources/js/ext.translate.special.importtranslations.js',
- 'dependencies' => [
- 'jquery.ui',
- ]
- ],
- 'ext.translate.special.managetranslatorsandbox' => $tpl + [
- 'scripts' => 'resources/js/ext.translate.special.managetranslatorsandbox.js',
- 'dependencies' => array_merge( [
- 'ext.translate.loader',
- 'ext.translate.translationstashstorage',
- 'ext.uls.mediawiki',
- 'jquery.ui',
- 'mediawiki.api',
- 'mediawiki.jqueryMsg',
- 'mediawiki.language',
- ], $hasOldNotify ? [ 'mediawiki.notify' ] : [] ),
- 'messages' => [
- 'tsb-accept-all-button-label',
- 'tsb-accept-button-label',
- 'tsb-reject-confirmation',
- 'tsb-accept-confirmation',
- 'tsb-all-languages-button-label',
- 'tsb-didnt-make-any-translations',
- 'tsb-no-requests-from-new-users',
- 'tsb-older-requests',
- 'tsb-reject-all-button-label',
- 'tsb-reject-button-label',
- 'tsb-reminder-failed',
- 'tsb-reminder-link-text',
- 'tsb-reminder-sending',
- 'tsb-reminder-sent',
- 'tsb-reminder-sent-new',
- 'tsb-request-count',
- 'tsb-selected-count',
- 'tsb-translations-current',
- 'tsb-translations-source',
- 'tsb-translations-user',
- 'tsb-user-posted-a-comment'
- ]
- ],
- 'ext.translate.special.searchtranslations.operatorsuggest' => $tpl + [
- 'scripts' => 'resources/js/ext.translate.special.operatorsuggest.js',
- 'dependencies' => [
- 'jquery.ui',
- ]
- ],
- 'ext.translate.special.pagetranslation' => $tpl + [
- 'packageFiles' => [
- 'resources/js/ext.translate.special.pagetranslation.js',
- 'resources/js/LanguagesMultiselectWidget.js'
- ],
- 'dependencies' => [
- 'mediawiki.Uri',
- 'mediawiki.api',
- 'mediawiki.ui.button',
- 'mediawiki.widgets',
- 'oojs-ui-widgets',
- $hasOldTokens ? 'user.tokens' : 'user.options',
- ],
- 'targets' => [
- 'desktop'
- ]
- ],
- "ext.translate.editor" => $tpl + [
- "scripts" => [
- "resources/js/ext.translate.storage.js",
- "resources/lib/jquery.autosize.js",
- "resources/js/ext.translate.editor.helpers.js",
- "resources/js/ext.translate.editor.js",
- "resources/js/ext.translate.editor.shortcuts.js",
- "resources/js/ext.translate.pagemode.js",
- "resources/js/ext.translate.proofread.js"
- ],
- "styles" => [
- "resources/css/ext.translate.editor.css",
- "resources/css/ext.translate.pagemode.css",
- "resources/css/ext.translate.proofread.css"
- ],
- "dependencies" => array_merge( [
- "ext.translate.base",
- "ext.translate.dropdownmenu",
- "jquery.makeCollapsible",
- "jquery.textSelection",
- "jquery.textchange",
- "mediawiki.Uri",
- "mediawiki.api",
- "mediawiki.jqueryMsg",
- "mediawiki.language",
- "mediawiki.user",
- "mediawiki.util"
- ], $hasOldNotify ? [ 'mediawiki.notify' ] : [] ),
- "messages" => [
- "translate-edit-askpermission",
- "translate-edit-nopermission",
- "tux-editor-add-desc",
- "tux-editor-ask-help",
- "tux-editor-cancel-button-label",
- "tux-editor-close-tooltip",
- "tux-editor-collapse-tooltip",
- "tux-editor-confirm-button-label",
- "tux-editor-discard-changes-button-label",
- "tux-editor-doc-editor-cancel",
- "tux-editor-doc-editor-placeholder",
- "tux-editor-doc-editor-save",
- "tux-editor-edit-desc",
- "tux-editor-expand-tooltip",
- "tux-editor-in-other-languages",
- "tux-editor-loading",
- "tux-editor-loading-failed",
- "tux-editor-message-desc-less",
- "tux-editor-message-desc-more",
- "tux-editor-message-tools-show-editor",
- "tux-editor-message-tools-delete",
- "tux-editor-message-tools-history",
- "tux-editor-message-tools-translations",
- "tux-editor-message-tools-linktothis",
- "tux-editor-n-uses",
- "tux-editor-need-more-help",
- "tux-editor-outdated-notice",
- "tux-editor-outdated-notice-diff-link",
- "tux-editor-paste-original-button-label",
- "tux-editor-placeholder",
- "tux-editor-editsummary-placeholder",
- "tux-editor-proofread-button-label",
- "tux-editor-save-button-label",
- "tux-editor-save-failed",
- "tux-editor-shortcut-info",
- "tux-editor-skip-button-label",
- "tux-editor-suggestions-title",
- "tux-editor-tm-match",
- "tux-proofread-action-tooltip",
- "tux-proofread-edit-label",
- "tux-proofread-translated-by-self",
- "tux-session-expired",
- "tux-status-saving",
- "tux-status-translated",
- "tux-status-unsaved",
- "tux-save-unknown-error",
- "tux-notices-hide",
- "tux-notices-more",
- "spamprotectiontext"
- ],
- "targets" => [
- "desktop",
- "mobile"
- ]
- ],
- "ext.translate.special.managegroups" => $tpl + [
- "dependencies" => array_merge( [
- "ext.translate.messagerenamedialog"
- ], $hasOldNotify ? [ 'mediawiki.notify' ] : [] ),
- "messages" => [
- "translate-smg-rename-new",
- "translate-smg-rename-rename",
- "translate-smg-rename-dialog-title",
- "translate-smg-loading",
- "translate-smg-group-action-resolve",
- "translate-smg-unknown-error",
- "percent"
- ],
- "scripts" => [
- "resources/js/ext.translate.special.managegroups.js"
- ],
- "targets" => [
- "desktop",
- "mobile"
- ]
- ],
- ];
-
- $resourceLoader->register( $modules );
- }
-
/**
* Runs the configured validator to ensure that the message meets the required criteria.
* Hook: EditFilterMergedContent
@@ -1103,7 +852,7 @@ class TranslateHooks {
* @param Content $content
* @param Status $status
* @param string $summary
- * @param \User $user
+ * @param User $user
* @return bool true if message is valid, false otherwise.
*/
public static function validateMessage( IContextSource $context, Content $content,
@@ -1148,8 +897,7 @@ class TranslateHooks {
$validationResponse = $messageValidator->validateMessage( $message, $handle->getCode() );
if ( $validationResponse->hasErrors() ) {
- // @phan-suppress-next-line SecurityCheck-DoubleEscaped
- $status->fatal( new \ApiRawMessage(
+ $status->fatal( new ApiRawMessage(
$context->msg( 'translate-syntax-error' )->parse(),
'translate-validation-failed',
[
@@ -1159,10 +907,49 @@ class TranslateHooks {
]
]
) );
+ // @todo Remove this line after this extension do not support mediawiki version 1.36 and before
+ $status->value = EditPage::AS_HOOK_ERROR_EXPECTED;
return false;
}
}
return true;
}
+
+ /** @inheritDoc */
+ public function onRevisionRecordInserted( $revisionRecord ): void {
+ $parentId = $revisionRecord->getParentId();
+ if ( $parentId === 0 || $parentId === null ) {
+ // No parent, bail out.
+ return;
+ }
+
+ $prevRev = $this->revisionLookup->getRevisionById( $parentId );
+ if ( !$prevRev || !$revisionRecord->hasSameContent( $prevRev ) ) {
+ // Not a null revision, bail out.
+ return;
+ }
+
+ // List of tags that should be copied over when updating
+ // tp:tag and tp:mark handling is in PageTranslationHooks::updateTranstagOnNullRevisions.
+ $tagsToCopy = [ 'fuzzy', 'tp:transver' ];
+
+ $db = $this->loadBalancer->getConnectionRef( DB_PRIMARY );
+ $db->insertSelect(
+ 'revtag',
+ 'revtag',
+ [
+ 'rt_type' => 'rt_type',
+ 'rt_page' => 'rt_page',
+ 'rt_revision' => $revisionRecord->getId(),
+ 'rt_value' => 'rt_value',
+
+ ],
+ [
+ 'rt_type' => $tagsToCopy,
+ 'rt_revision' => $parentId,
+ ],
+ __METHOD__
+ );
+ }
}