summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'MLEB/Translate/tag/PageTranslationHooks.php')
-rw-r--r--MLEB/Translate/tag/PageTranslationHooks.php250
1 files changed, 173 insertions, 77 deletions
diff --git a/MLEB/Translate/tag/PageTranslationHooks.php b/MLEB/Translate/tag/PageTranslationHooks.php
index 205987f5..ed0996da 100644
--- a/MLEB/Translate/tag/PageTranslationHooks.php
+++ b/MLEB/Translate/tag/PageTranslationHooks.php
@@ -7,10 +7,13 @@
* @license GPL-2.0-or-later
*/
-use MediaWiki\Extensions\Translate\SystemUsers\FuzzyBot;
+use MediaWiki\Extension\Translate\PageTranslation\ParsingFailure;
+use MediaWiki\Extension\Translate\Services;
+use MediaWiki\Extension\Translate\SystemUsers\FuzzyBot;
use MediaWiki\Linker\LinkTarget;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\MutableRevisionRecord;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\User\UserIdentity;
use Wikimedia\ScopedCallback;
@@ -23,44 +26,46 @@ use Wikimedia\ScopedCallback;
class PageTranslationHooks {
// Uuugly hacks
public static $allowTargetEdit = false;
-
// Check if job queue is running
public static $jobQueueRunning = false;
-
// Check if we are just rendering tags or such
public static $renderingContext = false;
-
// Used to communicate data between LanguageLinks and SkinTemplateGetLanguageLink hooks.
private static $languageLinkData = [];
/**
* Hook: ParserBeforeInternalParse
- * @param Parser $parser
+ *
+ * @param Parser $wikitextParser
* @param string &$text
* @param-taint $text escapes_htmlnoent
* @param string $state
* @return bool
*/
- public static function renderTagPage( $parser, &$text, $state ) {
- $title = $parser->getTitle();
+ public static function renderTagPage( $wikitextParser, &$text, $state ) {
+ $translatablePageParser = Services::getInstance()->getTranslatablePageParser();
- if ( preg_match( '~</?translate[ >]~', $text ) !== 0 ) {
+ if ( $translatablePageParser->containsMarkup( $text ) ) {
try {
- $parse = TranslatablePage::newFromText( $parser->getTitle(), $text )->getParse();
- $text = $parse->getTranslationPageText( null );
- $parser->getOutput()->addModuleStyles( 'ext.translate' );
- } catch ( TPException $e ) {
- wfDebug( 'TPException caught; expected' );
+ $parserOutput = $translatablePageParser->parse( $text );
+ // If parsing succeeds, replace text and add styles
+ $text = $parserOutput->sourcePageTextForRendering(
+ $wikitextParser->getTargetLanguage()
+ );
+ $wikitextParser->getOutput()->addModuleStyles( 'ext.translate' );
+ } catch ( ParsingFailure $e ) {
+ wfDebug( 'ParsingFailure caught; expected' );
}
}
// For section previews, perform additional clean-up, given tags are often
// unbalanced when we preview one section only.
- if ( $parser->getOptions()->getIsSectionPreview() ) {
- $text = TranslatablePage::cleanupTags( $text );
+ if ( $wikitextParser->getOptions()->getIsSectionPreview() ) {
+ $text = $translatablePageParser->cleanupTags( $text );
}
// Set display title
+ $title = $wikitextParser->getTitle();
$page = TranslatablePage::isTranslationPage( $title );
if ( !$page ) {
return true;
@@ -70,23 +75,40 @@ class PageTranslationHooks {
[ , $code ] = TranslateUtils::figureMessage( $title->getText() );
$name = $page->getPageDisplayTitle( $code );
if ( $name ) {
- $name = $parser->recursivePreprocess( $name );
- $name = $parser->getTargetLanguage()->convert( $name );
- $parser->getOutput()->setDisplayTitle( $name );
+ $name = $wikitextParser->recursivePreprocess( $name );
+ if ( method_exists( MediaWikiServices::class, 'getLanguageConverterFactory' ) ) {
+ // MW >= 1.35
+ $langConv = MediaWikiServices::getInstance()->getLanguageConverterFactory()
+ ->getLanguageConverter( $wikitextParser->getTargetLanguage() );
+ $name = $langConv->convert( $name );
+ } else {
+ $name = $wikitextParser->getTargetLanguage()->convert( $name );
+ }
+ $wikitextParser->getOutput()->setDisplayTitle( $name );
}
self::$renderingContext = false;
- $parser->getOutput()->setExtensionData(
- 'translate-translation-page',
- [
- 'sourcepagetitle' => $page->getTitle(),
- 'languagecode' => $code,
- 'messagegroupid' => $page->getMessageGroupId()
- ]
+ $extensionData = [
+ 'languagecode' => $code,
+ 'messagegroupid' => $page->getMessageGroupId()
+ ];
+ // Backwards-compatibility. If SemanticMediaWiki is installed, write the whole
+ // Title object since prior to https://github.com/SemanticMediaWiki/SemanticMediaWiki/pull/4869
+ // SMW could only understand it. To be removed after SMW release.
+ if ( ExtensionRegistry::getInstance()->isLoaded( 'SemanticMediaWiki' ) ) {
+ $extensionData['sourcepagetitle'] = $page->getTitle();
+ } else {
+ $extensionData['sourcepagetitle'] = [
+ 'namespace' => $page->getTitle()->getNamespace(),
+ 'dbkey' => $page->getTitle()->getDBkey()
+ ];
+ }
+ $wikitextParser->getOutput()->setExtensionData(
+ 'translate-translation-page', $extensionData
);
// Disable edit section links
- $parser->getOutput()->setExtensionData( 'Translate-noeditsection', true );
+ $wikitextParser->getOutput()->setExtensionData( 'Translate-noeditsection', true );
return true;
}
@@ -106,6 +128,81 @@ class PageTranslationHooks {
}
/**
+ * This sets &$revRecord to the revision of transcluded page translation if it exists,
+ * or sets it to the source language if the page translation does not exist.
+ * The page translation is chosen based on language of the source page.
+ * Used in MW >= 1.36
+ *
+ * Hook: BeforeParserFetchTemplateRevisionRecord
+ * @param LinkTarget|null $contextLink
+ * @param LinkTarget|null $templateLink
+ * @param bool &$skip
+ * @param RevisionRecord|null &$revRecord
+ */
+ public static function fetchTranslatableTemplateAndTitle(
+ ?LinkTarget $contextLink,
+ ?LinkTarget $templateLink,
+ bool &$skip,
+ ?RevisionRecord &$revRecord
+ ): void {
+ if ( !$templateLink ) {
+ return;
+ }
+
+ $templateTitle = Title::castFromLinkTarget( $templateLink );
+
+ $templateTranslationPage = TranslatablePage::isTranslationPage( $templateTitle );
+ if ( $templateTranslationPage ) {
+ // Template is referring to a translation page, fetch it and incase it doesn't
+ // exist, fetch the source fallback
+ $revRecord = $templateTranslationPage->getRevisionRecordWithFallback();
+ return;
+ }
+
+ if ( !TranslatablePage::isSourcePage( $templateTitle ) ) {
+ return;
+ }
+
+ $translatableTemplatePage = TranslatablePage::newFromTitle( $templateTitle );
+
+ if ( !( $translatableTemplatePage->supportsTransclusion() ?? false ) ) {
+ // Page being transcluded does not support language aware transclusion
+ return;
+ }
+
+ $store = MediaWikiServices::getInstance()->getRevisionStore();
+
+ if ( $contextLink ) {
+ // Fetch the context page language, and then check if template is present in that language
+ $templateTranslationTitle = $templateTitle->getSubpage(
+ Title::castFromLinkTarget( $contextLink )->getPageLanguage()->getCode()
+ );
+
+ if ( $templateTranslationTitle ) {
+ if ( $templateTranslationTitle->exists() ) {
+ // Template is present in the context page language, fetch the revision record and return
+ $revRecord = $store->getRevisionByTitle( $templateTranslationTitle );
+ } else {
+ // In case the template has not been translated to the context page language,
+ // we assign a MutableRevisionRecord in order to add a dependency, so that when
+ // it is created, the newly created page is loaded rather than the fallback
+ $revRecord = new MutableRevisionRecord( $templateTranslationTitle );
+ }
+ return;
+ }
+ }
+
+ // Context page information not available OR the template translation title could not be determined.
+ // Fetch and return the RevisionRecord of the template in the source language
+ $sourceTemplateTitle = $templateTitle->getSubpage(
+ $translatableTemplatePage->getMessageGroup()->getSourceLanguage()
+ );
+ if ( $sourceTemplateTitle && $sourceTemplateTitle->exists() ) {
+ $revRecord = $store->getRevisionByTitle( $sourceTemplateTitle );
+ }
+ }
+
+ /**
* Set the right page content language for translated pages ("Page/xx").
* Hook: PageContentLanguage
*
@@ -139,15 +236,9 @@ class PageTranslationHooks {
$notices['translate-tag'] = $msg->parseAsBlock();
}
- $label = wfMessage( 'tps-edit-sourcepage-title' )->escaped();
- $msg = Html::rawElement(
- 'div',
- [],
- wfMessage( 'tps-edit-sourcepage-text' )->parse()
- );
-
- $notices[] = TranslateUtils::fieldset(
- $label, $msg, [ 'class' => 'mw-infobox translate-edit-documentation' ]
+ $notices[] = Html::warningBox(
+ wfMessage( 'tps-edit-sourcepage-text' )->parse(),
+ 'translate-edit-documentation'
);
}
}
@@ -229,8 +320,8 @@ class PageTranslationHooks {
return true;
}
- public static function updateTranslationPage( TranslatablePage $page,
- $code, $user, $flags, $summary
+ public static function updateTranslationPage(
+ TranslatablePage $page, $code, $user, $flags, $summary
) {
$source = $page->getTitle();
$target = $source->getSubpage( $code );
@@ -243,11 +334,16 @@ class PageTranslationHooks {
$job->setUser( $user );
$job->setSummary( $summary );
$job->setFlags( $flags );
- $job->run();
+ JobQueueGroup::singleton()->push( $job );
// Invalidate caches so that language bar is up-to-date
$pages = $page->getTranslationPages();
foreach ( $pages as $title ) {
+ if ( $title->equals( $target ) ) {
+ // Handled by the TranslateRenderJob
+ continue;
+ }
+
$wikiPage = WikiPage::factory( $title );
$wikiPage->doPurge();
}
@@ -354,7 +450,7 @@ class PageTranslationHooks {
'task' => 'view'
];
- $classes[] = 'new'; // For red link color
+ $classes[] = 'new'; // For red link color
$attribs = [
'title' => wfMessage( 'tpt-languages-zero' )->inLanguage( $userLang )->text(),
'class' => $classes,
@@ -385,7 +481,7 @@ class PageTranslationHooks {
);
$out .= Html::rawElement(
'div',
- [ 'class' => 'mw-pt-languages-list autonym' ],
+ [ 'class' => 'mw-pt-languages-list' ],
$languages
);
$out .= Html::closeElement( 'div' );
@@ -609,7 +705,6 @@ class PageTranslationHooks {
return true;
}
- /** Returns any syntax error */
protected static function tpSyntaxError( ?Title $title, Content $content ): ?TPException {
if ( !$content instanceof TextContent || !$title ) {
return null;
@@ -620,17 +715,14 @@ class PageTranslationHooks {
// See T154500
$text = str_replace( [ "\r\n", "\r" ], "\n", rtrim( $text ) );
- if ( preg_match( '~</?translate[ >]~', $text ) === 0 ) {
- return null;
- }
-
- $page = TranslatablePage::newFromText( $title, $text );
-
$exception = null;
- try {
- $page->getParse();
- } catch ( TPException $e ) {
- $exception = $e;
+ $parser = Services::getInstance()->getTranslatablePageParser();
+ if ( $parser->containsMarkup( $text ) ) {
+ try {
+ $parser->parse( $text );
+ } catch ( ParsingFailure $e ) {
+ $exception = new TPException( $e->getMessageSpecification() );
+ }
}
return $exception;
@@ -691,19 +783,17 @@ class PageTranslationHooks {
if ( $content instanceof TextContent ) {
$text = $content->getNativeData();
} else {
- // Screw it, not interested
+ // Not applicable
return true;
}
- // Quick escape on normal pages
- if ( preg_match( '~</?translate[ >]~', $text ) === 0 ) {
- return true;
+ $parser = Services::getInstance()->getTranslatablePageParser();
+ if ( $parser->containsMarkup( $text ) ) {
+ // Add the ready tag
+ $page = TranslatablePage::newFromTitle( $wikiPage->getTitle() );
+ $page->addReadyTag( $revisionRecord->getId() );
}
- // Add the ready tag
- $page = TranslatablePage::newFromTitle( $wikiPage->getTitle() );
- $page->addReadyTag( $revisionRecord->getId() );
-
return true;
}
@@ -734,19 +824,17 @@ class PageTranslationHooks {
if ( $content instanceof TextContent ) {
$text = $content->getNativeData();
} else {
- // Screw it, not interested
+ // Not applicable
return true;
}
- // Quick escape on normal pages
- if ( preg_match( '~</?translate[ >]~', $text ) === 0 ) {
- return true;
+ $parser = Services::getInstance()->getTranslatablePageParser();
+ if ( $parser->containsMarkup( $text ) ) {
+ // Add the ready tag
+ $page = TranslatablePage::newFromTitle( $wikiPage->getTitle() );
+ $page->addReadyTag( $revision->getId() );
}
- // Add the ready tag
- $page = TranslatablePage::newFromTitle( $wikiPage->getTitle() );
- $page->addReadyTag( $revision->getId() );
-
return true;
}
@@ -842,7 +930,7 @@ class PageTranslationHooks {
return false;
}
- private static function checkTranslatablePageSlow( LinkTarget $unit ) : ?TranslatablePage {
+ private static function checkTranslatablePageSlow( LinkTarget $unit ): ?TranslatablePage {
$parts = TranslatablePage::parseTranslationUnit( $unit );
$translationPageTitle = Title::newFromText(
$parts[ 'sourcepage' ] . '/' . $parts[ 'language' ]
@@ -886,13 +974,16 @@ class PageTranslationHooks {
return [];
}
- // And finally check whether the language is not included in whitelist
+ // And finally check whether the language is in the inclusion list
$languages = TranslateMetadata::get( $groupId, 'prioritylangs' );
$filter = array_flip( explode( ',', $languages ) );
if ( !isset( $filter[$handle->getCode()] ) ) {
- // @todo Default reason if none provided
$reason = TranslateMetadata::get( $groupId, 'priorityreason' );
- return [ 'tpt-translation-restricted', $reason ];
+ if ( $reason ) {
+ return [ 'tpt-translation-restricted', $reason ];
+ }
+
+ return [ 'tpt-translation-restricted-no-reason' ];
}
return [];
@@ -912,12 +1003,12 @@ class PageTranslationHooks {
return true;
}
- $whitelist = [
+ $inclusionList = [
'read', 'delete', 'undelete', 'deletedtext', 'deletedhistory',
'review', // FlaggedRevs
'patrol', // T151172
];
- if ( in_array( $action, $whitelist ) ) {
+ if ( in_array( $action, $inclusionList ) ) {
return true;
}
@@ -969,7 +1060,7 @@ class PageTranslationHooks {
* Hook: ArticleViewHeader
*
* @param Article $article
- * @param bool &$outputDone
+ * @param bool|ParserOutput|null &$outputDone
* @param bool &$pcache
* @return bool
*/
@@ -1142,8 +1233,8 @@ class PageTranslationHooks {
return true;
}
- $cache = wfGetCache( CACHE_ANYTHING );
- $key = wfMemcKey( 'pt-lock', sha1( $title->getPrefixedText() ) );
+ $cache = ObjectCache::getInstance( CACHE_ANYTHING );
+ $key = $cache->makeKey( 'pt-lock', sha1( $title->getPrefixedText() ) );
if ( $cache->get( $key ) === 'locked' ) {
$result = [ 'pt-locked-page' ];
@@ -1169,7 +1260,11 @@ class PageTranslationHooks {
}
// Copied from Skin::subPageSubtitle()
- if ( $out->isArticle() && MWNamespace::hasSubpages( $out->getTitle()->getNamespace() ) ) {
+ $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
+ if (
+ $out->isArticle() &&
+ $nsInfo->hasSubpages( $out->getTitle()->getNamespace() )
+ ) {
$ptext = $out->getTitle()->getPrefixedText();
if ( strpos( $ptext, '/' ) !== false ) {
$links = explode( '/', $ptext );
@@ -1352,6 +1447,7 @@ class PageTranslationHooks {
continue;
}
+ /** @var WikiPageMessageGroup */
$group = $handle->getGroup();
if ( !$group instanceof WikiPageMessageGroup ) {
continue;