aboutsummaryrefslogtreecommitdiffstats
path: root/includes/language/MessageCache.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/language/MessageCache.php')
-rw-r--r--includes/language/MessageCache.php156
1 files changed, 22 insertions, 134 deletions
diff --git a/includes/language/MessageCache.php b/includes/language/MessageCache.php
index 45eff8cf547b..490f9f0fc4bc 100644
--- a/includes/language/MessageCache.php
+++ b/includes/language/MessageCache.php
@@ -20,13 +20,13 @@
use MediaWiki\Config\ServiceOptions;
use MediaWiki\Content\Content;
-use MediaWiki\Context\RequestContext;
use MediaWiki\Deferred\DeferredUpdates;
use MediaWiki\HookContainer\HookContainer;
use MediaWiki\HookContainer\HookRunner;
use MediaWiki\Language\ILanguageConverter;
use MediaWiki\Language\Language;
use MediaWiki\Language\MessageCacheUpdate;
+use MediaWiki\Language\MessageParser;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Languages\LanguageFactory;
use MediaWiki\Languages\LanguageFallback;
@@ -37,9 +37,6 @@ use MediaWiki\MediaWikiServices;
use MediaWiki\Page\PageIdentity;
use MediaWiki\Page\PageReference;
use MediaWiki\Page\PageReferenceValue;
-use MediaWiki\Parser\Parser;
-use MediaWiki\Parser\ParserFactory;
-use MediaWiki\Parser\ParserOptions;
use MediaWiki\Parser\ParserOutput;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\StubObject\StubObject;
@@ -139,23 +136,6 @@ class MessageCache implements LoggerAwareInterface {
/** @var string[] */
private $rawHtmlMessages;
- /**
- * Message cache has its own parser which it uses to transform messages
- * @var ParserOptions
- */
- private $parserOptions;
-
- /** @var Parser[] Lazy-created via self::getParser() */
- private array $parsers = [];
- private int $curParser = -1;
-
- /**
- * Parsing some messages may require parsing another message first, due to special page
- * transclusion and some hooks (T372891). This constant is the limit of nesting depth where
- * we'll display an error instead of the other message.
- */
- private const MAX_PARSER_DEPTH = 5;
-
/** @var WANObjectCache */
private $wanCache;
/** @var BagOStuff */
@@ -178,8 +158,8 @@ class MessageCache implements LoggerAwareInterface {
private $languageFallback;
/** @var HookRunner */
private $hookRunner;
- /** @var ParserFactory */
- private $parserFactory;
+ /** @var MessageParser */
+ private $messageParser;
/** @var (string|callable)[]|null */
private $messageKeyOverrides;
@@ -220,7 +200,7 @@ class MessageCache implements LoggerAwareInterface {
* @param LanguageNameUtils $languageNameUtils
* @param LanguageFallback $languageFallback
* @param HookContainer $hookContainer
- * @param ParserFactory $parserFactory
+ * @param MessageParser $messageParser
*/
public function __construct(
WANObjectCache $wanCache,
@@ -235,7 +215,7 @@ class MessageCache implements LoggerAwareInterface {
LanguageNameUtils $languageNameUtils,
LanguageFallback $languageFallback,
HookContainer $hookContainer,
- ParserFactory $parserFactory
+ MessageParser $messageParser
) {
$this->wanCache = $wanCache;
$this->clusterCache = $clusterCache;
@@ -249,7 +229,7 @@ class MessageCache implements LoggerAwareInterface {
$this->languageNameUtils = $languageNameUtils;
$this->languageFallback = $languageFallback;
$this->hookRunner = new HookRunner( $hookContainer );
- $this->parserFactory = $parserFactory;
+ $this->messageParser = $messageParser;
// limit size
$this->cache = new MapCacheLRU( self::MAX_REQUEST_LANGUAGES );
@@ -267,34 +247,6 @@ class MessageCache implements LoggerAwareInterface {
}
/**
- * ParserOptions is lazily initialised.
- *
- * @return ParserOptions
- */
- private function getParserOptions() {
- if ( !$this->parserOptions ) {
- $context = RequestContext::getMain();
- $user = $context->getUser();
- if ( !$user->isSafeToLoad() ) {
- // It isn't safe to use the context user yet, so don't try to get a
- // ParserOptions for it. And don't cache this ParserOptions
- // either.
- $po = ParserOptions::newFromAnon();
- $po->setAllowUnsafeRawHtml( false );
- return $po;
- }
-
- $this->parserOptions = ParserOptions::newFromContext( $context );
- // Messages may take parameters that could come
- // from malicious sources. As a precaution, disable
- // the <html> parser tag when parsing messages.
- $this->parserOptions->setAllowUnsafeRawHtml( false );
- }
-
- return $this->parserOptions;
- }
-
- /**
* Try to load the cache from APC.
*
* @param string $code Optional language code, see documentation of load().
@@ -1456,6 +1408,8 @@ class MessageCache implements LoggerAwareInterface {
}
/**
+ * @deprecated since 1.44 use MessageParser::transform()
+ *
* @param string $message
* @param bool $interface
* @param Language|null $language
@@ -1463,48 +1417,14 @@ class MessageCache implements LoggerAwareInterface {
* @return string
*/
public function transform( $message, $interface = false, $language = null, ?PageReference $page = null ) {
- // Avoid creating parser if nothing to transform
- if ( !str_contains( $message, '{{' ) ) {
- return $message;
- }
-
- $popts = $this->getParserOptions();
- $popts->setInterfaceMessage( $interface );
- $popts->setTargetLanguage( $language );
-
- $userlang = $popts->setUserLang( $language );
- try {
- $this->curParser++;
- $parser = $this->getParser();
- if ( !$parser ) {
- return '<span class="error">Message transform depth limit exceeded</span>';
- }
- $message = $parser->transformMsg( $message, $popts, $page );
- } finally {
- $this->curParser--;
- }
- $popts->setUserLang( $userlang );
-
- return $message;
- }
-
- /**
- * You should increment $this->curParser before calling this method and decrement it after
- * to support recursive calls to message parsing.
- */
- private function getParser(): ?Parser {
- if ( $this->curParser >= self::MAX_PARSER_DEPTH ) {
- $this->logger->debug( __METHOD__ . ": Refusing to create a new parser with index {$this->curParser}" );
- return null;
- }
- if ( !isset( $this->parsers[ $this->curParser ] ) ) {
- $this->logger->debug( __METHOD__ . ": Creating a new parser with index {$this->curParser}" );
- $this->parsers[ $this->curParser ] = $this->parserFactory->create();
- }
- return $this->parsers[ $this->curParser ];
+ return $this->messageParser->transform(
+ $message, $interface, $language, $page );
}
/**
+ * @deprecated since 1.44 use MessageParser::parse()
+ * @internal
+ *
* @param string $text
* @param PageReference $contextPage
* @param bool $linestart Whether this should be parsed in start-of-line
@@ -1513,7 +1433,6 @@ class MessageCache implements LoggerAwareInterface {
* (defaults to false)
* @param Language|StubUserLang|string|null $language Language code
* @return ParserOutput
- * @internal
*/
public function parseWithPostprocessing(
string $text, PageReference $contextPage,
@@ -1521,48 +1440,25 @@ class MessageCache implements LoggerAwareInterface {
bool $interface = false,
$language = null
): ParserOutput {
- $options = [
- 'allowTOC' => false,
- 'enableSectionEditLinks' => false,
- // Wrapping messages in an extra <div> is probably not expected. If
- // they're outside the content area they probably shouldn't be
- // targeted by CSS that's targeting the parser output, and if
- // they're inside they already are from the outer div.
- 'unwrap' => true,
- 'userLang' => $language,
- ];
- // Parse $text to yield a ParserOutput
- $po = $this->parse( $text, $contextPage, $linestart, $interface, $language );
- if ( is_string( $po ) ) {
- $po = new ParserOutput( $po );
- }
- // Run the post-processing pipeline
- return MediaWikiServices::getInstance()->getDefaultOutputPipeline()
- ->run( $po, $this->getParserOptions(), $options );
+ return $this->messageParser->parse(
+ $text, $contextPage, $linestart, $interface, $language );
}
/**
+ * @deprecated since 1.44 use MessageParser::parseWithoutPostprocessing()
+ *
* @param string $text
* @param PageReference|null $page
* @param bool $linestart Whether this is at the start of a line
* @param bool $interface Whether this is an interface message
* @param Language|StubUserLang|string|null $language Language code
- * @return ParserOutput|string
+ * @return ParserOutput
*/
- public function parse( $text, ?PageReference $page = null, $linestart = true,
- $interface = false, $language = null
+ public function parse( $text, ?PageReference $page = null,
+ $linestart = true, $interface = false, $language = null
) {
// phpcs:ignore MediaWiki.Usage.DeprecatedGlobalVariables.Deprecated$wgTitle
global $wgTitle;
-
- $popts = $this->getParserOptions();
- $popts->setInterfaceMessage( $interface );
-
- if ( is_string( $language ) ) {
- $language = $this->langFactory->getLanguage( $language );
- }
- $popts->setTargetLanguage( $language );
-
if ( !$page ) {
$logger = LoggerFactory::getInstance( 'GlobalTitleFail' );
$logger->info(
@@ -1581,16 +1477,8 @@ class MessageCache implements LoggerAwareInterface {
);
}
- try {
- $this->curParser++;
- $parser = $this->getParser();
- if ( !$parser ) {
- return '<span class="error">Message parse depth limit exceeded</span>';
- }
- return $parser->parse( $text, $page, $popts, $linestart );
- } finally {
- $this->curParser--;
- }
+ return $this->messageParser->parseWithoutPostprocessing(
+ $text, $page, $linestart, $interface, $language );
}
public function disable() {