Merge "RCFilters: display timestamp of new changes in refresh link"
[lhc/web/wiklou.git] / includes / content / WikitextContent.php
index a7021b1..455eb0d 100644 (file)
@@ -25,6 +25,7 @@
  * @author Daniel Kinzler
  */
 
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -41,6 +42,11 @@ class WikitextContent extends TextContent {
         */
        private $hadSignature = false;
 
+       /**
+        * @var array|null Stack trace of the previous parse
+        */
+       private $previousParseStackTrace = null;
+
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
        }
@@ -53,10 +59,9 @@ class WikitextContent extends TextContent {
         * @see Content::getSection()
         */
        public function getSection( $sectionId ) {
-               global $wgParser;
-
-               $text = $this->getNativeData();
-               $sect = $wgParser->getSection( $text, $sectionId, false );
+               $text = $this->getText();
+               $sect = MediaWikiServices::getInstance()->getParser()
+                       ->getSection( $text, $sectionId, false );
 
                if ( $sect === false ) {
                        return false;
@@ -85,8 +90,8 @@ class WikitextContent extends TextContent {
                                "section uses $sectionModelId." );
                }
 
-               $oldtext = $this->getNativeData();
-               $text = $with->getNativeData();
+               $oldtext = $this->getText();
+               $text = $with->getText();
 
                if ( strval( $sectionId ) === '' ) {
                        return $with; # XXX: copy first?
@@ -103,9 +108,8 @@ class WikitextContent extends TextContent {
                        }
                } else {
                        # Replacing an existing section; roll out the big guns
-                       global $wgParser;
-
-                       $text = $wgParser->replaceSection( $oldtext, $sectionId, $text );
+                       $text = MediaWikiServices::getInstance()->getParser()
+                               ->replaceSection( $oldtext, $sectionId, $text );
                }
 
                $newContent = new static( $text );
@@ -125,7 +129,7 @@ class WikitextContent extends TextContent {
                $text = wfMessage( 'newsectionheaderdefaultlevel' )
                        ->rawParams( $header )->inContentLanguage()->text();
                $text .= "\n\n";
-               $text .= $this->getNativeData();
+               $text .= $this->getText();
 
                return new static( $text );
        }
@@ -141,10 +145,10 @@ class WikitextContent extends TextContent {
         * @return Content
         */
        public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
-               global $wgParser;
+               $text = $this->getText();
 
-               $text = $this->getNativeData();
-               $pst = $wgParser->preSaveTransform( $text, $title, $user, $popts );
+               $parser = MediaWikiServices::getInstance()->getParser();
+               $pst = $parser->preSaveTransform( $text, $title, $user, $popts );
 
                if ( $text === $pst ) {
                        return $this;
@@ -152,7 +156,7 @@ class WikitextContent extends TextContent {
 
                $ret = new static( $pst );
 
-               if ( $wgParser->getOutput()->getFlag( 'user-signature' ) ) {
+               if ( $parser->getOutput()->getFlag( 'user-signature' ) ) {
                        $ret->hadSignature = true;
                }
 
@@ -170,10 +174,9 @@ class WikitextContent extends TextContent {
         * @return Content
         */
        public function preloadTransform( Title $title, ParserOptions $popts, $params = [] ) {
-               global $wgParser;
-
-               $text = $this->getNativeData();
-               $plt = $wgParser->getPreloadText( $text, $title, $popts, $params );
+               $text = $this->getText();
+               $plt = MediaWikiServices::getInstance()->getParser()
+                       ->getPreloadText( $text, $title, $popts, $params );
 
                return new static( $plt );
        }
@@ -196,12 +199,12 @@ class WikitextContent extends TextContent {
 
                if ( $wgMaxRedirects < 1 ) {
                        // redirects are disabled, so quit early
-                       $this->redirectTargetAndText = [ null, $this->getNativeData() ];
+                       $this->redirectTargetAndText = [ null, $this->getText() ];
                        return $this->redirectTargetAndText;
                }
 
                $redir = MediaWikiServices::getInstance()->getMagicWordFactory()->get( 'redirect' );
-               $text = ltrim( $this->getNativeData() );
+               $text = ltrim( $this->getText() );
                if ( $redir->matchStartAndRemove( $text ) ) {
                        // Extract the first link and see if it's usable
                        // Ensure that it really does come directly after #REDIRECT
@@ -217,7 +220,7 @@ class WikitextContent extends TextContent {
                                $title = Title::newFromText( $m[1] );
                                // If the title is a redirect to bad special pages or is invalid, return null
                                if ( !$title instanceof Title || !$title->isValidRedirectTarget() ) {
-                                       $this->redirectTargetAndText = [ null, $this->getNativeData() ];
+                                       $this->redirectTargetAndText = [ null, $this->getText() ];
                                        return $this->redirectTargetAndText;
                                }
 
@@ -226,7 +229,7 @@ class WikitextContent extends TextContent {
                        }
                }
 
-               $this->redirectTargetAndText = [ null, $this->getNativeData() ];
+               $this->redirectTargetAndText = [ null, $this->getText() ];
                return $this->redirectTargetAndText;
        }
 
@@ -265,7 +268,7 @@ class WikitextContent extends TextContent {
                # so the regex has to be fairly general
                $newText = preg_replace( '/ \[ \[  [^\]]*  \] \] /x',
                        '[[' . $target->getFullText() . ']]',
-                       $this->getNativeData(), 1 );
+                       $this->getText(), 1 );
 
                return new static( $newText );
        }
@@ -323,7 +326,7 @@ class WikitextContent extends TextContent {
 
        /**
         * Returns a ParserOutput object resulting from parsing the content's text
-        * using $wgParser.
+        * using the global Parser service.
         *
         * @param Title $title
         * @param int $revId Revision to pass to the parser (default: null)
@@ -335,10 +338,31 @@ class WikitextContent extends TextContent {
        protected function fillParserOutput( Title $title, $revId,
                        ParserOptions $options, $generateHtml, ParserOutput &$output
        ) {
-               global $wgParser;
+               $stackTrace = ( new RuntimeException() )->getTraceAsString();
+               if ( $this->previousParseStackTrace ) {
+                       // NOTE: there may be legitimate changes to re-parse the same WikiText content,
+                       // e.g. if predicted revision ID for the REVISIONID magic word mismatched.
+                       // But that should be rare.
+                       $logger = LoggerFactory::getInstance( 'DuplicateParse' );
+                       $logger->debug(
+                               __METHOD__ . ': Possibly redundant parse!',
+                               [
+                                       'title' => $title->getPrefixedDBkey(),
+                                       'rev' => $revId,
+                                       'options-hash' => $options->optionsHash(
+                                               ParserOptions::allCacheVaryingOptions(),
+                                               $title
+                                       ),
+                                       'trace' => $stackTrace,
+                                       'previous-trace' => $this->previousParseStackTrace,
+                               ]
+                       );
+               }
+               $this->previousParseStackTrace = $stackTrace;
 
                list( $redir, $text ) = $this->getRedirectTargetAndText();
-               $output = $wgParser->parse( $text, $title, $options, true, true, $revId );
+               $output = MediaWikiServices::getInstance()->getParser()
+                       ->parse( $text, $title, $options, true, true, $revId );
 
                // Add redirect indicator at the top
                if ( $redir ) {
@@ -380,7 +404,7 @@ class WikitextContent extends TextContent {
         * @see Content::matchMagicWord()
         */
        public function matchMagicWord( MagicWord $word ) {
-               return $word->match( $this->getNativeData() );
+               return $word->match( $this->getText() );
        }
 
 }