Merge "Simplify HTMLTitleTextField::validate"
[lhc/web/wiklou.git] / includes / parser / ParserOptions.php
index 5959281..a8da3ce 100644 (file)
@@ -41,6 +41,13 @@ use Wikimedia\ScopedCallback;
  */
 class ParserOptions {
 
+       /**
+        * Flag indicating that newCanonical() accepts an IContextSource or the string 'canonical', for
+        * back-compat checks from extensions.
+        * @since 1.32
+        */
+       const HAS_NEWCANONICAL_FROM_CONTEXT = 1;
+
        /**
         * Default values for all options that are relevant for caching.
         * @see self::getDefaults()
@@ -54,6 +61,7 @@ class ParserOptions {
         */
        private static $lazyOptions = [
                'dateformat' => [ __CLASS__, 'initDateFormat' ],
+               'speculativeRevId' => [ __CLASS__, 'initSpeculativeRevId' ],
        ];
 
        /**
@@ -659,7 +667,7 @@ class ParserOptions {
        /**
         * Get the user language used by the parser for this page and split the parser cache.
         *
-        * @warning: Calling this causes the parser cache to be fragmented by user language!
+        * @warning Calling this causes the parser cache to be fragmented by user language!
         * To avoid cache fragmentation, output should not depend on the user language.
         * Use Parser::getFunctionLang() or Parser::getTargetLanguage() instead!
         *
@@ -680,7 +688,7 @@ class ParserOptions {
        /**
         * Same as getUserLangObj() but returns a string instead.
         *
-        * @warning: Calling this causes the parser cache to be fragmented by user language!
+        * @warning Calling this causes the parser cache to be fragmented by user language!
         * To avoid cache fragmentation, output should not depend on the user language.
         * Use Parser::getFunctionLang() or Parser::getTargetLanguage() instead!
         *
@@ -824,9 +832,38 @@ class ParserOptions {
                return $this->setOptionLegacy( 'templateCallback', $x );
        }
 
+       /**
+        * A guess for {{REVISIONID}}, calculated using the callback provided via
+        * setSpeculativeRevIdCallback(). For consistency, the value will be calculated upon the
+        * first call of this method, and re-used for subsequent calls.
+        *
+        * If no callback was defined via setSpeculativeRevIdCallback(), this method will return false.
+        *
+        * @since 1.32
+        * @return int|false
+        */
+       public function getSpeculativeRevId() {
+               return $this->getOption( 'speculativeRevId' );
+       }
+
+       /**
+        * Callback registered with ParserOptions::$lazyOptions, triggered by getSpeculativeRevId().
+        *
+        * @param ParserOptions $popt
+        * @return bool|false
+        */
+       private static function initSpeculativeRevId( ParserOptions $popt ) {
+               $cb = $popt->getOption( 'speculativeRevIdCallback' );
+               $id = $cb ? $cb() : null;
+
+               // returning null would result in this being re-called every access
+               return $id ?? false;
+       }
+
        /**
         * Callback to generate a guess for {{REVISIONID}}
         * @since 1.28
+        * @deprecated since 1.32, use getSpeculativeRevId() instead!
         * @return callable|null
         */
        public function getSpeculativeRevIdCallback() {
@@ -840,6 +877,7 @@ class ParserOptions {
         * @return callable|null Old value
         */
        public function setSpeculativeRevIdCallback( $x ) {
+               $this->setOption( 'speculativeRevId', null ); // reset
                return $this->setOptionLegacy( 'speculativeRevIdCallback', $x );
        }
 
@@ -930,10 +968,9 @@ class ParserOptions {
 
        /**
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
-        * @param User $user
-        * @param Language $lang
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
+        * @param User|null $user
+        * @param Language|null $lang
         */
        public function __construct( $user = null, $lang = null ) {
                if ( $user === null ) {
@@ -957,14 +994,13 @@ class ParserOptions {
        /**
         * Get a ParserOptions object for an anonymous user
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @since 1.27
         * @return ParserOptions
         */
        public static function newFromAnon() {
-               global $wgContLang;
-               return new ParserOptions( new User, $wgContLang );
+               return new ParserOptions( new User,
+                       MediaWikiServices::getInstance()->getContentLanguage() );
        }
 
        /**
@@ -972,8 +1008,7 @@ class ParserOptions {
         * Language will be taken from $wgLang.
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param User $user
         * @return ParserOptions
         */
@@ -985,8 +1020,7 @@ class ParserOptions {
         * Get a ParserOptions object from a given user and language
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param User $user
         * @param Language $lang
         * @return ParserOptions
@@ -999,8 +1033,7 @@ class ParserOptions {
         * Get a ParserOptions object from a IContextSource object
         *
         * @warning For interaction with the parser cache, use
-        *  WikiPage::makeParserOptions(), ContentHandler::makeParserOptions(), or
-        *  ParserOptions::newCanonical() instead.
+        *  WikiPage::makeParserOptions() or ParserOptions::newCanonical() instead.
         * @param IContextSource $context
         * @return ParserOptions
         */
@@ -1015,12 +1048,29 @@ class ParserOptions {
         * different from the canonical values used for caching.
         *
         * @since 1.30
-        * @param User|null $user
-        * @param Language|StubObject|null $lang
+        * @since 1.32 Added string and IContextSource as options for the first parameter
+        * @param IContextSource|string|User|null $context
+        *  - If an IContextSource, the options are initialized based on the source's User and Language.
+        *  - If the string 'canonical', the options are initialized with an anonymous user and
+        *    the content language.
+        *  - If a User or null, the options are initialized for that User (or $wgUser if null).
+        *    'userlang' is taken from the $userLang parameter, defaulting to $wgLang if that is null.
+        * @param Language|StubObject|null $userLang (see above)
         * @return ParserOptions
         */
-       public static function newCanonical( User $user = null, $lang = null ) {
-               $ret = new ParserOptions( $user, $lang );
+       public static function newCanonical( $context = null, $userLang = null ) {
+               if ( $context instanceof IContextSource ) {
+                       $ret = self::newFromContext( $context );
+               } elseif ( $context === 'canonical' ) {
+                       $ret = self::newFromAnon();
+               } elseif ( $context instanceof User || $context === null ) {
+                       $ret = new self( $context, $userLang );
+               } else {
+                       throw new InvalidArgumentException(
+                               '$context must be an IContextSource, the string "canonical", a User, or null'
+                       );
+               }
+
                foreach ( self::getCanonicalOverrides() as $k => $v ) {
                        $ret->setOption( $k, $v );
                }
@@ -1042,7 +1092,7 @@ class ParserOptions {
                        $wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
                        $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
                        $wgMaxGeneratedPPNodeCount, $wgDisableLangConversion, $wgDisableTitleConversion,
-                       $wgEnableMagicLinks, $wgContLang;
+                       $wgEnableMagicLinks;
 
                if ( self::$defaults === null ) {
                        // *UPDATE* ParserOptions::matches() if any of this changes as needed
@@ -1062,6 +1112,7 @@ class ParserOptions {
                                'currentRevisionCallback' => [ Parser::class, 'statelessFetchRevision' ],
                                'templateCallback' => [ Parser::class, 'statelessFetchTemplate' ],
                                'speculativeRevIdCallback' => null,
+                               'speculativeRevId' => null,
                        ];
 
                        Hooks::run( 'ParserOptionsRegister', [
@@ -1096,7 +1147,7 @@ class ParserOptions {
                        'numberheadings' => User::getDefaultOption( 'numberheadings' ),
                        'thumbsize' => User::getDefaultOption( 'thumbsize' ),
                        'stubthreshold' => 0,
-                       'userlang' => $wgContLang,
+                       'userlang' => MediaWikiServices::getInstance()->getContentLanguage(),
                ];
        }
 
@@ -1271,7 +1322,7 @@ class ParserOptions {
         *
         * @since 1.17
         * @param string[] $forOptions
-        * @param Title $title Used to get the content language of the page (since r97636)
+        * @param Title|null $title Used to get the content language of the page (since r97636)
         * @return string Page rendering hash
         */
        public function optionsHash( $forOptions, $title = null ) {
@@ -1310,8 +1361,8 @@ class ParserOptions {
                if ( !is_null( $title ) ) {
                        $confstr .= $title->getPageLanguage()->getExtraHashOptions();
                } else {
-                       global $wgContLang;
-                       $confstr .= $wgContLang->getExtraHashOptions();
+                       $confstr .=
+                               MediaWikiServices::getInstance()->getContentLanguage()->getExtraHashOptions();
                }
 
                $confstr .= $wgRenderHashAppend;