parser: inject a Logger into Parser instead of using wfDebug()
[lhc/web/wiklou.git] / includes / parser / Parser.php
index 4808caf..863b5e8 100644 (file)
@@ -26,7 +26,9 @@ use MediaWiki\Linker\LinkRendererFactory;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Special\SpecialPageFactory;
+use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
+use Psr\Log\LoggerInterface;
 
 /**
  * @defgroup Parser Parser
@@ -205,9 +207,11 @@ class Parser {
        public $mLinkID;
        public $mIncludeSizes, $mPPNodeCount, $mGeneratedPPNodeCount, $mHighestExpansionDepth;
        public $mDefaultSort;
-       public $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
+       public $mTplRedirCache, $mHeadings, $mDoubleUnderscores;
        public $mExpensiveFunctionCount; # number of expensive parser function calls
        public $mShowToc, $mForceTocPosition;
+       /** @var array */
+       public $mTplDomCache;
 
        /**
         * @var User
@@ -292,6 +296,9 @@ class Parser {
        /** @var NamespaceInfo */
        private $nsInfo;
 
+       /** @var LoggerInterface */
+       private $logger;
+
        /**
         * TODO Make this a const when HHVM support is dropped (T192166)
         *
@@ -331,11 +338,18 @@ class Parser {
         * @param SpecialPageFactory|null $spFactory
         * @param LinkRendererFactory|null $linkRendererFactory
         * @param NamespaceInfo|null $nsInfo
+        * @param LoggerInterface|null $logger
         */
        public function __construct(
-               $svcOptions = null, MagicWordFactory $magicWordFactory = null,
-               Language $contLang = null, ParserFactory $factory = null, $urlProtocols = null,
-               SpecialPageFactory $spFactory = null, $linkRendererFactory = null, $nsInfo = null
+               $svcOptions = null,
+               MagicWordFactory $magicWordFactory = null,
+               Language $contLang = null,
+               ParserFactory $factory = null,
+               $urlProtocols = null,
+               SpecialPageFactory $spFactory = null,
+               $linkRendererFactory = null,
+               $nsInfo = null,
+               $logger = null
        ) {
                $services = MediaWikiServices::getInstance();
                if ( !$svcOptions || is_array( $svcOptions ) ) {
@@ -380,6 +394,7 @@ class Parser {
                $this->specialPageFactory = $spFactory ?? $services->getSpecialPageFactory();
                $this->linkRendererFactory = $linkRendererFactory ?? $services->getLinkRendererFactory();
                $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
+               $this->logger = $logger ?: new NullLogger();
        }
 
        /**
@@ -2774,8 +2789,7 @@ class Parser {
                                        # which means the user is previewing a new page.
                                        # The vary-revision flag must be set, because the magic word
                                        # will have a different value once the page is saved.
-                                       $this->mOutput->setFlag( 'vary-revision' );
-                                       wfDebug( __METHOD__ . ": {{PAGEID}} used in a new page, setting vary-revision" );
+                                       $this->setOutputFlag( 'vary-revision', '{{PAGEID}} on new page' );
                                }
                                $value = $pageid ?: null;
                                break;
@@ -2791,15 +2805,13 @@ class Parser {
                                        if ( $this->getRevisionId() || $this->mOptions->getSpeculativeRevId() ) {
                                                $value = '-';
                                        } else {
-                                               $this->mOutput->setFlag( 'vary-revision-exists' );
-                                               wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-exists" );
+                                               $this->setOutputFlag( 'vary-revision-exists', '{{REVISIONID}} used' );
                                                $value = '';
                                        }
                                } else {
                                        # Inform the edit saving system that getting the canonical output after
                                        # revision insertion requires another parse using the actual revision ID
-                                       $this->mOutput->setFlag( 'vary-revision-id' );
-                                       wfDebug( __METHOD__ . ": {{REVISIONID}} used, setting vary-revision-id" );
+                                       $this->setOutputFlag( 'vary-revision-id', '{{REVISIONID}} used' );
                                        $value = $this->getRevisionId();
                                        if ( $value === 0 ) {
                                                $rev = $this->getRevisionObject();
@@ -2834,8 +2846,7 @@ class Parser {
                        case 'revisionuser':
                                # Inform the edit saving system that getting the canonical output after
                                # revision insertion requires a parse that used the actual user ID
-                               $this->mOutput->setFlag( 'vary-user' );
-                               wfDebug( __METHOD__ . ": {{REVISIONUSER}} used, setting vary-user" );
+                               $this->setOutputFlag( 'vary-user', '{{REVISIONUSER}} used' );
                                $value = $this->getRevisionUser();
                                break;
                        case 'revisionsize':
@@ -3005,8 +3016,7 @@ class Parser {
                        if ( $resNow !== $resThen ) {
                                # Inform the edit saving system that getting the canonical output after
                                # revision insertion requires a parse that used an actual revision timestamp
-                               $this->mOutput->setFlag( 'vary-revision-timestamp' );
-                               wfDebug( __METHOD__ . ": $variable used, setting vary-revision-timestamp" );
+                               $this->setOutputFlag( 'vary-revision-timestamp', "$variable used" );
                        }
                }
 
@@ -3084,7 +3094,7 @@ class Parser {
         *  self::OT_HTML: all templates and extension tags
         *
         * @param string $text The text to transform
-        * @param bool|PPFrame $frame Object describing the arguments passed to the
+        * @param false|PPFrame|array $frame Object describing the arguments passed to the
         *   template. Arguments may also be provided as an associative array, as
         *   was the usual case before MW1.12. Providing arguments this way may be
         *   useful for extensions wishing to perform variable replacement
@@ -3103,8 +3113,10 @@ class Parser {
                if ( $frame === false ) {
                        $frame = $this->getPreprocessor()->newFrame();
                } elseif ( !( $frame instanceof PPFrame ) ) {
-                       wfDebug( __METHOD__ . " called using plain parameters instead of "
-                               . "a PPFrame instance. Creating custom frame.\n" );
+                       $this->logger->debug(
+                               __METHOD__ . " called using plain parameters instead of " .
+                               "a PPFrame instance. Creating custom frame."
+                       );
                        $frame = $this->getPreprocessor()->newCustomFrame( $frame );
                }
 
@@ -3190,7 +3202,7 @@ class Parser {
         *   $piece['lineStart']: whether the brace was at the start of a line
         * @param PPFrame $frame The current frame, contains template arguments
         * @throws Exception
-        * @return string The text of the template
+        * @return string|array The text of the template
         */
        public function braceSubstitution( $piece, $frame ) {
                // Flags
@@ -3405,8 +3417,10 @@ class Parser {
                                        }
                                } elseif ( $this->nsInfo->isNonincludable( $title->getNamespace() ) ) {
                                        $found = false; # access denied
-                                       wfDebug( __METHOD__ . ": template inclusion denied for " .
-                                               $title->getPrefixedDBkey() . "\n" );
+                                       $this->logger->debug(
+                                               __METHOD__ .
+                                               ": template inclusion denied for " . $title->getPrefixedDBkey()
+                                       );
                                } else {
                                        list( $text, $title ) = $this->getTemplateDom( $title );
                                        if ( $text !== false ) {
@@ -3444,7 +3458,7 @@ class Parser {
                                $this->addTrackingCategory( 'template-loop-category' );
                                $this->mOutput->addWarning( wfMessage( 'template-loop-warning',
                                        wfEscapeWikiText( $titleText ) )->text() );
-                               wfDebug( __METHOD__ . ": template loop broken at '$titleText'\n" );
+                               $this->logger->debug( __METHOD__ . ": template loop broken at '$titleText'" );
                        }
                }
 
@@ -3691,6 +3705,18 @@ class Parser {
                return $this->currentRevisionCache->get( $cacheKey );
        }
 
+       /**
+        * @param Title $title
+        * @return bool
+        * @since 1.34
+        */
+       public function isCurrentRevisionOfTitleCached( $title ) {
+               return (
+                       $this->currentRevisionCache &&
+                       $this->currentRevisionCache->has( $title->getPrefixedText() )
+               );
+       }
+
        /**
         * Wrapper around Revision::newFromTitle to allow passing additional parameters
         * without passing them on to it.
@@ -3725,10 +3751,8 @@ class Parser {
                        foreach ( $stuff['deps'] as $dep ) {
                                $this->mOutput->addTemplate( $dep['title'], $dep['page_id'], $dep['rev_id'] );
                                if ( $dep['title']->equals( $this->getTitle() ) ) {
-                                       // If we transclude ourselves, the final result
-                                       // will change based on the new version of the page
-                                       $this->mOutput->setFlag( 'vary-revision' );
-                                       wfDebug( __METHOD__ . ": self transclusion, setting vary-revision" );
+                                       // Self-transclusion; final result may change based on the new page version
+                                       $this->setOutputFlag( 'vary-revision', 'Self transclusion' );
                                }
                        }
                }
@@ -4672,7 +4696,7 @@ class Parser {
                                '~~~' => $sigText
                        ] );
                        # The main two signature forms used above are time-sensitive
-                       $this->mOutput->setFlag( 'user-signature' );
+                       $this->setOutputFlag( 'user-signature', 'User signature detected' );
                }
 
                # Context links ("pipe tricks"): [[|name]] and [[name (context)|]]
@@ -4737,7 +4761,7 @@ class Parser {
 
                if ( mb_strlen( $nickname ) > $this->svcOptions->get( 'MaxSigChars' ) ) {
                        $nickname = $username;
-                       wfDebug( __METHOD__ . ": $username has overlong signature.\n" );
+                       $this->logger->debug( __METHOD__ . ": $username has overlong signature." );
                } elseif ( $fancySig !== false ) {
                        # Sig. might contain markup; validate this
                        if ( $this->validateSig( $nickname ) !== false ) {
@@ -4746,7 +4770,7 @@ class Parser {
                        } else {
                                # Failed to validate; fall back to the default
                                $nickname = $username;
-                               wfDebug( __METHOD__ . ": $username has bad XML tags in signature.\n" );
+                               $this->logger->debug( __METHOD__ . ": $username has bad XML tags in signature." );
                        }
                }
 
@@ -5243,7 +5267,8 @@ class Parser {
                                                                        $handlerOptions[$paramName] = $match;
                                                                } else {
                                                                        // Guess not, consider it as caption.
-                                                                       wfDebug( "$parameterMatch failed parameter validation\n" );
+                                                                       $this->logger->debug(
+                                                                               "$parameterMatch failed parameter validation" );
                                                                        $label = $parameterMatch;
                                                                }
                                                }
@@ -5629,7 +5654,7 @@ class Parser {
         * @deprecated since 1.28; use getOutput()->updateCacheExpiry()
         */
        public function disableCache() {
-               wfDebug( "Parser output marked as uncacheable.\n" );
+               $this->logger->debug( "Parser output marked as uncacheable." );
                if ( !$this->mOutput ) {
                        throw new MWException( __METHOD__ .
                                " can only be called when actually parsing something" );
@@ -6435,4 +6460,14 @@ class Parser {
                OutputPage::setupOOUI();
                $this->mOutput->setEnableOOUI( true );
        }
+
+       /**
+        * @param string $flag
+        * @param string $reason
+        */
+       protected function setOutputFlag( $flag, $reason ) {
+               $this->mOutput->setFlag( $flag );
+               $name = $this->mTitle->getPrefixedText();
+               $this->logger->debug( __METHOD__ . ": set $flag flag on '$name'; $reason" );
+       }
 }