Merge "Localisation updates from https://translatewiki.net."
[mediawiki.git] / includes / parser / ParserOptions.php
blob2ca9d505bbc083d98a54daa044715684c2e40cca
1 <?php
2 /**
3 * Options for the PHP parser
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.
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.
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
20 * @file
21 * @ingroup Parser
24 /**
25 * @brief Set options of the Parser
27 * All member variables are supposed to be private in theory, although in
28 * practise this is not the case.
30 * @ingroup Parser
32 class ParserOptions {
34 /**
35 * Interlanguage links are removed and returned in an array
37 public $mInterwikiMagic;
39 /**
40 * Allow external images inline?
42 public $mAllowExternalImages;
44 /**
45 * If not, any exception?
47 public $mAllowExternalImagesFrom;
49 /**
50 * If not or it doesn't match, should we check an on-wiki whitelist?
52 public $mEnableImageWhitelist;
54 /**
55 * Date format index
57 public $mDateFormat = null;
59 /**
60 * Create "edit section" links?
62 public $mEditSection = true;
64 /**
65 * Allow inclusion of special pages?
67 public $mAllowSpecialInclusion;
69 /**
70 * Use tidy to cleanup output HTML?
72 public $mTidy = false;
74 /**
75 * Which lang to call for PLURAL and GRAMMAR
77 public $mInterfaceMessage = false;
79 /**
80 * Overrides $mInterfaceMessage with arbitrary language
82 public $mTargetLanguage = null;
84 /**
85 * Maximum size of template expansions, in bytes
87 public $mMaxIncludeSize;
89 /**
90 * Maximum number of nodes touched by PPFrame::expand()
92 public $mMaxPPNodeCount;
94 /**
95 * Maximum number of nodes generated by Preprocessor::preprocessToObj()
97 public $mMaxGeneratedPPNodeCount;
99 /**
100 * Maximum recursion depth in PPFrame::expand()
102 public $mMaxPPExpandDepth;
105 * Maximum recursion depth for templates within templates
107 public $mMaxTemplateDepth;
110 * Maximum number of calls per parse to expensive parser functions
112 public $mExpensiveParserFunctionLimit;
115 * Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS
117 public $mRemoveComments = true;
120 * Callback for template fetching. Used as first argument to call_user_func().
122 public $mTemplateCallback =
123 array( 'Parser', 'statelessFetchTemplate' );
126 * Enable limit report in an HTML comment on output
128 public $mEnableLimitReport = false;
131 * Timestamp used for {{CURRENTDAY}} etc.
133 public $mTimestamp;
136 * Target attribute for external links
138 public $mExternalLinkTarget;
141 * Clean up signature texts?
143 * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures
144 * 2) Substitute all transclusions
146 public $mCleanSignatures;
149 * Transform wiki markup when saving the page?
151 public $mPreSaveTransform = true;
154 * Whether content conversion should be disabled
156 public $mDisableContentConversion;
159 * Whether title conversion should be disabled
161 public $mDisableTitleConversion;
164 * Automatically number headings?
166 public $mNumberHeadings;
169 * Thumb size preferred by the user.
171 public $mThumbSize;
174 * Maximum article size of an article to be marked as "stub"
176 private $mStubThreshold;
179 * Language object of the User language.
181 public $mUserLang;
184 * @var User
185 * Stored user object
187 public $mUser;
190 * Parsing the page for a "preview" operation?
192 public $mIsPreview = false;
195 * Parsing the page for a "preview" operation on a single section?
197 public $mIsSectionPreview = false;
200 * Parsing the printable version of the page?
202 public $mIsPrintable = false;
205 * Extra key that should be present in the caching key.
207 public $mExtraKey = '';
210 * Function to be called when an option is accessed.
212 protected $onAccessCallback = null;
214 public function getInterwikiMagic() {
215 return $this->mInterwikiMagic;
218 public function getAllowExternalImages() {
219 return $this->mAllowExternalImages;
222 public function getAllowExternalImagesFrom() {
223 return $this->mAllowExternalImagesFrom;
226 public function getEnableImageWhitelist() {
227 return $this->mEnableImageWhitelist;
230 public function getEditSection() {
231 return $this->mEditSection;
234 public function getNumberHeadings() {
235 $this->optionUsed( 'numberheadings' );
237 return $this->mNumberHeadings;
240 public function getAllowSpecialInclusion() {
241 return $this->mAllowSpecialInclusion;
244 public function getTidy() {
245 return $this->mTidy;
248 public function getInterfaceMessage() {
249 return $this->mInterfaceMessage;
252 public function getTargetLanguage() {
253 return $this->mTargetLanguage;
256 public function getMaxIncludeSize() {
257 return $this->mMaxIncludeSize;
260 public function getMaxPPNodeCount() {
261 return $this->mMaxPPNodeCount;
264 public function getMaxGeneratedPPNodeCount() {
265 return $this->mMaxGeneratedPPNodeCount;
268 public function getMaxPPExpandDepth() {
269 return $this->mMaxPPExpandDepth;
272 public function getMaxTemplateDepth() {
273 return $this->mMaxTemplateDepth;
276 /* @since 1.20 */
277 public function getExpensiveParserFunctionLimit() {
278 return $this->mExpensiveParserFunctionLimit;
281 public function getRemoveComments() {
282 return $this->mRemoveComments;
285 public function getTemplateCallback() {
286 return $this->mTemplateCallback;
289 public function getEnableLimitReport() {
290 return $this->mEnableLimitReport;
293 public function getCleanSignatures() {
294 return $this->mCleanSignatures;
297 public function getExternalLinkTarget() {
298 return $this->mExternalLinkTarget;
301 public function getDisableContentConversion() {
302 return $this->mDisableContentConversion;
305 public function getDisableTitleConversion() {
306 return $this->mDisableTitleConversion;
309 public function getThumbSize() {
310 $this->optionUsed( 'thumbsize' );
312 return $this->mThumbSize;
315 public function getStubThreshold() {
316 $this->optionUsed( 'stubthreshold' );
318 return $this->mStubThreshold;
321 public function getIsPreview() {
322 return $this->mIsPreview;
325 public function getIsSectionPreview() {
326 return $this->mIsSectionPreview;
329 public function getIsPrintable() {
330 $this->optionUsed( 'printable' );
332 return $this->mIsPrintable;
335 public function getUser() {
336 return $this->mUser;
339 public function getPreSaveTransform() {
340 return $this->mPreSaveTransform;
343 public function getDateFormat() {
344 $this->optionUsed( 'dateformat' );
345 if ( !isset( $this->mDateFormat ) ) {
346 $this->mDateFormat = $this->mUser->getDatePreference();
348 return $this->mDateFormat;
351 public function getTimestamp() {
352 if ( !isset( $this->mTimestamp ) ) {
353 $this->mTimestamp = wfTimestampNow();
355 return $this->mTimestamp;
359 * Get the user language used by the parser for this page.
361 * You shouldn't use this. Really. $parser->getFunctionLang() is all you need.
363 * To avoid side-effects where the page will be rendered based on the language
364 * of the user who last saved, this function will triger a cache fragmentation.
365 * Usage of this method is discouraged for that reason.
367 * When saving, this will return the default language instead of the user's.
369 * {{int: }} uses this which used to produce inconsistent link tables (bug 14404).
371 * @return Language
372 * @since 1.19
374 public function getUserLangObj() {
375 $this->optionUsed( 'userlang' );
376 return $this->mUserLang;
380 * Same as getUserLangObj() but returns a string instead.
382 * @return string Language code
383 * @since 1.17
385 public function getUserLang() {
386 return $this->getUserLangObj()->getCode();
389 public function setInterwikiMagic( $x ) {
390 return wfSetVar( $this->mInterwikiMagic, $x );
393 public function setAllowExternalImages( $x ) {
394 return wfSetVar( $this->mAllowExternalImages, $x );
397 public function setAllowExternalImagesFrom( $x ) {
398 return wfSetVar( $this->mAllowExternalImagesFrom, $x );
401 public function setEnableImageWhitelist( $x ) {
402 return wfSetVar( $this->mEnableImageWhitelist, $x );
405 public function setDateFormat( $x ) {
406 return wfSetVar( $this->mDateFormat, $x );
409 public function setEditSection( $x ) {
410 return wfSetVar( $this->mEditSection, $x );
413 public function setNumberHeadings( $x ) {
414 return wfSetVar( $this->mNumberHeadings, $x );
417 public function setAllowSpecialInclusion( $x ) {
418 return wfSetVar( $this->mAllowSpecialInclusion, $x );
421 public function setTidy( $x ) {
422 return wfSetVar( $this->mTidy, $x );
425 public function setInterfaceMessage( $x ) {
426 return wfSetVar( $this->mInterfaceMessage, $x );
429 public function setTargetLanguage( $x ) {
430 return wfSetVar( $this->mTargetLanguage, $x, true );
433 public function setMaxIncludeSize( $x ) {
434 return wfSetVar( $this->mMaxIncludeSize, $x );
437 public function setMaxPPNodeCount( $x ) {
438 return wfSetVar( $this->mMaxPPNodeCount, $x );
441 public function setMaxGeneratedPPNodeCount( $x ) {
442 return wfSetVar( $this->mMaxGeneratedPPNodeCount, $x );
445 public function setMaxTemplateDepth( $x ) {
446 return wfSetVar( $this->mMaxTemplateDepth, $x );
449 /* @since 1.20 */
450 public function setExpensiveParserFunctionLimit( $x ) {
451 return wfSetVar( $this->mExpensiveParserFunctionLimit, $x );
454 public function setRemoveComments( $x ) {
455 return wfSetVar( $this->mRemoveComments, $x );
458 public function setTemplateCallback( $x ) {
459 return wfSetVar( $this->mTemplateCallback, $x );
462 public function enableLimitReport( $x = true ) {
463 return wfSetVar( $this->mEnableLimitReport, $x );
466 public function setTimestamp( $x ) {
467 return wfSetVar( $this->mTimestamp, $x );
470 public function setCleanSignatures( $x ) {
471 return wfSetVar( $this->mCleanSignatures, $x );
474 public function setExternalLinkTarget( $x ) {
475 return wfSetVar( $this->mExternalLinkTarget, $x );
478 public function disableContentConversion( $x = true ) {
479 return wfSetVar( $this->mDisableContentConversion, $x );
482 public function disableTitleConversion( $x = true ) {
483 return wfSetVar( $this->mDisableTitleConversion, $x );
486 public function setUserLang( $x ) {
487 if ( is_string( $x ) ) {
488 $x = Language::factory( $x );
491 return wfSetVar( $this->mUserLang, $x );
494 public function setThumbSize( $x ) {
495 return wfSetVar( $this->mThumbSize, $x );
498 public function setStubThreshold( $x ) {
499 return wfSetVar( $this->mStubThreshold, $x );
502 public function setPreSaveTransform( $x ) {
503 return wfSetVar( $this->mPreSaveTransform, $x );
506 public function setIsPreview( $x ) {
507 return wfSetVar( $this->mIsPreview, $x );
510 public function setIsSectionPreview( $x ) {
511 return wfSetVar( $this->mIsSectionPreview, $x );
514 public function setIsPrintable( $x ) {
515 return wfSetVar( $this->mIsPrintable, $x );
519 * Extra key that should be present in the parser cache key.
520 * @param string $key
522 public function addExtraKey( $key ) {
523 $this->mExtraKey .= '!' . $key;
527 * Constructor
528 * @param User $user
529 * @param Language $lang
531 public function __construct( $user = null, $lang = null ) {
532 if ( $user === null ) {
533 global $wgUser;
534 if ( $wgUser === null ) {
535 $user = new User;
536 } else {
537 $user = $wgUser;
540 if ( $lang === null ) {
541 global $wgLang;
542 if ( !StubObject::isRealObject( $wgLang ) ) {
543 $wgLang->_unstub();
545 $lang = $wgLang;
547 $this->initialiseFromUser( $user, $lang );
551 * Get a ParserOptions object from a given user.
552 * Language will be taken from $wgLang.
554 * @param User $user
555 * @return ParserOptions
557 public static function newFromUser( $user ) {
558 return new ParserOptions( $user );
562 * Get a ParserOptions object from a given user and language
564 * @param User $user
565 * @param Language $lang
566 * @return ParserOptions
568 public static function newFromUserAndLang( User $user, Language $lang ) {
569 return new ParserOptions( $user, $lang );
573 * Get a ParserOptions object from a IContextSource object
575 * @param IContextSource $context
576 * @return ParserOptions
578 public static function newFromContext( IContextSource $context ) {
579 return new ParserOptions( $context->getUser(), $context->getLanguage() );
583 * Get user options
585 * @param User $user
586 * @param Language $lang
588 private function initialiseFromUser( $user, $lang ) {
589 global $wgInterwikiMagic, $wgAllowExternalImages,
590 $wgAllowExternalImagesFrom, $wgEnableImageWhitelist, $wgAllowSpecialInclusion,
591 $wgMaxArticleSize, $wgMaxPPNodeCount, $wgMaxTemplateDepth, $wgMaxPPExpandDepth,
592 $wgCleanSignatures, $wgExternalLinkTarget, $wgExpensiveParserFunctionLimit,
593 $wgMaxGeneratedPPNodeCount, $wgDisableLangConversion, $wgDisableTitleConversion;
595 wfProfileIn( __METHOD__ );
597 $this->mInterwikiMagic = $wgInterwikiMagic;
598 $this->mAllowExternalImages = $wgAllowExternalImages;
599 $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
600 $this->mEnableImageWhitelist = $wgEnableImageWhitelist;
601 $this->mAllowSpecialInclusion = $wgAllowSpecialInclusion;
602 $this->mMaxIncludeSize = $wgMaxArticleSize * 1024;
603 $this->mMaxPPNodeCount = $wgMaxPPNodeCount;
604 $this->mMaxGeneratedPPNodeCount = $wgMaxGeneratedPPNodeCount;
605 $this->mMaxPPExpandDepth = $wgMaxPPExpandDepth;
606 $this->mMaxTemplateDepth = $wgMaxTemplateDepth;
607 $this->mExpensiveParserFunctionLimit = $wgExpensiveParserFunctionLimit;
608 $this->mCleanSignatures = $wgCleanSignatures;
609 $this->mExternalLinkTarget = $wgExternalLinkTarget;
610 $this->mDisableContentConversion = $wgDisableLangConversion;
611 $this->mDisableTitleConversion = $wgDisableLangConversion || $wgDisableTitleConversion;
613 $this->mUser = $user;
614 $this->mNumberHeadings = $user->getOption( 'numberheadings' );
615 $this->mThumbSize = $user->getOption( 'thumbsize' );
616 $this->mStubThreshold = $user->getStubThreshold();
617 $this->mUserLang = $lang;
619 wfProfileOut( __METHOD__ );
623 * Registers a callback for tracking which ParserOptions which are used.
624 * This is a private API with the parser.
625 * @param callable $callback
627 public function registerWatcher( $callback ) {
628 $this->onAccessCallback = $callback;
632 * Called when an option is accessed.
633 * @param string $optionName Name of the option
635 public function optionUsed( $optionName ) {
636 if ( $this->onAccessCallback ) {
637 call_user_func( $this->onAccessCallback, $optionName );
642 * Returns the full array of options that would have been used by
643 * in 1.16.
644 * Used to get the old parser cache entries when available.
645 * @return array
647 public static function legacyOptions() {
648 return array(
649 'stubthreshold',
650 'numberheadings',
651 'userlang',
652 'thumbsize',
653 'editsection',
654 'printable'
659 * Generate a hash string with the values set on these ParserOptions
660 * for the keys given in the array.
661 * This will be used as part of the hash key for the parser cache,
662 * so users sharing the options with vary for the same page share
663 * the same cached data safely.
665 * Extensions which require it should install 'PageRenderingHash' hook,
666 * which will give them a chance to modify this key based on their own
667 * settings.
669 * @since 1.17
670 * @param array $forOptions
671 * @param Title $title Used to get the content language of the page (since r97636)
672 * @return string Page rendering hash
674 public function optionsHash( $forOptions, $title = null ) {
675 global $wgRenderHashAppend;
677 // FIXME: Once the cache key is reorganized this argument
678 // can be dropped. It was used when the math extension was
679 // part of core.
680 $confstr = '*';
682 // Space assigned for the stubthreshold but unused
683 // since it disables the parser cache, its value will always
684 // be 0 when this function is called by parsercache.
685 if ( in_array( 'stubthreshold', $forOptions ) ) {
686 $confstr .= '!' . $this->mStubThreshold;
687 } else {
688 $confstr .= '!*';
691 if ( in_array( 'dateformat', $forOptions ) ) {
692 $confstr .= '!' . $this->getDateFormat();
695 if ( in_array( 'numberheadings', $forOptions ) ) {
696 $confstr .= '!' . ( $this->mNumberHeadings ? '1' : '' );
697 } else {
698 $confstr .= '!*';
701 if ( in_array( 'userlang', $forOptions ) ) {
702 $confstr .= '!' . $this->mUserLang->getCode();
703 } else {
704 $confstr .= '!*';
707 if ( in_array( 'thumbsize', $forOptions ) ) {
708 $confstr .= '!' . $this->mThumbSize;
709 } else {
710 $confstr .= '!*';
713 // add in language specific options, if any
714 // @todo FIXME: This is just a way of retrieving the url/user preferred variant
715 if ( !is_null( $title ) ) {
716 $confstr .= $title->getPageLanguage()->getExtraHashOptions();
717 } else {
718 global $wgContLang;
719 $confstr .= $wgContLang->getExtraHashOptions();
722 $confstr .= $wgRenderHashAppend;
724 if ( !in_array( 'editsection', $forOptions ) ) {
725 $confstr .= '!*';
726 } elseif ( !$this->mEditSection ) {
727 $confstr .= '!edit=0';
730 if ( $this->mIsPrintable && in_array( 'printable', $forOptions ) ) {
731 $confstr .= '!printable=1';
734 if ( $this->mExtraKey != '' ) {
735 $confstr .= $this->mExtraKey;
738 // Give a chance for extensions to modify the hash, if they have
739 // extra options or other effects on the parser cache.
740 wfRunHooks( 'PageRenderingHash', array( &$confstr, $this->getUser(), &$forOptions ) );
742 // Make it a valid memcached key fragment
743 $confstr = str_replace( ' ', '_', $confstr );
745 return $confstr;