Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.43% covered (warning)
87.43%
320 / 366
68.52% covered (warning)
68.52%
74 / 108
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParserOptions
87.67% covered (warning)
87.67%
320 / 365
68.52% covered (warning)
68.52%
74 / 108
211.18
0.00% covered (danger)
0.00%
0 / 1
 getOption
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 lazyLoadOption
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 nullifyLazyOption
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLazyOptions
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 getCacheVaryingOptionsHash
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setOption
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 setOptionLegacy
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 getInterwikiMagic
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setInterwikiMagic
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowExternalImages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllowExternalImagesFrom
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEnableImageWhitelist
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllowSpecialInclusion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setAllowSpecialInclusion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getInterfaceMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setInterfaceMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isMessage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setIsMessage
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTargetLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTargetLanguage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMaxIncludeSize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setMaxIncludeSize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMaxPPNodeCount
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setMaxPPNodeCount
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getMaxPPExpandDepth
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMaxTemplateDepth
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setMaxTemplateDepth
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getExpensiveParserFunctionLimit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setExpensiveParserFunctionLimit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getRemoveComments
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setRemoveComments
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getEnableLimitReport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 enableLimitReport
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCleanSignatures
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setCleanSignatures
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExternalLinkTarget
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setExternalLinkTarget
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDisableContentConversion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 disableContentConversion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDisableTitleConversion
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 disableTitleConversion
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getThumbSize
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setThumbSize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIsPreview
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setIsPreview
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIsSectionPreview
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIsSectionPreview
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getIsPrintable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setIsPrintable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getPreSaveTransform
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setPreSaveTransform
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUseParsoid
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUseParsoid
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDateFormat
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 initDateFormat
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setDateFormat
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUserLangObj
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUserLang
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setUserLang
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getMagicISBNLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMagicPMIDLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMagicRFCLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSuppressTOC
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSuppressTOC
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSuppressSectionEditLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setSuppressSectionEditLinks
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCollapsibleSections
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCollapsibleSections
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAllowUnsafeRawHtml
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setAllowUnsafeRawHtml
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWrapOutputClass
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setWrapOutputClass
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getCurrentRevisionRecordCallback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCurrentRevisionRecordCallback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTemplateCallback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setTemplateCallback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSpeculativeRevId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSpeculativePageId
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 initSpeculativeRevId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 initSpeculativePageId
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setSpeculativeRevIdCallback
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setSpeculativePageIdCallback
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getTimestamp
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 setTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRedirectTarget
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRedirectTarget
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addExtraKey
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUserIdentity
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 newFromAnon
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 newFromUser
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newFromUserAndLang
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 newFromContext
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 newCanonical
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 clearStaticCache
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
2.03
 getDefaults
100.00% covered (success)
100.00%
72 / 72
100.00% covered (success)
100.00%
1 / 1
2
 initialiseFromUser
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 matches
95.83% covered (success)
95.83%
23 / 24
0.00% covered (danger)
0.00%
0 / 1
8
 matchesForCacheKey
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 registerWatcher
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 optionUsed
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 allCacheVaryingOptions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 optionToString
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
6
 optionsHash
