Merge "Document that img_description_id is a comment id"
[lhc/web/wiklou.git] / includes / parser / Parser.php
index e5bf94a..a19f86c 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Parser
  */
+use MediaWiki\BadFileLookup;
 use MediaWiki\Config\ServiceOptions;
 use MediaWiki\Linker\LinkRenderer;
 use MediaWiki\Linker\LinkRendererFactory;
@@ -299,6 +300,9 @@ class Parser {
        /** @var LoggerInterface */
        private $logger;
 
+       /** @var BadFileLookup */
+       private $badFileLookup;
+
        /**
         * TODO Make this a const when HHVM support is dropped (T192166)
         *
@@ -339,6 +343,7 @@ class Parser {
         * @param LinkRendererFactory|null $linkRendererFactory
         * @param NamespaceInfo|null $nsInfo
         * @param LoggerInterface|null $logger
+        * @param BadFileLookup|null $badFileLookup
         */
        public function __construct(
                $svcOptions = null,
@@ -349,9 +354,9 @@ class Parser {
                SpecialPageFactory $spFactory = null,
                $linkRendererFactory = null,
                $nsInfo = null,
-               $logger = null
+               $logger = null,
+               BadFileLookup $badFileLookup = null
        ) {
-               $services = MediaWikiServices::getInstance();
                if ( !$svcOptions || is_array( $svcOptions ) ) {
                        // Pre-1.34 calling convention is the first parameter is just ParserConf, the seventh is
                        // Config, and the eighth is LinkRendererFactory.
@@ -363,8 +368,8 @@ class Parser {
                                $this->mConf['preprocessorClass'] = self::getDefaultPreprocessorClass();
                        }
                        $this->svcOptions = new ServiceOptions( self::$constructorOptions,
-                               $this->mConf,
-                               func_num_args() > 6 ? func_get_arg( 6 ) : $services->getMainConfig()
+                               $this->mConf, func_num_args() > 6
+                                       ? func_get_arg( 6 ) : MediaWikiServices::getInstance()->getMainConfig()
                        );
                        $linkRendererFactory = func_num_args() > 7 ? func_get_arg( 7 ) : null;
                        $nsInfo = func_num_args() > 8 ? func_get_arg( 8 ) : null;
@@ -386,15 +391,19 @@ class Parser {
                        self::EXT_LINK_URL_CLASS . '*)\p{Zs}*([^\]\\x00-\\x08\\x0a-\\x1F\\x{FFFD}]*?)\]/Su';
 
                $this->magicWordFactory = $magicWordFactory ??
-                       $services->getMagicWordFactory();
+                       MediaWikiServices::getInstance()->getMagicWordFactory();
 
-               $this->contLang = $contLang ?? $services->getContentLanguage();
+               $this->contLang = $contLang ?? MediaWikiServices::getInstance()->getContentLanguage();
 
-               $this->factory = $factory ?? $services->getParserFactory();
-               $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
-               $this->linkRendererFactory = $linkRendererFactory ?? $services->getLinkRendererFactory();
-               $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
+               $this->factory = $factory ?? MediaWikiServices::getInstance()->getParserFactory();
+               $this->specialPageFactory = $spFactory ??
+                       MediaWikiServices::getInstance()->getSpecialPageFactory();
+               $this->linkRendererFactory = $linkRendererFactory ??
+                       MediaWikiServices::getInstance()->getLinkRendererFactory();
+               $this->nsInfo = $nsInfo ?? MediaWikiServices::getInstance()->getNamespaceInfo();
                $this->logger = $logger ?: new NullLogger();
+               $this->badFileLookup = $badFileLookup ??
+                       MediaWikiServices::getInstance()->getBadFileLookup();
        }
 
        /**
@@ -468,8 +477,7 @@ class Parser {
         */
        public function clearState() {
                $this->firstCallInit();
-               $this->mOutput = new ParserOutput;
-               $this->mOptions->registerWatcher( [ $this->mOutput, 'recordOption' ] );
+               $this->resetOutput();
                $this->mAutonumber = 0;
                $this->mIncludeCount = [];
                $this->mLinkHolders = new LinkHolderArray( $this );
@@ -512,6 +520,14 @@ class Parser {
                Hooks::run( 'ParserClearState', [ &$parser ] );
        }
 
+       /**
+        * Reset the ParserOutput
+        */
+       public function resetOutput() {
+               $this->mOutput = new ParserOutput;
+               $this->mOptions->registerWatcher( [ $this->mOutput, 'recordOption' ] );
+       }
+
        /**
         * Convert wikitext to HTML
         * Do not call this function recursively.
@@ -522,7 +538,10 @@ class Parser {
         * @param ParserOptions $options
         * @param bool $linestart
         * @param bool $clearState
-        * @param int|null $revid Number to pass in {{REVISIONID}}
+        * @param int|null $revid ID of the revision being rendered. This is used to render
+        *  REVISION* magic words. 0 means that any current revision will be used. Null means
+        *  that {{REVISIONID}}/{{REVISIONUSER}} will be empty and {{REVISIONTIMESTAMP}} will
+        *  use the current timestamp.
         * @return ParserOutput A ParserOutput
         * @return-taint escaped
         */
@@ -1177,6 +1196,15 @@ class Parser {
                return $this->mStripList;
        }
 
+       /**
+        * Get the StripState
+        *
+        * @return StripState
+        */
+       public function getStripState() {
+               return $this->mStripState;
+       }
+
        /**
         * Add an item to the strip state
         * Returns the unique tag which must be inserted into the stripped text
@@ -2481,7 +2509,7 @@ class Parser {
                                }
 
                                if ( $ns == NS_FILE ) {
-                                       if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) {
+                                       if ( !$this->badFileLookup->isBadFile( $nt->getDBkey(), $this->mTitle ) ) {
                                                if ( $wasblank ) {
                                                        # if no parameters were passed, $text
                                                        # becomes something like "File:Foo.png",
@@ -3742,21 +3770,22 @@ class Parser {
                // Defaults to Parser::statelessFetchTemplate()
                $templateCb = $this->mOptions->getTemplateCallback();
                $stuff = call_user_func( $templateCb, $title, $this );
-               // We use U+007F DELETE to distinguish strip markers from regular text.
+               $rev = $stuff['revision'] ?? null;
                $text = $stuff['text'];
                if ( is_string( $stuff['text'] ) ) {
+                       // We use U+007F DELETE to distinguish strip markers from regular text
                        $text = strtr( $text, "\x7f", "?" );
                }
                $finalTitle = $stuff['finalTitle'] ?? $title;
-               if ( isset( $stuff['deps'] ) ) {
-                       foreach ( $stuff['deps'] as $dep ) {
-                               $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
-                               if ( $dep['title']->equals( $this->getTitle() ) ) {
-                                       // Self-transclusion; final result may change based on the new page version
-                                       $this->setOutputFlag( 'vary-revision', 'Self transclusion' );
-                               }
+               foreach ( ( $stuff['deps'] ?? [] ) as $dep ) {
+                       $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
+                       if ( $dep['title']->equals( $this->getTitle() ) && $rev instanceof Revision ) {
+                               // Self-transclusion; final result may change based on the new page version
+                               $this->setOutputFlag( 'vary-revision-sha1', 'Self transclusion' );
+                               $this->getOutput()->setRevisionUsedSha1Base36( $rev->getSha1() );
                        }
                }
+
                return [ $text, $finalTitle ];
        }
 
@@ -3782,6 +3811,7 @@ class Parser {
                $text = $skip = false;
                $finalTitle = $title;
                $deps = [];
+               $rev = null;
 
                # Loop to fetch the article, with up to 1 redirect
                for ( $i = 0; $i < 2 && is_object( $title ); $i++ ) {
@@ -3817,13 +3847,15 @@ class Parser {
                        $deps[] = [
                                'title' => $title,
                                'page_id' => $title->getArticleID(),
-                               'rev_id' => $rev_id ];
+                               'rev_id' => $rev_id
+                       ];
                        if ( $rev && !$title->equals( $rev->getTitle() ) ) {
                                # We fetched a rev from a different title; register it too...
                                $deps[] = [
                                        'title' => $rev->getTitle(),
                                        'page_id' => $rev->getPage(),
-                                       'rev_id' => $rev_id ];
+                                       'rev_id' => $rev_id
+                               ];
                        }
 
                        if ( $rev ) {
@@ -3857,9 +3889,11 @@ class Parser {
                        $title = $content->getRedirectTarget();
                }
                return [
+                       'revision' => $rev,
                        'text' => $text,
                        'finalTitle' => $finalTitle,
-                       'deps' => $deps ];
+                       'deps' => $deps
+               ];
        }
 
        /**
@@ -4857,11 +4891,15 @@ class Parser {
         * @param ParserOptions $options
         * @param int $outputType
         * @param bool $clearState
+        * @param int|null $revId
         */
        public function startExternalParse( Title $title = null, ParserOptions $options,
-               $outputType, $clearState = true
+               $outputType, $clearState = true, $revId = null
        ) {
                $this->startParse( $title, $options, $outputType, $clearState );
+               if ( $revId !== null ) {
+                       $this->mRevisionId = $revId;
+               }
        }
 
        /**