96.67% covered (success)
96.67%
29 / 30
0.00% covered (danger)
0.00%
0 / 1
7
 isSafeToCache
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 setupFakeRevision
85.42% covered (warning)
85.42%
41 / 48
0.00% covered (danger)
0.00%
0 / 1
8.20
 getRenderReason
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setRenderReason
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Options for the PHP parser
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Parser
22 */
23
24namespace MediaWiki\Parser;
25
26use InvalidArgumentException;
27use LogicException;
28use MediaWiki\Content\Content;
29use MediaWiki\Context\IContextSource;
30use MediaWiki\HookContainer\HookRunner;
31use MediaWiki\Language\Language;
32use MediaWiki\MainConfigNames;
33use MediaWiki\MediaWikiServices;
34use MediaWiki\Page\PageIdentity;
35use MediaWiki\Page\PageIdentityValue;
36use MediaWiki\Page\PageRecord;
37use MediaWiki\Revision\MutableRevisionRecord;
38use MediaWiki\Revision\SlotRecord;
39use MediaWiki\StubObject\StubObject;
40use MediaWiki\Title\Title;
41use MediaWiki\User\UserIdentity;
42use MediaWiki\User\UserIdentityValue;
43use MediaWiki\Utils\MWTimestamp;
44use ReflectionClass;
45use Wikimedia\IPUtils;
46use Wikimedia\ScopedCallback;
47
48/**
49 * @brief Set options of the Parser
50 *
51 * How to add an option in core:
52 *  1. Add it to one of the arrays in ParserOptions::setDefaults()
53 *  2. If necessary, add an entry to ParserOptions::$inCacheKey
54 *  3. Add a getter and setter in the section for that.
55 *
56 * How to add an option in an extension:
57 *  1. Use the 'ParserOptionsRegister' hook to register it.
58 *  2. Where necessary, use $popt->getOption() and $popt->setOption()
59 *     to access it.
60 *
61 * @ingroup Parser
62 */
63class ParserOptions {
64
65    /**
66     * Default values for all options that are relevant for caching.
67     * @see self::getDefaults()
68     * @var array|null
69     */
70    private static $defaults = null;
71
72    /**
73     * Lazy-loaded options
74     * @var callable[]|null
75     */
76    private static $lazyOptions = null;
77
78    /**
79     * Initial lazy-loaded options (before hook)
80     * @var callable[]
81     */
82    private static $initialLazyOptions = [
83        'dateformat' => [ self::class, 'initDateFormat' ],
84        'speculativeRevId' => [ self::class, 'initSpeculativeRevId' ],
85        'speculativePageId' => [ self::class, 'initSpeculativePageId' ],
86    ];
87
88    /**
89     * Specify options that are included in the cache key
90     * @var array|null
91     */
92    private static $cacheVaryingOptionsHash = null;
93
94    /**
95     * Initial inCacheKey options (before hook)
96     * @var array
97     */
98    private static $initialCacheVaryingOptionsHash = [
99        'dateformat' => true,
100        'thumbsize' => true,
101        'printable' => true,
102        'userlang' => true,
103        'useParsoid' => true,
104        'suppressSectionEditLinks' => true,
105        'collapsibleSections' => true,
106    ];
107
108    /**
109     * Specify pseudo-options that are actually callbacks.
110     * These must be ignored when checking for cacheability.
111     * @var array
112     */
113    private static $callbacks = [
114        'currentRevisionRecordCallback' => true,
115        'templateCallback' => true,
116        'speculativeRevIdCallback' => true,
117        'speculativePageIdCallback' => true,
118    ];
119
120    /**
121     * Current values for all options that are relevant for caching.
122     * @var array
123     */
124    private $options;
125
126    /**
127     * Timestamp used for {{CURRENTDAY}} etc.
128     * @var string|null
129     * @note Caching based on parse time is handled externally
130     */
131    private $mTimestamp;
132
133    /**
134     * Stored user object
135     * @var UserIdentity
136     * @todo Track this for caching somehow without fragmenting the cache
137     */
138    private $mUser;
139
140    /**
141     * Function to be called when an option is accessed.
142     * @var callable|null
143     * @note Used for collecting used options, does not affect caching
144     */
145    private $onAccessCallback = null;
146
147    /**
148     * If the page being parsed is a redirect, this should hold the redirect
149     * target.
150     * @var Title|null
151     * @todo Track this for caching somehow
152     */
153    private $redirectTarget = null;
154
155    /**
156     * Appended to the options hash
157     * @var string
158     */
159    private $mExtraKey = '';
160
161    /**
162     * The reason for rendering the content.
163     * @var string
164     */
165    private $renderReason = 'unknown';
166
167    /**
168     * Fetch an option and track that is was accessed
169     * @since 1.30
170     * @param string $name Option name
171     * @return mixed
172     */
173    public function getOption( $name ) {
174        if ( !array_key_exists( $name, $this->options ) ) {
175            throw new InvalidArgumentException( "Unknown parser option $name" );
176        }
177
178        $this->lazyLoadOption( $name );
179        $this->optionUsed( $name );
180        return $this->options[$name];
181    }
182
183    /**
184     * @param string $name Lazy load option without tracking usage
185     */
186    private function lazyLoadOption( $name ) {
187        $lazyOptions = self::getLazyOptions();
188        if ( isset( $lazyOptions[$name] ) && $this->options[$name] === null ) {
189            $this->options[$name] = $lazyOptions[$name]( $this, $name );
190        }
191    }
192
193    /**
194     * Resets lazy loaded options to null in the provided $options array
195     * @param array $options
196     * @return array
197     */
198    private function nullifyLazyOption( array $options ): array {
199        return array_fill_keys( array_keys( self::getLazyOptions() ), null ) + $options;
200    }
201
202    /**
203     * Get lazy-loaded options.
204     *
205     * This array should be initialised by the constructor. The return type
206     * hint is used as an assertion to ensure this has happened and to coerce
207     * the type for static analysis.
208     *
209     * @internal Public for testing only
210     *
211     * @return array
212     */
213    public static function getLazyOptions(): array {
214        // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
215        // already been called.
216        if ( self::$lazyOptions === null ) {
217            self::getDefaults();
218        }
219        return self::$lazyOptions;
220    }
221
222    /**
223     * Get cache varying options, with the name of the option in the key, and a
224     * boolean in the value which indicates whether the cache is indeed varied.
225     *
226     * @see self::allCacheVaryingOptions()
227     *
228     * @return array
229     */
230    private static function getCacheVaryingOptionsHash(): array {
231        // Trigger a call to the 'ParserOptionsRegister' hook if it hasn't
232        // already been called.
233        if ( self::$cacheVaryingOptionsHash === null ) {
234            self::getDefaults();
235        }
236        return self::$cacheVaryingOptionsHash;
237    }
238
239    /**
240     * Set an option, generically
241     * @since 1.30
242     * @param string $name Option name
243     * @param mixed $value New value. Passing null will set null, unlike many
244     *  of the existing accessors which ignore null for historical reasons.
245     * @return mixed Old value
246     */
247    public function setOption( $name, $value ) {
248        if ( !array_key_exists( $name, $this->options ) ) {
249            throw new InvalidArgumentException( "Unknown parser option $name" );
250        }
251        $old = $this->options[$name];
252        $this->options[$name] = $value;
253        return $old;
254    }
255
256    /**
257     * Legacy implementation
258     * @since 1.30 For implementing legacy setters only. Don't use this in new code.
259     * @deprecated since 1.30
260     * @param string $name Option name
261     * @param mixed $value New value. Passing null does not set the value.
262     * @return mixed Old value
263     */
264    protected function setOptionLegacy( $name, $value ) {
265        if ( !array_key_exists( $name, $this->options ) ) {
266            throw new InvalidArgumentException( "Unknown parser option $name" );
267        }
268        return wfSetVar( $this->options[$name], $value );
269    }
270
271    /**
272     * Whether to extract interlanguage links
273     *
274     * When true, interlanguage links will be returned by
275     * ParserOutput::getLanguageLinks() instead of generating link HTML.
276     *
277     * @return bool
278     */
279    public function getInterwikiMagic() {
280        return $this->getOption( 'interwikiMagic' );
281    }
282
283    /**
284     * Specify whether to extract interlanguage links
285     * @param bool|null $x New value (null is no change)
286     * @return bool Old value
287     */
288    public function setInterwikiMagic( $x ) {
289        return $this->setOptionLegacy( 'interwikiMagic', $x );
290    }
291
292    /**
293     * Allow all external images inline?
294     * @return bool
295     */
296    public function getAllowExternalImages() {
297        return $this->getOption( 'allowExternalImages' );
298    }
299
300    /**
301     * External images to allow
302     *
303     * When self::getAllowExternalImages() is false
304     *
305     * @return string|string[] URLs to allow
306     */
307    public function getAllowExternalImagesFrom() {
308        return $this->getOption( 'allowExternalImagesFrom' );
309    }
310
311    /**
312     * Use the on-wiki external image whitelist?
313     * @return bool
314     */
315    public function getEnableImageWhitelist() {
316        return $this->getOption( 'enableImageWhitelist' );
317    }
318
319    /**
320     * Allow inclusion of special pages?
321     * @return bool
322     */
323    public function getAllowSpecialInclusion() {
324        return $this->getOption( 'allowSpecialInclusion' );
325    }
326
327    /**
328     * Allow inclusion of special pages?
329     * @param bool|null $x New value (null is no change)
330     * @return bool Old value
331     */
332    public function setAllowSpecialInclusion( $x ) {
333        return $this->setOptionLegacy( 'allowSpecialInclusion', $x );
334    }
335
336    /**
337     * Parsing an interface message in the user language?
338     *
339     * Note: use isMessage() to determine if we are parsing a message in any language.
340     *
341     * @return bool
342     */
343    public function getInterfaceMessage() {
344        return $this->getOption( 'interfaceMessage' );
345    }
346
347    /**
348     * Parsing an interface message in the user language?
349     * @param bool|null $x New value (null is no change)
350     * @return bool Old value
351     */
352    public function setInterfaceMessage( $x ) {
353        return $this->setOptionLegacy( 'interfaceMessage', $x );
354    }
355
356    /**
357     * Parsing a message?
358     *
359     * @since 1.45
360     * @return bool
361     */
362    public function isMessage() {
363        return $this->getOption( 'isMessage' );
364    }
365
366    /**
367     * Set whether we are parsing a message
368     *
369     * @since 1.45
370     * @param bool $x
371     * @return bool
372     */
373    public function setIsMessage( $x ) {
374        return $this->setOption( 'isMessage', $x );
375    }
376
377    /**
378     * Target language for the parse
379     * @return Language|null
380     */
381    public function getTargetLanguage() {